From 077bf0efa5e8308f6e34b9135dbdbbe86bbbdb82 Mon Sep 17 00:00:00 2001 From: Artur Spychaj Date: Mon, 25 Nov 2024 14:22:39 +0100 Subject: [PATCH 001/273] Update Fakes package version (#4143) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index d50ae7fda7..60b3004b2f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -16,7 +16,7 @@ 17.12.0 1.49.0 - 17.12.0-beta.24429.1 + 17.12.0 4.3.1 4.3.1 From e3900acea69fa95a8dbfb084d306621c896cbfc6 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 25 Nov 2024 16:09:00 +0100 Subject: [PATCH 002/273] Implement `--config` for specifying testconfig.json file (#4124) --- .../PlatformCommandLineProvider.cs | 21 ++++++ .../JsonConfigurationProvider.cs | 45 ++++++++++-- .../Configurations/JsonConfigurationSource.cs | 2 +- .../Resources/PlatformResources.resx | 8 ++- .../Resources/xlf/PlatformResources.cs.xlf | 10 +++ .../Resources/xlf/PlatformResources.de.xlf | 10 +++ .../Resources/xlf/PlatformResources.es.xlf | 10 +++ .../Resources/xlf/PlatformResources.fr.xlf | 10 +++ .../Resources/xlf/PlatformResources.it.xlf | 10 +++ .../Resources/xlf/PlatformResources.ja.xlf | 10 +++ .../Resources/xlf/PlatformResources.ko.xlf | 10 +++ .../Resources/xlf/PlatformResources.pl.xlf | 10 +++ .../Resources/xlf/PlatformResources.pt-BR.xlf | 10 +++ .../Resources/xlf/PlatformResources.ru.xlf | 10 +++ .../Resources/xlf/PlatformResources.tr.xlf | 10 +++ .../xlf/PlatformResources.zh-Hans.xlf | 10 +++ .../xlf/PlatformResources.zh-Hant.xlf | 10 +++ .../ConfigurationSettingsTests.cs | 70 +++++++++++++++++++ .../HelpInfoTests.cs | 2 + .../HelpInfoTests.cs | 12 ++++ 20 files changed, 281 insertions(+), 9 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs index 34685687d1..ba26ab2f22 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs @@ -31,6 +31,7 @@ internal sealed class PlatformCommandLineProvider : ICommandLineOptionsProvider public const string MinimumExpectedTestsOptionKey = "minimum-expected-tests"; public const string TestHostControllerPIDOptionKey = "internal-testhostcontroller-pid"; public const string ExitOnProcessExitOptionKey = "exit-on-process-exit"; + public const string ConfigFileOptionKey = "config-file"; public const string ServerOptionKey = "server"; public const string ClientPortOptionKey = "client-port"; @@ -59,6 +60,7 @@ internal sealed class PlatformCommandLineProvider : ICommandLineOptionsProvider new(DiscoverTestsOptionKey, PlatformResources.PlatformCommandLineDiscoverTestsOptionDescription, ArgumentArity.Zero, false, isBuiltIn: true), new(IgnoreExitCodeOptionKey, PlatformResources.PlatformCommandLineIgnoreExitCodeOptionDescription, ArgumentArity.ExactlyOne, false, isBuiltIn: true), new(ExitOnProcessExitOptionKey, PlatformResources.PlatformCommandLineExitOnProcessExitOptionDescription, ArgumentArity.ExactlyOne, false, isBuiltIn: true), + new(ConfigFileOptionKey, PlatformResources.PlatformCommandLineConfigFileOptionDescription, ArgumentArity.ExactlyOne, false, isBuiltIn: true), // Hidden options new(HelpOptionQuestionMark, PlatformResources.PlatformCommandLineHelpOptionDescription, ArgumentArity.Zero, true, isBuiltIn: true), @@ -120,6 +122,25 @@ public Task ValidateOptionArgumentsAsync(CommandLineOption com } } + if (commandOption.Name == ConfigFileOptionKey) + { + string arg = arguments[0]; + if (!File.Exists(arg)) + { + try + { + // Get the full path for better error messages. + // As this is only for the purpose of throwing an exception, ignore any exceptions during the GetFullPath call. + arg = Path.GetFullPath(arg); + } + catch + { + } + + return ValidationResult.InvalidTask(string.Format(CultureInfo.InvariantCulture, PlatformResources.ConfigurationFileNotFound, arg)); + } + } + // Now validate the minimum expected tests option return IsMinimumExpectedTestsOptionValidAsync(commandOption, arguments); } diff --git a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationProvider.cs b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationProvider.cs index 68b80c53a5..5857586520 100644 --- a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationProvider.cs @@ -1,18 +1,27 @@ // 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.Globalization; + +using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Logging; +using Microsoft.Testing.Platform.Resources; using Microsoft.Testing.Platform.Services; namespace Microsoft.Testing.Platform.Configurations; internal sealed partial class JsonConfigurationSource { - internal sealed class JsonConfigurationProvider(ITestApplicationModuleInfo testApplicationModuleInfo, IFileSystem fileSystem, ILogger? logger) : IConfigurationProvider + internal sealed class JsonConfigurationProvider( + ITestApplicationModuleInfo testApplicationModuleInfo, + IFileSystem fileSystem, + CommandLineParseResult commandLineParseResult, + ILogger? logger) : IConfigurationProvider { private readonly ITestApplicationModuleInfo _testApplicationModuleInfo = testApplicationModuleInfo; private readonly IFileSystem _fileSystem = fileSystem; + private readonly CommandLineParseResult _commandLineParseResult = commandLineParseResult; private readonly ILogger? _logger = logger; private Dictionary? _propertyToAllChildren; private Dictionary? _singleValueData; @@ -29,13 +38,35 @@ private async Task LogInformationAsync(string message) public async Task LoadAsync() { - string configFileName = $"{Path.Combine( - Path.GetDirectoryName(_testApplicationModuleInfo.GetCurrentTestApplicationFullPath())!, - Path.GetFileNameWithoutExtension(_testApplicationModuleInfo.GetCurrentTestApplicationFullPath()))}{PlatformConfigurationConstants.PlatformConfigSuffixFileName}"; - if (!_fileSystem.Exists(configFileName)) + string configFileName; + if (_commandLineParseResult.TryGetOptionArgumentList(PlatformCommandLineProvider.ConfigFileOptionKey, out string[]? configOptions)) { - await LogInformationAsync($"Config file '{configFileName}' not found."); - return; + configFileName = configOptions[0]; + if (!_fileSystem.Exists(configFileName)) + { + try + { + // Get the full path for better error messages. + // As this is only for the purpose of throwing an exception, ignore any exceptions during the GetFullPath call. + configFileName = Path.GetFullPath(configFileName); + } + catch + { + } + + throw new FileNotFoundException(string.Format(CultureInfo.InvariantCulture, PlatformResources.ConfigurationFileNotFound, configFileName), configFileName); + } + } + else + { + configFileName = $"{Path.Combine( + Path.GetDirectoryName(_testApplicationModuleInfo.GetCurrentTestApplicationFullPath())!, + Path.GetFileNameWithoutExtension(_testApplicationModuleInfo.GetCurrentTestApplicationFullPath()))}{PlatformConfigurationConstants.PlatformConfigSuffixFileName}"; + + if (!_fileSystem.Exists(configFileName)) + { + return; + } } await LogInformationAsync($"Config file '{configFileName}' loaded."); diff --git a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationSource.cs b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationSource.cs index 470ab1712b..3855c806e8 100644 --- a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationSource.cs +++ b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationSource.cs @@ -34,5 +34,5 @@ internal sealed partial class JsonConfigurationSource(ITestApplicationModuleInfo public Task IsEnabledAsync() => Task.FromResult(true); public Task BuildAsync(CommandLineParseResult commandLineParseResult) - => Task.FromResult((IConfigurationProvider)new JsonConfigurationProvider(_testApplicationModuleInfo, _fileSystem, _fileLoggerProvider?.CreateLogger(typeof(JsonConfigurationProvider).ToString()))); + => Task.FromResult((IConfigurationProvider)new JsonConfigurationProvider(_testApplicationModuleInfo, _fileSystem, commandLineParseResult, _fileLoggerProvider?.CreateLogger(typeof(JsonConfigurationProvider).ToString()))); } diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx index 51d20861e7..5bd7f79c1a 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx +++ b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx @@ -665,4 +665,10 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Specifies the minimum number of tests that are expected to run. - \ No newline at end of file + + Specifies a testconfig.json file. + + + The configuration file '{0}' specified with '--config-file' could not be found. + + diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index 59c6383447..8db997eddd 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -157,6 +157,11 @@ Už je zaregistrovaná stejná instance CompositeExtensonFactory. + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration Nepovedlo se najít výchozí konfiguraci json. @@ -416,6 +421,11 @@ Zadejte port klienta. + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index 93010da43a..154d7a643b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -157,6 +157,11 @@ Die gleiche Instanz von "CompositeExtensonFactory" ist bereits registriert + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration Die standardmäßige JSON-Konfiguration wurde nicht gefunden. @@ -416,6 +421,11 @@ Geben Sie den Port des Clients an. + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index 91955cb0c2..ffc6cc0328 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -157,6 +157,11 @@ La misma instancia de "CompositeExtensonFactory" ya está registrada + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration No se pudo encontrar la configuración json predeterminada @@ -416,6 +421,11 @@ Especifique el puerto del cliente. + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index a52c16c4c7..d312b88920 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -157,6 +157,11 @@ La même instance de « CompositeExtensonFactory » est déjà inscrite + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration Configuration JSON par défaut introuvable @@ -416,6 +421,11 @@ Spécifier le port du client. + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index ffc131d874..b87e60db7c 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -157,6 +157,11 @@ La stessa istanza di 'CompositeExtensonFactory' è già registrata + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration Non è stato possibile trovare la configurazione JSON predefinita @@ -416,6 +421,11 @@ Specifica la porta del client. + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index 93c55f9f9e..d7e5015d90 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -157,6 +157,11 @@ 'CompositeExtensonFactory' の同じインスタンスが既に登録されています + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration 既定の JSON 構成が見つかりませんでした @@ -416,6 +421,11 @@ クライアントのポートを指定します。 + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index 02feafb53a..9c15b13c2d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -157,6 +157,11 @@ 동일한 'CompositeExtensonFactory' 인스턴스가 이미 등록됨 + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration 기본 json 구성을 찾을 수 없습니다. @@ -416,6 +421,11 @@ 클라이언트의 포트를 지정합니다. + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index 63a7e36fe1..b8e6cb922e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -157,6 +157,11 @@ To samo wystąpienie elementu „CompositeExtensonFactory” jest już zarejestrowane + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration Nie można odnaleźć domyślnej konfiguracji JSON @@ -416,6 +421,11 @@ Określ port klienta. + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index a397aabdb9..bcb11fe735 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -157,6 +157,11 @@ A mesma instância de “CompositeExtensonFactory” já está registrada + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration Não foi possível localizar a configuração padrão do json @@ -416,6 +421,11 @@ Especifique a porta do cliente. + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index b478eea875..6495697d60 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -157,6 +157,11 @@ Такой же экземпляр CompositeExtensonFactory уже зарегистрирован + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration Не удалось найти конфигурацию JSON по умолчанию @@ -416,6 +421,11 @@ Укажите порт клиента. + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 4d0ad0f21e..207f7a4fd9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -157,6 +157,11 @@ Aynı 'CompositeExtensonFactory' örneği zaten kayıtlı + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration Varsayılan JSON yapılandırması bulunamadı @@ -416,6 +421,11 @@ İstemcinin bağlantı noktasını belirtir. + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 381bffaf18..b90e61c75d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -157,6 +157,11 @@ “CompositeExtensonFactory”的同一实例已注册 + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration 找不到默认 json 配置 @@ -416,6 +421,11 @@ 指定客户端的端口。 + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index 6a801d838c..b9b18bdbaa 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -157,6 +157,11 @@ 已註冊 'CompositeExtensonFactory' 的同一執行個體 + + The configuration file '{0}' specified with '--config-file' could not be found. + The configuration file '{0}' specified with '--config-file' could not be found. + + Could not find the default json configuration 找不到預設 JSON 設定 @@ -416,6 +421,11 @@ 指定用戶端的連接埠。 + + Specifies a testconfig.json file. + Specifies a testconfig.json file. + + Force the built-in file logger to write the log synchronously. Useful for scenario where you don't want to lose any log (i.e. in case of crash). diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ConfigurationSettingsTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ConfigurationSettingsTests.cs index 4e2e71f877..1ff51d33a8 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ConfigurationSettingsTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ConfigurationSettingsTests.cs @@ -57,6 +57,42 @@ public async Task TestConfigJson_WithoutRunSettings_BuildSuccess(string tfm) testHostResult.AssertExitCodeIs(ExitCodes.Success); } + public async Task TestWithConfigFromCommandLineWithMapInconclusiveToFailedIsTrue() + { + var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + TestHostResult testHostResult = await testHost.ExecuteAsync("--config-file dummyconfigfile_map.json", environmentVariables: new() + { + ["TestWithConfigFromCommandLine"] = "true", + }); + + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContainsSummary(failed: 1, passed: 1, skipped: 0); + } + + public async Task TestWithConfigFromCommandLineWithMapInconclusiveToFailedIsFalse() + { + var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + TestHostResult testHostResult = await testHost.ExecuteAsync("--config-file dummyconfigfile_doNotMap.json", environmentVariables: new() + { + ["TestWithConfigFromCommandLine"] = "true", + }); + + testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 1); + } + + public async Task TestWithConfigFromCommandLineWithNonExistingFile() + { + var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + TestHostResult testHostResult = await testHost.ExecuteAsync("--config-file dummyconfigfile_not_existing_file.json", environmentVariables: new() + { + ["TestWithConfigFromCommandLine"] = "true", + }); + + testHostResult.AssertStandardErrorContains("FileNotFoundException"); + testHostResult.AssertStandardErrorContains("dummyconfigfile_not_existing_file.json"); + } + [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) { @@ -127,6 +163,12 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test Always + + Always + + + Always + @@ -143,6 +185,24 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test $AppendSettings$ +#file dummyconfigfile_map.json +{ + "mstest": { + "execution": { + "mapInconclusiveToFailed": true, + }, + } +} + +#file dummyconfigfile_doNotMap.json +{ + "mstest": { + "execution": { + "mapInconclusiveToFailed": false, + }, + } +} + #file $ProjectName$.testconfig.json { "mstest": { @@ -197,6 +257,7 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test #file UnitTest1.cs +using System; using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -206,6 +267,15 @@ public class UnitTest1 public void TestMethod() { } + + [TestMethod] + public void TestWithConfigFromCommandLine() + { + if (Environment.GetEnvironmentVariable("TestWithConfigFromCommandLine") == "true") + { + Assert.Inconclusive("Inconclusive TestWithConfigFromCommandLine"); + } + } } """; } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs index 6f5fd33638..8894ffbc2d 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs @@ -31,6 +31,8 @@ public async Task Help_WhenMSTestExtensionRegistered_OutputHelpContentOfRegister Usage {AssetName}* [option providers] [extension option providers] Execute a .NET Test Application. Options: + --config-file + Specifies a testconfig.json file. --diagnostic Enable the diagnostic logging. The default log level is 'Trace'. The file will be written in the output directory with the name log_[yyMMddHHmmssfff].diag diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs index b44f617897..4292684d6e 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs @@ -27,6 +27,8 @@ .NET Testing Platform v* Usage {TestAssetFixture.NoExtensionAssetName}* [option providers] [extension option providers] Execute a .NET Test Application. Options: + --config-file + Specifies a testconfig.json file. --diagnostic Enable the diagnostic logging. The default log level is 'Trace'. The file will be written in the output directory with the name log_[yyMMddHHmmssfff].diag @@ -150,6 +152,10 @@ .NET Testing Platform v.+ \[.+\] Arity: 1 Hidden: True Description: Specify the port of the client\. + --config-file + Arity: 1 + Hidden: False + Description: Specifies a testconfig\.json file\. --diagnostic Arity: 0 Hidden: False @@ -283,6 +289,8 @@ .NET Testing Platform v* Usage {TestAssetFixture.AllExtensionsAssetName}* [option providers] [extension option providers] Execute a .NET Test Application. Options: + --config-file + Specifies a testconfig.json file. --diagnostic Enable the diagnostic logging. The default log level is 'Trace'. The file will be written in the output directory with the name log_[yyMMddHHmmssfff].diag @@ -418,6 +426,10 @@ .NET Testing Platform v* [*] Arity: 1 Hidden: True Description: Specify the port of the client. + --config-file + Arity: 1 + Hidden: False + Description: Specifies a testconfig.json file. --diagnostic Arity: 0 Hidden: False From 7d0cd29ae1fa85772fa08a58f50eb68ee472dcb0 Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Mon, 25 Nov 2024 16:42:49 +0000 Subject: [PATCH 003/273] StopUpdate in Finally Block (#4147) --- .../OutputDevice/Terminal/NonAnsiTerminal.cs | 3 +- .../TestProgressStateAwareTerminal.cs | 37 +++++++++++++------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs index e0af85e4fc..8c1f545720 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs @@ -5,6 +5,7 @@ using System.Text; using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.Resources; namespace Microsoft.Testing.Platform.OutputDevice.Terminal; @@ -122,7 +123,7 @@ public void StartUpdate() { if (_isBatching) { - throw new InvalidOperationException("Console is already in batching mode."); + throw new InvalidOperationException(PlatformResources.ConsoleIsAlreadyInBatchingMode); } _stringBuilder.Clear(); diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs index f1b1f32c62..c462d8e67e 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs @@ -16,13 +16,17 @@ internal sealed partial class TestProgressStateAwareTerminal : IDisposable /// /// Protects access to state shared between the logger callbacks and the rendering thread. /// +#if NET9_0_OR_GREATER + private readonly System.Threading.Lock _lock = new(); +#else private readonly object _lock = new(); +#endif private readonly ITerminal _terminal; private readonly Func _showProgress; private readonly bool _writeProgressImmediatelyAfterOutput; private readonly int _updateEvery; - private TestProgressState?[] _progressItems = Array.Empty(); + private TestProgressState?[] _progressItems = []; private bool? _showProgressCached; /// @@ -122,24 +126,35 @@ internal void WriteToTerminal(Action write) { lock (_lock) { - _terminal.StartUpdate(); - _terminal.EraseProgress(); - write(_terminal); - if (_writeProgressImmediatelyAfterOutput) + try { - _terminal.RenderProgress(_progressItems); + _terminal.StartUpdate(); + _terminal.EraseProgress(); + write(_terminal); + if (_writeProgressImmediatelyAfterOutput) + { + _terminal.RenderProgress(_progressItems); + } + } + finally + { + _terminal.StopUpdate(); } - - _terminal.StopUpdate(); } } else { lock (_lock) { - _terminal.StartUpdate(); - write(_terminal); - _terminal.StopUpdate(); + try + { + _terminal.StartUpdate(); + write(_terminal); + } + finally + { + _terminal.StopUpdate(); + } } } } From f46d115666a1f0e30129ceec4922d77edf59003a Mon Sep 17 00:00:00 2001 From: Mariam Abdullah <122357303+mariam-abdulla@users.noreply.github.com> Date: Mon, 25 Nov 2024 20:18:16 +0100 Subject: [PATCH 004/273] Set IsTestingPlatformApplication to true in ClassicEngine.targets (#4151) --- src/Package/MSTest.Sdk/Sdk/Runner/ClassicEngine.targets | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Package/MSTest.Sdk/Sdk/Runner/ClassicEngine.targets b/src/Package/MSTest.Sdk/Sdk/Runner/ClassicEngine.targets index 402e9c4d74..703349650f 100644 --- a/src/Package/MSTest.Sdk/Sdk/Runner/ClassicEngine.targets +++ b/src/Package/MSTest.Sdk/Sdk/Runner/ClassicEngine.targets @@ -5,6 +5,15 @@ true + + + true From 773144fb931cfa2d29bafbef4040791e4f3ba2d0 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 25 Nov 2024 20:33:25 +0100 Subject: [PATCH 005/273] Improve error message for incompatible architecture (#4144) --- .../Resources/MSBuildResources.resx | 8 ++++ .../Resources/xlf/MSBuildResources.cs.xlf | 15 +++++++ .../Resources/xlf/MSBuildResources.de.xlf | 15 +++++++ .../Resources/xlf/MSBuildResources.es.xlf | 15 +++++++ .../Resources/xlf/MSBuildResources.fr.xlf | 15 +++++++ .../Resources/xlf/MSBuildResources.it.xlf | 15 +++++++ .../Resources/xlf/MSBuildResources.ja.xlf | 15 +++++++ .../Resources/xlf/MSBuildResources.ko.xlf | 15 +++++++ .../Resources/xlf/MSBuildResources.pl.xlf | 15 +++++++ .../Resources/xlf/MSBuildResources.pt-BR.xlf | 15 +++++++ .../Resources/xlf/MSBuildResources.ru.xlf | 15 +++++++ .../Resources/xlf/MSBuildResources.tr.xlf | 15 +++++++ .../xlf/MSBuildResources.zh-Hans.xlf | 15 +++++++ .../xlf/MSBuildResources.zh-Hant.xlf | 15 +++++++ .../Tasks/InvokeTestingPlatformTask.cs | 2 +- .../MSBuildTests.Test.cs | 39 +++++++++++++++++++ 16 files changed, 243 insertions(+), 1 deletion(-) diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/MSBuildResources.resx b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/MSBuildResources.resx index 3d687d988e..16ec9b3e2a 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/MSBuildResources.resx +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/MSBuildResources.resx @@ -156,4 +156,12 @@ Tests succeeded: '{0}' [{1}|{2}] + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.cs.xlf index 8d3dc35a31..72322ab120 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.cs.xlf @@ -27,6 +27,21 @@ Výpočet úplné cesty nástroje se nezdařil. Spouštěč {0} + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} Neplatná hodnota TargetPath, {0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.de.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.de.xlf index b429cb8fd5..57afa3c6cc 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.de.xlf @@ -27,6 +27,21 @@ Fehler bei der Berechnung des vollständigen Pfadtools Runner „{0}“ + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} Ungültiger TargetPath, {0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.es.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.es.xlf index 433fecfb13..0a79556d63 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.es.xlf @@ -27,6 +27,21 @@ El cálculo de la herramienta de ruta de acceso completa es incorrecto. Runner '{0}' + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} TargetPath no válido, {0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.fr.xlf index a9db79e77f..2cf75dd865 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.fr.xlf @@ -27,6 +27,21 @@ Désolé... Nous n’avons pas pu effectuer le calcul d’outil de chemin complet. Exécuteur « {0} » + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} TargetPath non valide, {0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.it.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.it.xlf index 654e88ead5..84acb581b1 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.it.xlf @@ -27,6 +27,21 @@ Calcolo del percorso completo dello strumento non riuscito. Strumento di esecuzione '{0}' + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} TargetPath non valido, {0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ja.xlf index 4e6f7689ef..2446ab0a45 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ja.xlf @@ -27,6 +27,21 @@ 完全なパス ツールの計算に失敗しました。ランナー '{0}' + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} 無効な TargetPath、{0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ko.xlf index 133a392a42..e55406eb5a 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ko.xlf @@ -27,6 +27,21 @@ 전체 경로 도구를 계산하지 못했습니다. 러너 '{0}' + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} 잘못된 TargetPath, {0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pl.xlf index 47d2e8869a..2de569adf6 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pl.xlf @@ -27,6 +27,21 @@ Obliczanie narzędzia pełnej ścieżki nie powiodło się. Moduł uruchamiający „{0}” + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} Nieprawidłowa ścieżka docelowa, {0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pt-BR.xlf index e07d9e4ee3..1e7c962212 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pt-BR.xlf @@ -27,6 +27,21 @@ Falha no cálculo da ferramenta de caminho completo. Executor “{0}” + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} TargetPath inválido, {0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ru.xlf index 10ae284b08..6d90b2fc2a 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ru.xlf @@ -27,6 +27,21 @@ Сбой вычисления средства полного пути. Средство выполнения тестов "{0}" + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} Недопустимый TargetPath, {0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.tr.xlf index 21b5c1c465..35f1a622a3 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.tr.xlf @@ -27,6 +27,21 @@ Tam yol aracı hesaplaması başarısız. Çalıştırıcı '{0}' + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} Geçersiz TargetPath, {0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hans.xlf index e53d10fbaf..8d38e43bea 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hans.xlf @@ -27,6 +27,21 @@ 完整路径工具计算失败。运行器“{0}” + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} TargetPath {0} 无效 diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hant.xlf index 1e6ce78dc8..50f79ba0bb 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hant.xlf @@ -27,6 +27,21 @@ 完整路徑工具計算失敗。執行器 '{0}' + + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + Could not find '{0}' host for the '{1}' architecture. + +You can resolve the problem by installing the '{1}' .NET. + +The specified framework can be found at: + - https://aka.ms/dotnet-download + + Invalid TargetPath, {0} TargetPath 無效,{0} diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs index 588f94cac9..95c7169762 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs @@ -141,7 +141,7 @@ protected override string ToolName else { Log.LogMessage(MessageImportance.Low, resolutionLog.ToString()); - Log.LogError(Resources.MSBuildResources.FullPathToolCalculationFailed, dotnetRunnerName); + Log.LogError(string.Format(CultureInfo.InvariantCulture, Resources.MSBuildResources.IncompatibleArchitecture, dotnetRunnerName, TestArchitecture.ItemSpec)); return null; } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs index fa4a775ae4..d7c4abd3f9 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs @@ -4,6 +4,8 @@ using System.Runtime.InteropServices; using System.Text.RegularExpressions; +using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; + namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestGroup] @@ -159,6 +161,43 @@ await DotnetCli.RunAsync( Assert.IsTrue(Regex.IsMatch(logFileContent, @"\.dotnet\\x86\\dotnet\.exe"), logFileContent); } + public async Task Invoke_DotnetTest_With_Incompatible_Arch() + { + Architecture currentArchitecture = RuntimeInformation.ProcessArchitecture; + string incompatibleArchitecture = currentArchitecture switch + { + Architecture.X86 or Architecture.X64 => "arm64", + _ => "x64", + }; + + TestAsset testAsset = await TestAsset.GenerateAssetAsync( + AssetName, + SourceCode + .PatchCodeWithReplace("$PlatformTarget$", string.Empty) + .PatchCodeWithReplace("$TargetFrameworks$", $"{TargetFrameworks.NetCurrent.Arguments}") + .PatchCodeWithReplace("$AssertValue$", bool.TrueString.ToLowerInvariant()) + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + DotnetMuxerResult result = await DotnetCli.RunAsync( + $"test --arch {incompatibleArchitecture} -p:TestingPlatformDotnetTestSupport=True \"{testAsset.TargetAssetPath}\"", + _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + failIfReturnValueIsNotZero: false); + // The output looks like: + /* + D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\tidOn\.packages\microsoft.testing.platform.msbuild\1.5.0-ci\buildMultiTargeting\Microsoft.Testing.Platform.MSBuild.targets(320,5): error : Could not find 'dotnet.exe' host for the 'arm64' architecture. [D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\vf8vR\MSBuildTests\MSBuild Tests.csproj] + D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\tidOn\.packages\microsoft.testing.platform.msbuild\1.5.0-ci\buildMultiTargeting\Microsoft.Testing.Platform.MSBuild.targets(320,5): error : [D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\vf8vR\MSBuildTests\MSBuild Tests.csproj] + D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\tidOn\.packages\microsoft.testing.platform.msbuild\1.5.0-ci\buildMultiTargeting\Microsoft.Testing.Platform.MSBuild.targets(320,5): error : You can resolve the problem by installing the 'arm64' .NET. [D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\vf8vR\MSBuildTests\MSBuild Tests.csproj] + D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\tidOn\.packages\microsoft.testing.platform.msbuild\1.5.0-ci\buildMultiTargeting\Microsoft.Testing.Platform.MSBuild.targets(320,5): error : [D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\vf8vR\MSBuildTests\MSBuild Tests.csproj] + D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\tidOn\.packages\microsoft.testing.platform.msbuild\1.5.0-ci\buildMultiTargeting\Microsoft.Testing.Platform.MSBuild.targets(320,5): error : The specified framework can be found at: [D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\vf8vR\MSBuildTests\MSBuild Tests.csproj] + D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\tidOn\.packages\microsoft.testing.platform.msbuild\1.5.0-ci\buildMultiTargeting\Microsoft.Testing.Platform.MSBuild.targets(320,5): error : - https://aka.ms/dotnet-download [D:\a\_work\1\s\artifacts\tmp\Debug\testsuite\vf8vR\MSBuildTests\MSBuild Tests.csproj] + */ + // Assert each error line separately for simplicity. + result.AssertOutputContains($"Could not find '{(OperatingSystem.IsWindows() ? "dotnet.exe" : "dotnet")}' host for the '{incompatibleArchitecture}' architecture."); + result.AssertOutputContains($"You can resolve the problem by installing the '{incompatibleArchitecture}' .NET."); + result.AssertOutputContains("The specified framework can be found at:"); + result.AssertOutputContains(" - https://aka.ms/dotnet-download"); + } + public async Task Invoke_DotnetTest_With_DOTNET_HOST_PATH_Should_Work() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) From ff1568833d2edf25ef6c883a93a42e5261a06c8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 25 Nov 2024 21:15:06 +0100 Subject: [PATCH 006/273] Use Polyfill lock (#4153) --- .../OutputDevice/Terminal/TestProgressStateAwareTerminal.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs index c462d8e67e..2f52afaa00 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs @@ -16,11 +16,7 @@ internal sealed partial class TestProgressStateAwareTerminal : IDisposable /// /// Protects access to state shared between the logger callbacks and the rendering thread. /// -#if NET9_0_OR_GREATER - private readonly System.Threading.Lock _lock = new(); -#else - private readonly object _lock = new(); -#endif + private readonly Lock _lock = new(); private readonly ITerminal _terminal; private readonly Func _showProgress; From c142c75abe282a926d808f4431af029ff35e5659 Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Tue, 26 Nov 2024 08:37:33 +0000 Subject: [PATCH 007/273] Further `System.Threading.Lock` usages (#4156) --- .../Extensions/CompositeExtensionsFactory.cs | 2 +- src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Extensions/CompositeExtensionsFactory.cs b/src/Platform/Microsoft.Testing.Platform/Extensions/CompositeExtensionsFactory.cs index 84a48ce170..5e10f0400b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Extensions/CompositeExtensionsFactory.cs +++ b/src/Platform/Microsoft.Testing.Platform/Extensions/CompositeExtensionsFactory.cs @@ -17,7 +17,7 @@ namespace Microsoft.Testing.Platform.Extensions; public class CompositeExtensionFactory : ICompositeExtensionFactory, ICloneable where TExtension : class, IExtension { - private readonly object _syncLock = new(); + private readonly Lock _syncLock = new(); private readonly Func? _factoryWithServiceProvider; private readonly Func? _factory; private TExtension? _instance; diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs index 783713fd63..68d8a1b8eb 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs @@ -702,7 +702,7 @@ await SendMessageAsync( private sealed class RpcInvocationState : IDisposable { - private readonly object _cancellationTokenSourceLock = new(); + private readonly Lock _cancellationTokenSourceLock = new(); private readonly CancellationTokenSource _cancellationTokenSource = new(); private volatile bool _isDisposed; From 790f4e2ed6fe130c53a4939bdc69e5409da3e389 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 26 Nov 2024 15:35:18 +0100 Subject: [PATCH 008/273] Remove unused code in crash dump tests (#4158) --- .../CrashDumpTests.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs index c6bb94ac4f..0b17f1ffe2 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs @@ -9,11 +9,6 @@ namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestGroup] public sealed class CrashDumpTests : AcceptanceTestBase { - internal static Func RetryPolicy - => ex => ex.ToString().Contains("FAILED No such process") - || ex.ToString().Contains("FAILED 13 (Permission denied)") - || ex.ToString().Contains("Problem suspending threads"); - private readonly TestAssetFixture _testAssetFixture; public CrashDumpTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) From e7c722a2fd29b6f755279056c964b60942972b47 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 26 Nov 2024 14:40:13 +0000 Subject: [PATCH 009/273] [main] Update dependencies from dotnet/arcade, microsoft/testanywhere (#4161) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- global.json | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index afaac5d206..dd4da70eec 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,25 +1,25 @@ - + https://github.com/dotnet/arcade - 7d955f9f470465e144c76d47fd2596a0e4c02a21 + 2a3bf4e3a4c473135d058adcd7193a5a4bcd38a7 - + https://github.com/dotnet/arcade - 7d955f9f470465e144c76d47fd2596a0e4c02a21 + 2a3bf4e3a4c473135d058adcd7193a5a4bcd38a7 - + https://github.com/dotnet/arcade - 7d955f9f470465e144c76d47fd2596a0e4c02a21 + 2a3bf4e3a4c473135d058adcd7193a5a4bcd38a7 https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage 2d88381a218863f6b20537637b2bcfb0bc93686d - + https://github.com/microsoft/testanywhere - 222b1daf1d58cd34402736d9a896975b79171b6d + 0628cb69980b9b2a41b0dcc20a9ffdf181e942f6 https://github.com/microsoft/testanywhere diff --git a/eng/Versions.props b/eng/Versions.props index 6c4dd96500..7bb8254454 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,10 +7,10 @@ preview - 10.0.0-beta.24572.3 + 10.0.0-beta.24575.1 17.13.0-preview.24572.7 - 1.5.0-preview.24573.1 + 1.5.0-preview.24575.1 1.0.0-alpha.24473.2 diff --git a/global.json b/global.json index 77e444f5e2..2c41702631 100644 --- a/global.json +++ b/global.json @@ -25,7 +25,7 @@ "rollForward": "latestFeature" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.24572.3", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.24575.1", "MSBuild.Sdk.Extras": "3.0.44" } } From 02402e8a44a642126a76cfeb98e6df93e4cc7e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 26 Nov 2024 16:01:16 +0100 Subject: [PATCH 010/273] Add codecov.io to official pipeline (#4163) --- azure-pipelines-official.yml | 7 +++++++ azure-pipelines.yml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index 832eb75c92..c463827a50 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -148,6 +148,13 @@ extends: name: Test displayName: Test + # Upload code coverage to codecov.io + - script: $(Build.SourcesDirectory)/.dotnet/dotnet msbuild -restore + eng/CodeCoverage.proj + /p:Configuration=$(_BuildConfig) + /bl:$(BUILD.SOURCESDIRECTORY)\artifacts\log\$(_BuildConfig)\CodeCoverage.binlog + displayName: Upload coverage to codecov.io + # Remove temporary artifacts to avoid finding binskim issues for exes we don't own. - pwsh: | Remove-Item -Path $(Build.SourcesDirectory)/artifacts/tmp -Recurse -Force diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c7327adfd6..b98f8c6105 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -103,7 +103,7 @@ stages: name: Test displayName: Test - # Upload code coverage data + # Upload code coverage to codecov.io - script: $(Build.SourcesDirectory)/.dotnet/dotnet msbuild -restore eng/CodeCoverage.proj /p:Configuration=$(_BuildConfig) From 2d8da3add21f9b9a0947d78b005b0122deecb2eb Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 26 Nov 2024 07:14:19 -0800 Subject: [PATCH 011/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2589898 --- .../Resources/xlf/PlatformResources.cs.xlf | 4 ++-- .../Resources/xlf/PlatformResources.tr.xlf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index 8db997eddd..51789c6317 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -119,12 +119,12 @@ Failed to read response file '{0}'. {1}. - Failed to read response file '{0}'. {1}. + Čtení souboru odpovědí {0} selhalo. {1}. {1} is the exception The response file '{0}' was not found - The response file '{0}' was not found + Soubor odpovědí {0} nebyl nalezen. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 207f7a4fd9..03b115291e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -119,12 +119,12 @@ Failed to read response file '{0}'. {1}. - Failed to read response file '{0}'. {1}. + '{0}' yanıt dosyası okunamadı. {1}. {1} is the exception The response file '{0}' was not found - The response file '{0}' was not found + '{0}' yanıt dosyası bulunamadı From 775e0218661862dfb6af180be0ec997830c2474b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 26 Nov 2024 17:37:16 +0100 Subject: [PATCH 012/273] Add mac os on pr pipeline (#4155) --- azure-pipelines.yml | 30 +++++++++++++++++++ ...c => MSTest.TestAdapter.NonWindows.nuspec} | 0 .../MSTest.TestAdapter.csproj | 2 +- ....Linux.nuspec => MSTest.NonWindows.nuspec} | 0 src/Package/MSTest/MSTest.csproj | 2 +- ...=> MSTest.TestFramework.NonWindows.nuspec} | 0 .../TestFramework.Extensions.csproj | 2 +- .../NativeAotTests.cs | 12 +++++++- .../CrashDumpTests.cs | 20 +++++++++++++ .../CrashPlusHangDumpTests.cs | 14 +++++++++ .../HangDumpOutputTests.cs | 8 +++++ .../HangDumpTests.cs | 26 ++++++++++++++++ .../Helpers/AcceptanceTestBase.cs | 9 +++++- .../TrxTests.cs | 7 +++++ 14 files changed, 127 insertions(+), 5 deletions(-) rename src/Adapter/MSTest.TestAdapter/{MSTest.TestAdapter.Linux.nuspec => MSTest.TestAdapter.NonWindows.nuspec} (100%) rename src/Package/MSTest/{MSTest.Linux.nuspec => MSTest.NonWindows.nuspec} (100%) rename src/TestFramework/TestFramework.Extensions/{MSTest.TestFramework.Linux.nuspec => MSTest.TestFramework.NonWindows.nuspec} (100%) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b98f8c6105..7864d89bee 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -148,3 +148,33 @@ stages: ./test.sh --configuration $(_BuildConfig) --ci --test --integrationTest --nobl name: Test displayName: Tests + + - job: MacOS + timeoutInMinutes: 90 + pool: + name: Azure Pipelines + vmImage: macos-latest + os: macOS + strategy: + matrix: + Release: + _BuildConfig: Release + Debug: + _BuildConfig: Debug + steps: + - script: eng/common/cibuild.sh + -configuration $(_BuildConfig) + -prepareMachine + /p:Test=false + /p:NonWindowsBuild=true + /p:FastAcceptanceTest=true + displayName: Build + + - ${{ if eq(parameters.SkipTests, False) }}: + # --ci is allowing to import some environment variables and some required configurations + # --nobl avoids overwriting build binlog with binlog from tests + - script: | + chmod +x ./test.sh + ./test.sh --configuration $(_BuildConfig) --ci --test --integrationTest --nobl + name: Test + displayName: Tests diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.Linux.nuspec b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.NonWindows.nuspec similarity index 100% rename from src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.Linux.nuspec rename to src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.NonWindows.nuspec diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj index fb25147250..ccb26d8c0f 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj @@ -18,7 +18,7 @@ true MSTest.TestAdapter.nuspec - MSTest.TestAdapter.Linux.nuspec + MSTest.TestAdapter.NonWindows.nuspec $(OutputPath) MSTest.TestAdapter MSTest TestFramework TestAdapter VisualStudio Unittest MSTestV2 Microsoft diff --git a/src/Package/MSTest/MSTest.Linux.nuspec b/src/Package/MSTest/MSTest.NonWindows.nuspec similarity index 100% rename from src/Package/MSTest/MSTest.Linux.nuspec rename to src/Package/MSTest/MSTest.NonWindows.nuspec diff --git a/src/Package/MSTest/MSTest.csproj b/src/Package/MSTest/MSTest.csproj index 05b34847f1..5263dba60d 100644 --- a/src/Package/MSTest/MSTest.csproj +++ b/src/Package/MSTest/MSTest.csproj @@ -7,7 +7,7 @@ true MSTest.nuspec - MSTest.Linux.nuspec + MSTest.NonWindows.nuspec $(OutputPath) MSTest MSTest TestFramework TestAdapter VisualStudio Unittest MSTestV2 Microsoft diff --git a/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.Linux.nuspec b/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.NonWindows.nuspec similarity index 100% rename from src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.Linux.nuspec rename to src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.NonWindows.nuspec diff --git a/src/TestFramework/TestFramework.Extensions/TestFramework.Extensions.csproj b/src/TestFramework/TestFramework.Extensions/TestFramework.Extensions.csproj index 5dcc9df4a5..a66f58bbf3 100644 --- a/src/TestFramework/TestFramework.Extensions/TestFramework.Extensions.csproj +++ b/src/TestFramework/TestFramework.Extensions/TestFramework.Extensions.csproj @@ -13,7 +13,7 @@ true MSTest.TestFramework.nuspec - MSTest.TestFramework.Linux.nuspec + MSTest.TestFramework.NonWindows.nuspec $(OutputPath) MSTest.TestFramework MSTest TestFramework Unittest MSTestV2 Microsoft Test Testing TDD Framework diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs index c0efb2bae8..21af4e042c 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs @@ -1,6 +1,8 @@ // 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.Runtime.InteropServices; + using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; @@ -88,10 +90,17 @@ public NativeAotTests(ITestExecutionContext testExecutionContext, AcceptanceFixt : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; public async Task NativeAotTests_WillRunWithExitCodeZero() + { + // The hosted AzDO agents for Mac OS don't have the required tooling for us to test Native AOT. + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return; + } + // The native AOT publication is pretty flaky and is often failing on CI with "fatal error LNK1136: invalid or corrupt file", // or sometimes doesn't fail but the native code generation is not done. // Retrying the restore/publish on fresh asset seems to be more effective than retrying on the same asset. - => await RetryHelper.RetryAsync( + await RetryHelper.RetryAsync( async () => { using TestAsset generator = await TestAsset.GenerateAssetAsync( @@ -119,4 +128,5 @@ await DotnetCli.RunAsync( TestHostResult result = await testHost.ExecuteAsync(); result.AssertExitCodeIs(0); }, times: 15, every: TimeSpan.FromSeconds(5)); + } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs index 0b17f1ffe2..cad2f04a15 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs @@ -1,6 +1,8 @@ // 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.Runtime.InteropServices; + using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; using Microsoft.Testing.Platform.Helpers; @@ -17,6 +19,12 @@ public CrashDumpTests(ITestExecutionContext testExecutionContext, TestAssetFixtu [ArgumentsProvider(nameof(TargetFrameworks.Net), typeof(TargetFrameworks))] public async Task CrashDump_DefaultSetting_CreateDump(string tfm) { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // TODO: Investigate failures on macos + return; + } + string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N")); var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "CrashDump", tfm); TestHostResult testHostResult = await testHost.ExecuteAsync($"--crashdump --results-directory {resultDirectory}"); @@ -27,6 +35,12 @@ public async Task CrashDump_DefaultSetting_CreateDump(string tfm) public async Task CrashDump_CustomDumpName_CreateDump() { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // TODO: Investigate failures on macos + return; + } + string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N")); var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "CrashDump", TargetFrameworks.NetCurrent.Arguments); TestHostResult testHostResult = await testHost.ExecuteAsync($"--crashdump --crashdump-filename customdumpname.dmp --results-directory {resultDirectory}"); @@ -40,6 +54,12 @@ public async Task CrashDump_CustomDumpName_CreateDump() [Arguments("Full")] public async Task CrashDump_Formats_CreateDump(string format) { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // TODO: Investigate failures on macos + return; + } + string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N")); var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "CrashDump", TargetFrameworks.NetCurrent.Arguments); TestHostResult testHostResult = await testHost.ExecuteAsync($"--crashdump --crashdump-type {format} --results-directory {resultDirectory}"); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs index 44bd63c540..8d4a1adca5 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs @@ -1,6 +1,8 @@ // 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.Runtime.InteropServices; + using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; using Microsoft.Testing.Platform.Helpers; @@ -16,6 +18,12 @@ public CrashPlusHangDumpTests(ITestExecutionContext testExecutionContext, TestAs public async Task CrashPlusHangDump_InCaseOfCrash_CreateCrashDump() { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // TODO: Investigate failures on macos + return; + } + string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent.Arguments); var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "CrashPlusHangDump", TargetFrameworks.NetCurrent.Arguments); TestHostResult testHostResult = await testHost.ExecuteAsync( @@ -37,6 +45,12 @@ public async Task CrashPlusHangDump_InCaseOfCrash_CreateCrashDump() public async Task CrashPlusHangDump_InCaseOfHang_CreateHangDump() { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // TODO: Investigate failures on macos + return; + } + string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent.Arguments); var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "CrashPlusHangDump", TargetFrameworks.NetCurrent.Arguments); TestHostResult testHostResult = await testHost.ExecuteAsync( diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs index 2309c7082e..a66c6d166f 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs @@ -1,6 +1,8 @@ // 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.Runtime.InteropServices; + using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; using Microsoft.Testing.Platform.Helpers; @@ -17,6 +19,12 @@ public HangDumpOutputTests(ITestExecutionContext testExecutionContext, TestAsset [Arguments("Mini")] public async Task HangDump_Outputs_HangingTests_EvenWhenHangingTestsHaveTheSameDisplayName(string format) { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // TODO: Investigate failures on macos + return; + } + // This test makes sure that when tests have the same display name (e.g. like Test1 from both Class1 and Class2) // they will still show up in the hanging tests. This was not the case before when we were just putting them into // a dictionary based on DisplayName. In that case both tests were started at the same time, and only 1 entry was added diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs index 4fe5ac589e..fc9935efce 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs @@ -1,6 +1,8 @@ // 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.Runtime.InteropServices; + using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; using Microsoft.Testing.Platform.Helpers; @@ -17,6 +19,12 @@ public HangDumpTests(ITestExecutionContext testExecutionContext, TestAssetFixtur [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] public async Task HangDump_DefaultSetting_CreateDump(string tfm) { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // TODO: Investigate failures on macos + return; + } + string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), tfm); var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "HangDump", tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( @@ -33,6 +41,12 @@ public async Task HangDump_DefaultSetting_CreateDump(string tfm) public async Task HangDump_CustomFileName_CreateDump() { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // TODO: Investigate failures on macos + return; + } + string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent.Arguments); var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent.Arguments); TestHostResult testHostResult = await testHost.ExecuteAsync( @@ -49,6 +63,12 @@ public async Task HangDump_CustomFileName_CreateDump() public async Task HangDump_PathWithSpaces_CreateDump() { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // TODO: Investigate failures on macos + return; + } + string resultDir = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent.Arguments); string resultDirectory = Path.Combine(resultDir, "directory with spaces"); Directory.CreateDirectory(resultDirectory); @@ -71,6 +91,12 @@ public async Task HangDump_PathWithSpaces_CreateDump() [Arguments("Full")] public async Task HangDump_Formats_CreateDump(string format) { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // TODO: Investigate failures on macos + return; + } + string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), format); var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent.Arguments); TestHostResult testHostResult = await testHost.ExecuteAsync( diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs index ddaf3bc633..de978129ff 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs @@ -76,7 +76,14 @@ protected AcceptanceTestBase(ITestExecutionContext testExecutionContext) { } - internal static string RID { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "win-x64" : "linux-x64"; + internal static string RID { get; } + = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + ? "win-x64" + : RuntimeInformation.IsOSPlatform(OSPlatform.Linux) + ? "linux-x64" + : RuntimeInformation.IsOSPlatform(OSPlatform.OSX) + ? "osx-x64" + : throw new NotSupportedException("Current OS is not supported"); public static string MSTestVersion { get; private set; } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs index ec20efca39..f49bd2ca50 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs @@ -1,6 +1,7 @@ // 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.Runtime.InteropServices; using System.Text.RegularExpressions; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; @@ -47,6 +48,12 @@ public async Task Trx_WhenReportTrxIsSpecified_TrxReportIsGeneratedInDefaultLoca [ArgumentsProvider(nameof(TargetFrameworks.Net), typeof(TargetFrameworks))] public async Task Trx_WhenTestHostCrash_ErrorIsDisplayedInsideTheTrx(string tfm) { + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + // TODO: Investigate failures on macos + return; + } + string fileName = Guid.NewGuid().ToString("N"); var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( From 4c520912a2c8df8f14eb9310851f539f4737dd53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 26 Nov 2024 20:59:11 +0100 Subject: [PATCH 013/273] Drop codecov.io from internal build (#4169) --- azure-pipelines-official.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index c463827a50..832eb75c92 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -148,13 +148,6 @@ extends: name: Test displayName: Test - # Upload code coverage to codecov.io - - script: $(Build.SourcesDirectory)/.dotnet/dotnet msbuild -restore - eng/CodeCoverage.proj - /p:Configuration=$(_BuildConfig) - /bl:$(BUILD.SOURCESDIRECTORY)\artifacts\log\$(_BuildConfig)\CodeCoverage.binlog - displayName: Upload coverage to codecov.io - # Remove temporary artifacts to avoid finding binskim issues for exes we don't own. - pwsh: | Remove-Item -Path $(Build.SourcesDirectory)/artifacts/tmp -Recurse -Force From b97678da1cb8b6454436ef53f9c0ee72dc3b54f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 26 Nov 2024 21:07:08 +0100 Subject: [PATCH 014/273] Update codecov.yml (#4170) --- .github/codecov.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/codecov.yml b/.github/codecov.yml index c88a10a3af..28165ad155 100644 --- a/.github/codecov.yml +++ b/.github/codecov.yml @@ -11,4 +11,12 @@ coverage: - "eng/src/::src/" comment: - layout: "diff" + layout: "diff, flags, files" + +flags: + production: + paths: + - src/ + test: + paths: + - test/ From 2e89f20f8690f37484d121dd452716e2dc975d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 26 Nov 2024 21:20:47 +0100 Subject: [PATCH 015/273] Build targeting net9.0 (#4167) --- Directory.Build.props | 6 ++-- eng/verify-nupkgs.ps1 | 4 +-- global.json | 7 ++-- samples/Playground/Playground.csproj | 2 +- .../Execution/LogMessageListener.cs | 2 +- .../Execution/TestAssemblyInfo.cs | 7 ++-- .../Execution/TestClassInfo.cs | 2 +- .../MSTest.TestAdapter.NonWindows.nuspec | 12 +++++++ .../MSTest.TestAdapter.nuspec | 12 +++++++ .../AssemblyResolver.cs | 2 +- .../PublicAPI/net9.0/PublicAPI.Shipped.txt | 33 +++++++++++++++++++ .../PublicAPI/net9.0/PublicAPI.Unshipped.txt | 1 + .../Services/ThreadSafeStringWriter.cs | 4 +-- src/Package/MSTest/MSTest.NonWindows.nuspec | 7 ++++ src/Package/MSTest/MSTest.nuspec | 7 ++++ .../Tasks/InvokeTestingPlatformTask.cs | 2 +- .../Helpers/ObjectPool.cs | 4 +-- .../MSTest.TestFramework.NonWindows.nuspec | 9 +++++ .../MSTest.TestFramework.nuspec | 9 +++++ .../PublicAPI/net9.0/PublicAPI.Shipped.txt | 14 ++++++++ .../PublicAPI/net9.0/PublicAPI.Unshipped.txt | 1 + .../SdkTests.cs | 6 ++-- .../MSBuildTests.Test.cs | 4 +-- .../MSTest.Performance.Runner.csproj | 2 +- .../MSTest.Performance.Runner/Program.cs | 12 +++---- .../Scenarios/Scenario1.cs | 2 +- .../TargetFrameworks.cs | 3 +- 27 files changed, 140 insertions(+), 36 deletions(-) create mode 100644 src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Shipped.txt create mode 100644 src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Unshipped.txt create mode 100644 src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Shipped.txt create mode 100644 src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Unshipped.txt diff --git a/Directory.Build.props b/Directory.Build.props index 291e3b4f05..25e725ef65 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -28,10 +28,10 @@ net462 uap10.0.16299 net6.0-windows10.0.18362.0 - net8.0 + net9.0 - netcoreapp3.1;net6.0;net7.0;net8.0 - net6.0;net7.0;net8.0 + net6.0;net7.0;net8.0;net9.0 + netcoreapp3.1;net6.0;net7.0;net8.0;net9.0 diff --git a/eng/verify-nupkgs.ps1 b/eng/verify-nupkgs.ps1 index d119680355..f13aa658aa 100644 --- a/eng/verify-nupkgs.ps1 +++ b/eng/verify-nupkgs.ps1 @@ -21,8 +21,8 @@ function Confirm-NugetPackages { $expectedNumOfFiles = @{ "MSTest.Sdk" = 15; "MSTest.Internal.TestFx.Documentation" = 10; - "MSTest.TestFramework" = 130; - "MSTest.TestAdapter" = 76; + "MSTest.TestFramework" = 148; + "MSTest.TestAdapter" = 82; "MSTest" = 6; "MSTest.Analyzers" = 10; } diff --git a/global.json b/global.json index 2c41702631..8c4683a69c 100644 --- a/global.json +++ b/global.json @@ -6,13 +6,14 @@ "3.1.32", "6.0.35", "7.0.20", - "8.0.10" + "8.0.11", + "9.0.0" ], "dotnet/x86": [ - "8.0.10" + "9.0.0" ], "aspnetcore": [ - "8.0.10" + "9.0.0" ] }, "vs": { diff --git a/samples/Playground/Playground.csproj b/samples/Playground/Playground.csproj index 6e3e66fa49..f60b5e923c 100644 --- a/samples/Playground/Playground.csproj +++ b/samples/Playground/Playground.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 enable false $(NoWarn);NETSDK1023 diff --git a/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs b/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs index 584d98446a..d4c34388a2 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs @@ -16,7 +16,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// public class LogMessageListener : IDisposable { - private static readonly object TraceLock = new(); + private static readonly Lock TraceLock = new(); private static int s_listenerCount; private static ThreadSafeStringWriter? s_redirectedDebugTrace; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs index 4cdc59959c..3535d58cc0 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs @@ -20,17 +20,14 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// public class TestAssemblyInfo { - private readonly object _assemblyInfoExecuteSyncObject; + private readonly Lock _assemblyInfoExecuteSyncObject = new(); /// /// Initializes a new instance of the class. /// /// Sets the this class is representing. internal TestAssemblyInfo(Assembly assembly) - { - _assemblyInfoExecuteSyncObject = new object(); - Assembly = assembly; - } + => Assembly = assembly; /// /// Gets AssemblyInitialize method for the assembly. diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index e5de71475b..a4a22576c2 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -22,7 +22,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// public class TestClassInfo { - private readonly object _testClassExecuteSyncObject = new(); + private readonly Lock _testClassExecuteSyncObject = new(); /// /// Initializes a new instance of the class. diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.NonWindows.nuspec b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.NonWindows.nuspec index 6bd0c6adb2..9e6505d523 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.NonWindows.nuspec +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.NonWindows.nuspec @@ -24,6 +24,10 @@ + + + + PACKAGE.md @@ -70,6 +74,14 @@ + + + + + + + + diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec index dcb1207828..fab41babbc 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec @@ -32,6 +32,10 @@ + + + + PACKAGE.md @@ -88,6 +92,14 @@ + + + + + + + + diff --git a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs index 59ae87d210..36b4c02954 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs @@ -84,7 +84,7 @@ class AssemblyResolver : /// /// lock for the loaded assemblies cache. /// - private readonly object _syncLock = new(); + private readonly Lock _syncLock = new(); private static List? s_currentlyLoading; private bool _disposed; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Shipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..b5ff64abc0 --- /dev/null +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Shipped.txt @@ -0,0 +1,33 @@ +#nullable enable +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment.TestRunDirectories +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment.TestRunDirectories.InDirectory.get -> string! +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment.TestRunDirectories.InMachineNameDirectory.get -> string! +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment.TestRunDirectories.OutDirectory.get -> string! +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment.TestRunDirectories.RootDeploymentDirectory.get -> string! +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment.TestRunDirectories.RootDeploymentDirectory.set -> void +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment.TestRunDirectories.TestRunDirectories(string! rootDirectory) -> void +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DeleteDeploymentDirectoryAfterTestRunIsComplete.get -> bool +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DeploymentEnabled.get -> bool +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DeployTestSourceDependencies.get -> bool +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.GetDirectoryListWithRecursiveProperty(string! baseDirectory) -> System.Collections.Generic.List! +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.MSTestAdapterSettings() -> void +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.SearchDirectories.get -> System.Collections.Generic.List! +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.RecursiveDirectoryPath +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.RecursiveDirectoryPath.DirectoryPath.get -> string! +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.RecursiveDirectoryPath.IncludeSubDirectories.get -> bool +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.RecursiveDirectoryPath.RecursiveDirectoryPath(string! dirPath, bool includeSubDirectories) -> void +override Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.RecursiveDirectoryPath.InitializeLifetimeService() -> object! +override Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.DeploymentDirectory.get -> string? +override Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.FullyQualifiedTestClassName.get -> string! +override Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.ResultsDirectory.get -> string? +override Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.TestName.get -> string! +override Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.TestResultsDirectory.get -> string? +override Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.TestRunDirectory.get -> string? +override Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.TestRunResultsDirectory.get -> string? +static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.IsAppDomainCreationDisabled(string? settingsXml) -> bool +static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ToSettings(System.Xml.XmlReader! reader) -> Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings! +static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Reset() -> void +static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Settings.get -> Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings! +virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DoesDirectoryExist(string! path) -> bool +virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! \ No newline at end of file diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Unshipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs index d898382960..edebecf31b 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs @@ -18,7 +18,7 @@ public class ThreadSafeStringWriter : StringWriter // This static lock guards access to the state and getting values from dictionary. There can be multiple different instances of ThreadSafeStringWriter // accessing the state at the same time, and we need to give them the correct state for their async context. Non-concurrent dictionary is used to store the // state because we need to lock around it anyway, to ensure that the State is populated, but not overwritten by every new instance of ThreadSafeStringWriter. - private static readonly object StaticLockObject = new(); + private static readonly Lock StaticLockObject = new(); private readonly string _outputType; /// @@ -175,7 +175,7 @@ private ThreadSafeStringBuilder GetOrAddStringBuilder() private class ThreadSafeStringBuilder { private readonly StringBuilder _stringBuilder = new(); - private readonly object _instanceLockObject = new(); + private readonly Lock _instanceLockObject = new(); public void Append(string? value) { diff --git a/src/Package/MSTest/MSTest.NonWindows.nuspec b/src/Package/MSTest/MSTest.NonWindows.nuspec index 0559e35a8b..2a3c74c888 100644 --- a/src/Package/MSTest/MSTest.NonWindows.nuspec +++ b/src/Package/MSTest/MSTest.NonWindows.nuspec @@ -37,6 +37,13 @@ + + + + + + + diff --git a/src/Package/MSTest/MSTest.nuspec b/src/Package/MSTest/MSTest.nuspec index 7506c0555c..7341858a85 100644 --- a/src/Package/MSTest/MSTest.nuspec +++ b/src/Package/MSTest/MSTest.nuspec @@ -52,6 +52,13 @@ + + + + + + + PACKAGE.md diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs index 95c7169762..e365c36b75 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs @@ -35,7 +35,7 @@ public class InvokeTestingPlatformTask : Build.Utilities.ToolTask, IDisposable private readonly CancellationTokenSource _waitForConnections = new(); private readonly List _connections = new(); private readonly StringBuilder _output = new(); - private readonly object _initLock = new(); + private readonly Lock _initLock = new(); private readonly Process _currentProcess = Process.GetCurrentProcess(); private readonly Architecture _currentProcessArchitecture = RuntimeInformation.ProcessArchitecture; diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/ObjectPool.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/ObjectPool.cs index 63716f3cdb..38dc4a7530 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/ObjectPool.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/ObjectPool.cs @@ -128,9 +128,7 @@ internal ObjectPool(Factory factory) internal ObjectPool(Factory factory, int size) { -#pragma warning disable SA1405 // Debug.Assert should provide message text - Debug.Assert(size >= 1); -#pragma warning restore SA1405 // Debug.Assert should provide message text + RoslynDebug.Assert(size >= 1); _factory = factory; _items = new Element[size - 1]; } diff --git a/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.NonWindows.nuspec b/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.NonWindows.nuspec index cda91f2b76..0ec5da8496 100644 --- a/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.NonWindows.nuspec +++ b/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.NonWindows.nuspec @@ -8,6 +8,7 @@ + PACKAGE.md @@ -52,6 +53,14 @@ + + + + + + + + diff --git a/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.nuspec b/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.nuspec index 3c7f9c9f87..9e9a3ce8a3 100644 --- a/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.nuspec +++ b/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.nuspec @@ -10,6 +10,7 @@ + PACKAGE.md @@ -70,6 +71,14 @@ + + + + + + + + diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..f9d5205b2e --- /dev/null +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Shipped.txt @@ -0,0 +1,14 @@ +#nullable enable +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path, string? outputDirectory) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.OutputDirectory.get -> string? +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.Path.get -> string? +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.DeploymentDirectory.get -> string? +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.ResultsDirectory.get -> string? +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDeploymentDir.get -> string? +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDir.get -> string? +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestLogsDir.get -> string? +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestResultsDirectory.get -> string? +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunDirectory.get -> string? +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? \ No newline at end of file diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..815c92006a --- /dev/null +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +#nullable enable \ No newline at end of file diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs index ef972a347f..22c7931d86 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs @@ -74,8 +74,9 @@ public async Task RunTests_With_VSTest(string multiTfm, BuildConfiguration build DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test -c {buildConfiguration} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.AreEqual(0, compilationResult.ExitCode); - compilationResult.AssertOutputRegEx(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net8\.0\)"); + compilationResult.AssertOutputRegEx(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net9\.0\)"); #if !SKIP_INTERMEDIATE_TARGET_FRAMEWORKS + compilationResult.AssertOutputRegEx(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net8\.0\)"); compilationResult.AssertOutputRegEx(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net7\.0\)"); compilationResult.AssertOutputRegEx(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net6\.0\)"); #endif @@ -99,8 +100,9 @@ public async Task RunTests_With_MSTestRunner_DotnetTest(string multiTfm, BuildCo DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test -c {buildConfiguration} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.AreEqual(0, compilationResult.ExitCode); - compilationResult.AssertOutputRegEx(@"Tests succeeded: .* \[net8\.0|x64\]"); + compilationResult.AssertOutputRegEx(@"Tests succeeded: .* \[net9\.0|x64\]"); #if !SKIP_INTERMEDIATE_TARGET_FRAMEWORKS + compilationResult.AssertOutputRegEx(@"Tests succeeded: .* \[net8\.0|x64\]"); compilationResult.AssertOutputRegEx(@"Tests succeeded: .* \[net7\.0|x64\]"); compilationResult.AssertOutputRegEx(@"Tests succeeded: .* \[net6\.0|x64\]"); #endif diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs index d7c4abd3f9..9c3b9f9e8c 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs @@ -154,7 +154,7 @@ await DotnetCli.RunAsync( environmentVariables: dotnetRootX86, failIfReturnValueIsNotZero: false); - string outputFileLog = Directory.GetFiles(testAsset.TargetAssetPath, "MSBuild Tests_net8.0_x86.log", SearchOption.AllDirectories).Single(); + string outputFileLog = Directory.GetFiles(testAsset.TargetAssetPath, $"MSBuild Tests_net9.0_x86.log", SearchOption.AllDirectories).Single(); Assert.IsTrue(File.Exists(outputFileLog), $"Expected file '{outputFileLog}'"); string logFileContent = File.ReadAllText(outputFileLog); Assert.IsTrue(Regex.IsMatch(logFileContent, ".*win-x86.*"), logFileContent); @@ -227,7 +227,7 @@ await DotnetCli.RunAsync( environmentVariables: dotnetHostPathEnvVar, failIfReturnValueIsNotZero: false); - string outputFileLog = Directory.GetFiles(testAsset.TargetAssetPath, "MSBuild Tests_net8.0_x64.log", SearchOption.AllDirectories).Single(); + string outputFileLog = Directory.GetFiles(testAsset.TargetAssetPath, "MSBuild Tests_net9.0_x64.log", SearchOption.AllDirectories).Single(); Assert.IsTrue(File.Exists(outputFileLog), $"Expected file '{outputFileLog}'"); string logFileContent = File.ReadAllText(outputFileLog); Assert.IsTrue(Regex.IsMatch(logFileContent, @"\.dotnet\\dotnet\.exe"), logFileContent); diff --git a/test/Performance/MSTest.Performance.Runner/MSTest.Performance.Runner.csproj b/test/Performance/MSTest.Performance.Runner/MSTest.Performance.Runner.csproj index fba56e108c..eb2306c412 100644 --- a/test/Performance/MSTest.Performance.Runner/MSTest.Performance.Runner.csproj +++ b/test/Performance/MSTest.Performance.Runner/MSTest.Performance.Runner.csproj @@ -2,7 +2,7 @@ Exe - net8.0 + net9.0 enable diff --git a/test/Performance/MSTest.Performance.Runner/Program.cs b/test/Performance/MSTest.Performance.Runner/Program.cs index a5e94f2991..c5e424ee05 100644 --- a/test/Performance/MSTest.Performance.Runner/Program.cs +++ b/test/Performance/MSTest.Performance.Runner/Program.cs @@ -41,7 +41,7 @@ private static int Pipelines(string pipelineNameFilter) pipelineRunner.AddPipeline("Default", "Scenario1_PerfView", [OSPlatform.Windows], parametersBag => Pipeline - .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net8.0", executionScope: ExecutionScope.MethodLevel), parametersBag) + .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net9.0", executionScope: ExecutionScope.MethodLevel), parametersBag) .NextStep(() => new DotnetMuxer(BuildConfiguration.Debug)) .NextStep(() => new PerfviewRunner(" /BufferSizeMB:1024 ", "Scenario1_PerfView.zip", includeScenario: true)) .NextStep(() => new MoveFiles("*.zip", Path.Combine(Directory.GetCurrentDirectory(), "Results"))) @@ -49,7 +49,7 @@ private static int Pipelines(string pipelineNameFilter) pipelineRunner.AddPipeline("Default", "Scenario1_DotnetTrace", [OSPlatform.Windows], parametersBag => Pipeline - .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net8.0", executionScope: ExecutionScope.MethodLevel), parametersBag) + .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net9.0", executionScope: ExecutionScope.MethodLevel), parametersBag) .NextStep(() => new DotnetMuxer(BuildConfiguration.Debug)) .NextStep(() => new DotnetTrace("--profile cpu-sampling", "DotnetTrace_CPU_Sampling.zip")) .NextStep(() => new MoveFiles("*.zip", Path.Combine(Directory.GetCurrentDirectory(), "Results"))) @@ -58,14 +58,14 @@ private static int Pipelines(string pipelineNameFilter) // C:\Program Files\Microsoft Visual Studio\2022\Preview\Team Tools\DiagnosticsHub\Collector\AgentConfigs pipelineRunner.AddPipeline("Default", "Scenario1_DotNetObjectAllocBase", [OSPlatform.Windows], parametersBag => Pipeline - .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net8.0", executionScope: ExecutionScope.MethodLevel), parametersBag) + .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net9.0", executionScope: ExecutionScope.MethodLevel), parametersBag) .NextStep(() => new DotnetMuxer(BuildConfiguration.Debug)) .NextStep(() => new VSDiagnostics("DotNetObjectAllocLow.json", "Scenario1_DotNetObjectAllocBase.zip")) .NextStep(() => new MoveFiles("*.zip", Path.Combine(Directory.GetCurrentDirectory(), "Results"))) .NextStep(() => new CleanupDisposable())); pipelineRunner.AddPipeline("Default", "Scenario1_CpuUsageLow", [OSPlatform.Windows], parametersBag => Pipeline - .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net8.0", executionScope: ExecutionScope.MethodLevel), parametersBag) + .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net9.0", executionScope: ExecutionScope.MethodLevel), parametersBag) .NextStep(() => new DotnetMuxer(BuildConfiguration.Debug)) .NextStep(() => new VSDiagnostics("CpuUsageHigh.json", "Scenario1_CpuUsageLow.zip")) .NextStep(() => new MoveFiles("*.zip", Path.Combine(Directory.GetCurrentDirectory(), "Results"))) @@ -73,7 +73,7 @@ private static int Pipelines(string pipelineNameFilter) pipelineRunner.AddPipeline("Default", "Scenario1_ConcurrencyVisualizer", [OSPlatform.Windows], parametersBag => Pipeline - .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net8.0", executionScope: ExecutionScope.MethodLevel), parametersBag) + .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net9.0", executionScope: ExecutionScope.MethodLevel), parametersBag) .NextStep(() => new DotnetMuxer(BuildConfiguration.Debug)) .NextStep(() => new ConcurrencyVisualizer("Scenario1_ConcurrencyVisualizer.zip")) .NextStep(() => new MoveFiles("*.zip", Path.Combine(Directory.GetCurrentDirectory(), "Results"))) @@ -81,7 +81,7 @@ private static int Pipelines(string pipelineNameFilter) pipelineRunner.AddPipeline("Default", "Scenario1_PlainProcess", [OSPlatform.Windows], parametersBag => Pipeline - .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net8.0", executionScope: ExecutionScope.MethodLevel), parametersBag) + .FirstStep(() => new Scenario1(numberOfClass: 100, methodsPerClass: 100, tfm: "net9.0", executionScope: ExecutionScope.MethodLevel), parametersBag) .NextStep(() => new DotnetMuxer(BuildConfiguration.Debug)) .NextStep(() => new PlainProcess("Scenario1_PlainProcess.zip")) .NextStep(() => new MoveFiles("*.zip", Path.Combine(Directory.GetCurrentDirectory(), "Results"))) diff --git a/test/Performance/MSTest.Performance.Runner/Scenarios/Scenario1.cs b/test/Performance/MSTest.Performance.Runner/Scenarios/Scenario1.cs index 33768cd2dd..c9c4662bcf 100644 --- a/test/Performance/MSTest.Performance.Runner/Scenarios/Scenario1.cs +++ b/test/Performance/MSTest.Performance.Runner/Scenarios/Scenario1.cs @@ -106,7 +106,7 @@ public class UnitTest{{i}} addPublicFeeds: true); context.AddDisposable(generator); - return new SingleProject(["net8.0"], generator, nameof(Scenario1)); + return new SingleProject(["net9.0"], generator, nameof(Scenario1)); } private static string ExtractVersionFromPackage(string rootFolder, string packagePrefixName) diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs index d217e073ec..f5bdc6d05e 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs @@ -11,8 +11,9 @@ public static class TargetFrameworks { public static TestArgumentsEntry[] Net { get; } = [ - new("net8.0", "net8.0"), + new("net9.0", "net9.0"), #if !SKIP_INTERMEDIATE_TARGET_FRAMEWORKS + new("net8.0", "net8.0"), new("net7.0", "net7.0"), new("net6.0", "net6.0"), #endif From b2a79a50fef98834fd91974ecc067d5c1534a1c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 09:09:33 +0100 Subject: [PATCH 016/273] [main] Bump StreamJsonRpc (#4173) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 60b3004b2f..46a11b43eb 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -76,7 +76,7 @@ - + From c6c5ff0ed5d81b05fd7c33b3bc0e39fe96e479ca Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 08:43:12 +0000 Subject: [PATCH 017/273] [main] Bump Polyfill from 7.4.0 to 7.5.0 (#4174) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 46a11b43eb..a43b584c91 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -46,7 +46,7 @@ - + From 034defc9b380b1397352a8811947884728944b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 27 Nov 2024 10:21:16 +0100 Subject: [PATCH 018/273] Use VS version 17.12 (#4176) --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 8c4683a69c..f657e974e0 100644 --- a/global.json +++ b/global.json @@ -17,7 +17,7 @@ ] }, "vs": { - "version": "17.8.0" + "version": "17.12.0" } }, "sdk": { From f15997e27e3f15ff452fc5678a73432109c43d37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 27 Nov 2024 11:12:50 +0100 Subject: [PATCH 019/273] Use windows.vs2022preview.amd64 (#4177) --- azure-pipelines-official.yml | 2 +- global.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index 832eb75c92..8909a82eb7 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -73,7 +73,7 @@ extends: autoBaseline: true pool: name: $(DncEngInternalBuildPool) - image: windows.vs2022.amd64 + image: windows.vs2022preview.amd64 os: windows customBuildTags: - ES365AIMigrationTooling diff --git a/global.json b/global.json index f657e974e0..8c4683a69c 100644 --- a/global.json +++ b/global.json @@ -17,7 +17,7 @@ ] }, "vs": { - "version": "17.12.0" + "version": "17.8.0" } }, "sdk": { From 0b903b9aa8037467edc778e55e95a783eed97df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Wed, 27 Nov 2024 12:51:19 +0100 Subject: [PATCH 020/273] Show the text that timed out in regex match (#4175) Co-authored-by: Youssef Victor --- .../Terminal/TerminalTestReporter.cs | 25 ++++++++++++++++++- .../Resources/PlatformResources.resx | 6 ++++- .../Resources/xlf/PlatformResources.cs.xlf | 5 ++++ .../Resources/xlf/PlatformResources.de.xlf | 5 ++++ .../Resources/xlf/PlatformResources.es.xlf | 5 ++++ .../Resources/xlf/PlatformResources.fr.xlf | 5 ++++ .../Resources/xlf/PlatformResources.it.xlf | 5 ++++ .../Resources/xlf/PlatformResources.ja.xlf | 5 ++++ .../Resources/xlf/PlatformResources.ko.xlf | 5 ++++ .../Resources/xlf/PlatformResources.pl.xlf | 5 ++++ .../Resources/xlf/PlatformResources.pt-BR.xlf | 5 ++++ .../Resources/xlf/PlatformResources.ru.xlf | 5 ++++ .../Resources/xlf/PlatformResources.tr.xlf | 5 ++++ .../xlf/PlatformResources.zh-Hans.xlf | 5 ++++ .../xlf/PlatformResources.zh-Hant.xlf | 5 ++++ 15 files changed, 94 insertions(+), 2 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs index afcc850879..bc7bda8e50 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs @@ -4,9 +4,13 @@ #if !NET7_0_OR_GREATER using System.Diagnostics.CodeAnalysis; using System.Reflection; + #endif using System.Globalization; +#if !NETSTANDARD +using System.Runtime.ExceptionServices; +#endif using System.Text.RegularExpressions; using Microsoft.Testing.Platform.Helpers; @@ -647,7 +651,26 @@ private static void AppendAssemblyLinkTargetFrameworkAndArchitecture(ITerminal t internal /* for testing */ static void AppendStackFrame(ITerminal terminal, string stackTraceLine) { terminal.Append(DoubleIndentation); - Match match = GetFrameRegex().Match(stackTraceLine); + Match match; + try + { + match = GetFrameRegex().Match(stackTraceLine); + } + catch (RegexMatchTimeoutException ex) + { + // Add the stack trace line that was being matched to test locally. + var newTimeoutException = new RegexMatchTimeoutException(string.Format(CultureInfo.CurrentCulture, PlatformResources.TimeoutInRegexStackTraceLineParsing, stackTraceLine), ex); +#if !NETSTANDARD + throw ex.StackTrace is null + ? newTimeoutException + // Otherwise preserve the stack trace, so we can tell if this was using + // the generated regex or not. + : ExceptionDispatchInfo.SetRemoteStackTrace(newTimeoutException, ex.StackTrace); +#else + throw newTimeoutException; +#endif + } + if (match.Success) { bool weHaveFilePathAndCodeLine = !RoslynString.IsNullOrWhiteSpace(match.Groups["code"].Value); diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx index 5bd7f79c1a..36568d505e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx +++ b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx @@ -671,4 +671,8 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is The configuration file '{0}' specified with '--config-file' could not be found. - + + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index 51789c6317..7cf0a5fd4e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -825,6 +825,11 @@ Platné hodnoty jsou Normal a Detailed. Výchozí hodnota je Normal. Nepovedlo se vyprázdnit protokoly před vypršením časového limitu {0} s. + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total Celkem diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index 154d7a643b..0376d01bed 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -825,6 +825,11 @@ Gültige Werte sind „Normal“, „Detailed“. Der Standardwert ist „Normal Fehler beim Leeren von Protokollen vor dem Timeout von "{0}" Sekunden + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total Gesamt diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index ffc6cc0328..5715077b33 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -825,6 +825,11 @@ Los valores válidos son 'Normal', 'Detallado'. El valor predeterminado es 'Norm No se pudieron vaciar los registros antes del tiempo de espera de “{0}” segundos + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total Total diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index d312b88920..eafa1d1900 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -825,6 +825,11 @@ Les valeurs valides sont « Normal » et « Détaillé ». La valeur par dé Échec du vidage des journaux avant le délai d’expiration de « {0} » secondes + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total Total diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index b87e60db7c..10fec28c72 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -825,6 +825,11 @@ I valori validi sono 'Normal', 'Detailed'. L'impostazione predefinita è 'Normal Non è stato possibile scaricare i log prima del timeout di '{0}' secondi + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total Totale diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index d7e5015d90..081184d1f8 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -826,6 +826,11 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. '{0}' 秒のタイムアウト前にログをフラッシュできませんでした + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total 合計 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index 9c15b13c2d..bdebab13af 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -825,6 +825,11 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. '{0}'초의 시간 제한 전에 로그를 플러시하지 못했습니다. + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total 합계 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index b8e6cb922e..533e43c562 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -825,6 +825,11 @@ Prawidłowe wartości to „Normalne”, „Szczegółowe”. Wartość domyśln Nie można opróżnić dzienników przed upływem limitu czasu wynoszącego „{0}” s + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total Łącznie diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index bcb11fe735..9e11d5bfe7 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -825,6 +825,11 @@ Os valores válidos são “Normal”, “Detalhado”. O padrão é “Normal Falha ao liberar logs antes do tempo limite de '{0}' segundos + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total Total diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index 6495697d60..b9ccbc8183 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -825,6 +825,11 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. Не удалось записать журналы на диск до истечения времени ожидания ("{0}" с) + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total Всего diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 03b115291e..89430bf8ae 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -825,6 +825,11 @@ Geçerli değerler: ‘Normal’, ‘Ayrıntılı’. Varsayılan değer: ‘Nor '{0}' saniyelik zaman aşımından önce günlükler boşaltılamadı + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total Toplam diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index b90e61c75d..983303309c 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -825,6 +825,11 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. 未能在“{0}”秒超时之前刷新日志 + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total 总计 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index b9b18bdbaa..92158a8068 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -825,6 +825,11 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. 無法在 '{0}' 秒逾時前排清記錄 + + Parsing stack trace line with regex timed out. Input: '{0}' + Parsing stack trace line with regex timed out. Input: '{0}' + {0} is the line that was being matched + Total 總計 From aaf947af985c3a7c684a319ffd3e734911c6fd88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Wed, 27 Nov 2024 13:17:27 +0100 Subject: [PATCH 021/273] Use windows.vs2022preview.amd64 on all tasks (#4179) --- azure-pipelines-official.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index 8909a82eb7..c1c6ae1765 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -97,7 +97,7 @@ extends: timeoutInMinutes: 90 pool: name: $(DncEngInternalBuildPool) - image: windows.vs2022.amd64 + image: windows.vs2022preview.amd64 os: windows steps: - task: PowerShell@2 From 3a35de9c4cf917e7d3492c22ff2be13fd9bbe2e3 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 27 Nov 2024 16:24:33 +0100 Subject: [PATCH 022/273] Refactor WarnOnUnsupportedEntries (#4182) --- .../ObjectModel/RunSettingsAdapter.cs | 59 ++++++------------- 1 file changed, 17 insertions(+), 42 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs index ac2175740e..5eff0ec573 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs @@ -24,6 +24,18 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; /// internal sealed class RunSettingsAdapter : IRunSettings { + private static readonly string[] UnsupportedRunConfigurationSettings = [ + "MaxCpuCount", + "TargetFrameworkVersion", + "TargetPlatform", + "TreatTestAdapterErrorsAsWarnings", + "TestAdaptersPaths", + "TestCaseFilter", + "TestSessionTimeout", + "DotnetHostPath", + "TreatNoTestsAsError", + ]; + public RunSettingsAdapter( ICommandLineOptions commandLineOptions, IFileSystem fileSystem, @@ -92,49 +104,12 @@ private static void WarnOnUnsupportedEntries(XDocument document, IMessageLogger return; } - if (runConfigurationElement.Element("MaxCpuCount") is not null) - { - messageLogger.SendMessage(TestMessageLevel.Warning, string.Format(CultureInfo.InvariantCulture, ExtensionResources.UnsupportedRunconfigurationSetting, "MaxCpuCount")); - } - - if (runConfigurationElement.Element("TargetFrameworkVersion") is not null) - { - messageLogger.SendMessage(TestMessageLevel.Warning, string.Format(CultureInfo.InvariantCulture, ExtensionResources.UnsupportedRunconfigurationSetting, "TargetFrameworkVersion")); - } - - if (runConfigurationElement.Element("TargetPlatform") is not null) + foreach (string unsupportedRunConfigurationSetting in UnsupportedRunConfigurationSettings) { - messageLogger.SendMessage(TestMessageLevel.Warning, string.Format(CultureInfo.InvariantCulture, ExtensionResources.UnsupportedRunconfigurationSetting, "TargetPlatform")); - } - - if (runConfigurationElement.Element("TreatTestAdapterErrorsAsWarnings") is not null) - { - messageLogger.SendMessage(TestMessageLevel.Warning, string.Format(CultureInfo.InvariantCulture, ExtensionResources.UnsupportedRunconfigurationSetting, "TreatTestAdapterErrorsAsWarnings")); - } - - if (runConfigurationElement.Element("TestAdaptersPaths") is not null) - { - messageLogger.SendMessage(TestMessageLevel.Warning, string.Format(CultureInfo.InvariantCulture, ExtensionResources.UnsupportedRunconfigurationSetting, "TestAdaptersPaths")); - } - - if (runConfigurationElement.Element("TestCaseFilter") is not null) - { - messageLogger.SendMessage(TestMessageLevel.Warning, string.Format(CultureInfo.InvariantCulture, ExtensionResources.UnsupportedRunconfigurationSetting, "TestCaseFilter")); - } - - if (runConfigurationElement.Element("TestSessionTimeout") is not null) - { - messageLogger.SendMessage(TestMessageLevel.Warning, string.Format(CultureInfo.InvariantCulture, ExtensionResources.UnsupportedRunconfigurationSetting, "TestSessionTimeout")); - } - - if (runConfigurationElement.Element("DotnetHostPath") is not null) - { - messageLogger.SendMessage(TestMessageLevel.Warning, string.Format(CultureInfo.InvariantCulture, ExtensionResources.UnsupportedRunconfigurationSetting, "DotnetHostPath")); - } - - if (runConfigurationElement.Element("TreatNoTestsAsError") is not null) - { - messageLogger.SendMessage(TestMessageLevel.Warning, string.Format(CultureInfo.InvariantCulture, ExtensionResources.UnsupportedRunconfigurationSetting, "TreatNoTestsAsError")); + if (runConfigurationElement.Element(unsupportedRunConfigurationSetting) is not null) + { + messageLogger.SendMessage(TestMessageLevel.Warning, string.Format(CultureInfo.InvariantCulture, ExtensionResources.UnsupportedRunconfigurationSetting, unsupportedRunConfigurationSetting)); + } } } } From 5f6da8ca1ea4ae37eaae70a5f9f6f5cfef84e0f0 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 17:21:19 +0100 Subject: [PATCH 023/273] [main] Update dependencies from dotnet/arcade, microsoft/testanywhere (#4180) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- global.json | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index dd4da70eec..f867260244 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,25 +1,25 @@ - + https://github.com/dotnet/arcade - 2a3bf4e3a4c473135d058adcd7193a5a4bcd38a7 + 9ad0880a9f8450f4ac4e097cfe830e401ea3e22c - + https://github.com/dotnet/arcade - 2a3bf4e3a4c473135d058adcd7193a5a4bcd38a7 + 9ad0880a9f8450f4ac4e097cfe830e401ea3e22c - + https://github.com/dotnet/arcade - 2a3bf4e3a4c473135d058adcd7193a5a4bcd38a7 + 9ad0880a9f8450f4ac4e097cfe830e401ea3e22c https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage 2d88381a218863f6b20537637b2bcfb0bc93686d - + https://github.com/microsoft/testanywhere - 0628cb69980b9b2a41b0dcc20a9ffdf181e942f6 + f01fa388c7ec30f4f92ee01c2db94cc8e7a93ae8 https://github.com/microsoft/testanywhere diff --git a/eng/Versions.props b/eng/Versions.props index 7bb8254454..38501decc2 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,10 +7,10 @@ preview - 10.0.0-beta.24575.1 + 10.0.0-beta.24576.1 17.13.0-preview.24572.7 - 1.5.0-preview.24575.1 + 1.5.0-preview.24576.1 1.0.0-alpha.24473.2 diff --git a/global.json b/global.json index 8c4683a69c..b72e6c86d4 100644 --- a/global.json +++ b/global.json @@ -26,7 +26,7 @@ "rollForward": "latestFeature" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.24575.1", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.24576.1", "MSBuild.Sdk.Extras": "3.0.44" } } From d629d7b031e85ea1083fc284dfd7ae79428e197a Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 27 Nov 2024 17:21:49 +0100 Subject: [PATCH 024/273] Fix local warning (and fix typo) (#4185) --- .../MSTestBridgedTestFramework.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs index 5160e34c44..6a9ca840a1 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs @@ -17,14 +17,12 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; internal sealed class MSTestBridgedTestFramework : SynchronizedSingleSessionVSTestBridgedTestFramework { - private readonly IConfiguration? _configration; + private readonly IConfiguration? _configuration; public MSTestBridgedTestFramework(MSTestExtension mstestExtension, Func> getTestAssemblies, IServiceProvider serviceProvider, ITestFrameworkCapabilities capabilities) : base(mstestExtension, getTestAssemblies, serviceProvider, capabilities) - { - _configration = serviceProvider.GetConfiguration(); - } + => _configuration = serviceProvider.GetConfiguration(); /// protected override Task SynchronizedDiscoverTestsAsync(VSTestDiscoverTestExecutionRequest request, IMessageBus messageBus, @@ -36,7 +34,7 @@ protected override Task SynchronizedDiscoverTestsAsync(VSTestDiscoverTestExecuti Debugger.Launch(); } - MSTestDiscoverer.DiscoverTests(request.AssemblyPaths, request.DiscoveryContext, request.MessageLogger, request.DiscoverySink, _configration); + MSTestDiscoverer.DiscoverTests(request.AssemblyPaths, request.DiscoveryContext, request.MessageLogger, request.DiscoverySink, _configuration); return Task.CompletedTask; } @@ -54,11 +52,11 @@ protected override Task SynchronizedRunTestsAsync(VSTestRunTestExecutionRequest if (request.VSTestFilter.TestCases is { } testCases) { - testExecutor.RunTests(testCases, request.RunContext, request.FrameworkHandle, _configration); + testExecutor.RunTests(testCases, request.RunContext, request.FrameworkHandle, _configuration); } else { - testExecutor.RunTests(request.AssemblyPaths, request.RunContext, request.FrameworkHandle, _configration); + testExecutor.RunTests(request.AssemblyPaths, request.RunContext, request.FrameworkHandle, _configuration); } return Task.CompletedTask; From 8605b32b757e230b801c2cdbcf5be3bf6d9efe74 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 27 Nov 2024 17:24:27 +0100 Subject: [PATCH 025/273] Mark IgnoreAttribute as not inherited (#4183) --- .../TestFramework/Attributes/TestMethod/IgnoreAttribute.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/IgnoreAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/IgnoreAttribute.cs index 0f449e9b87..04950c969e 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/IgnoreAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/IgnoreAttribute.cs @@ -6,7 +6,7 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// /// The ignore attribute. /// -[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)] +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false)] public sealed class IgnoreAttribute : Attribute { /// From 73ea79ce5eb9c1330bff48f7b8f96a3c6352d34b Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 27 Nov 2024 20:05:00 +0100 Subject: [PATCH 026/273] Small XML doc refreshing (#4184) --- .../DataSource/DataSourceAttribute.cs | 12 ++++++++-- .../DataSource/DataTestMethodAttribute.cs | 3 ++- .../TestMethod/ExpectedExceptionAttribute.cs | 3 +++ .../ExpectedExceptionBaseAttribute.cs | 3 +++ .../Attributes/TestMethod/IgnoreAttribute.cs | 9 +++++--- .../TestMethod/TestClassAttribute.cs | 10 ++++++++- .../TestMethod/TestMethodAttribute.cs | 22 ++++++++++++++++++- 7 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs index e5de74e0b9..b23dec0cab 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs @@ -8,10 +8,18 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// /// Specifies connection string, table name and row access method for data driven testing. /// -/// +/// +/// +/// This works only on .NET Framework and is not supported on .NET Core or later. +/// +/// The following shows example usages for this attribute: +/// /// [DataSource("Provider=SQLOLEDB.1;Data Source=source;Integrated Security=SSPI;Initial Catalog=EqtCoverage;Persist Security Info=False", "MyTable")] /// [DataSource("dataSourceNameFromConfigFile")]. -/// +/// +/// +/// +/// [SuppressMessage("Microsoft.Design", "CA1019:DefineAccessorsForAttributeArguments", Justification = "Compat")] [AttributeUsage(AttributeTargets.Method)] public sealed class DataSourceAttribute : Attribute diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DataTestMethodAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DataTestMethodAttribute.cs index 70d7372b43..7ccc26126a 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DataTestMethodAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DataTestMethodAttribute.cs @@ -4,7 +4,8 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// -/// Attribute for data driven test where data can be specified in-line. +/// This attribute doesn't currently provide any different functionality compared to . It's only +/// present for backward compatibility. Using is recommended, even for parameterized tests. /// [AttributeUsage(AttributeTargets.Method)] public class DataTestMethodAttribute : TestMethodAttribute diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionAttribute.cs index 6032f64691..5cd6c160b8 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionAttribute.cs @@ -8,6 +8,9 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// /// Attribute that specifies to expect an exception of the specified type. /// +/// +/// We recommend using one of the Assert.ThrowsException or Assert.ThrowsExceptionAsync overload instead of using this attribute. +/// [AttributeUsage(AttributeTargets.Method)] public sealed class ExpectedExceptionAttribute : ExpectedExceptionBaseAttribute { diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionBaseAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionBaseAttribute.cs index 6efdc80d90..e15d9f4889 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionBaseAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionBaseAttribute.cs @@ -9,6 +9,9 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// /// Base class for attributes that specify to expect an exception from a unit test. /// +/// +/// We recommend using one of the Assert.ThrowsException or Assert.ThrowsExceptionAsync overload instead of using this attribute. +/// [AttributeUsage(AttributeTargets.Method)] public abstract class ExpectedExceptionBaseAttribute : Attribute { diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/IgnoreAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/IgnoreAttribute.cs index 04950c969e..c175d68358 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/IgnoreAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/IgnoreAttribute.cs @@ -4,13 +4,16 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// -/// The ignore attribute. +/// This attribute is used to ignore a test class or a test method, with an optional message. /// +/// +/// This attribute isn't inherited. Applying it to a base class will not cause derived classes to be ignored. +/// [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false)] public sealed class IgnoreAttribute : Attribute { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class with an empty message. /// public IgnoreAttribute() : this(string.Empty) @@ -26,7 +29,7 @@ public IgnoreAttribute() public IgnoreAttribute(string? message) => IgnoreMessage = message; /// - /// Gets the owner. + /// Gets the ignore message indicating the reason for ignoring the test method or test class. /// public string? IgnoreMessage { get; } } diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs index 77d80855cd..9c7bb5745d 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs @@ -4,8 +4,16 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// -/// The test class attribute. +/// This attribute is used to mark test classes. /// +/// +/// Test classes must be: +/// +/// public, or if is used then it can be internal. +/// not static +/// not generic +/// +/// [AttributeUsage(AttributeTargets.Class)] public class TestClassAttribute : Attribute { diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs index bca969e00f..319fcec986 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs @@ -3,9 +3,29 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; +#pragma warning disable CS1574 // XML comment has cref attribute that could not be resolved - The warning is for ValueTask. /// -/// The test method attribute. +/// This attribute is used to mark test methods. /// +/// +/// +/// +/// When using other attributes like or , it +/// the use of is still required. +/// +/// +/// Test methods must be: +/// +/// public, or if is used then it can be internal. +/// not static +/// not generic +/// not abstract +/// return type is either , , or . If , then it shouldn't be . +/// +/// +/// +/// +#pragma warning restore CS1574 // XML comment has cref attribute that could not be resolved// XML comment has cref attribute that could not be resolved [AttributeUsage(AttributeTargets.Method)] public class TestMethodAttribute : Attribute { From 70546c0d261f2b5fda45684be88e751c6dfb5f2d Mon Sep 17 00:00:00 2001 From: Tom Longhurst <30480171+thomhurst@users.noreply.github.com> Date: Wed, 27 Nov 2024 19:06:06 +0000 Subject: [PATCH 027/273] Improve Regex to Reduce Matching Time (#4160) Co-authored-by: Tom Longhurst <130671542+msm-tomlonghurst@users.noreply.github.com> --- .../Terminal/TerminalTestReporter.cs | 28 +- .../Terminal/TerminalTestReporterTests.cs | 469 ++++++++++++++++++ 2 files changed, 489 insertions(+), 8 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs index bc7bda8e50..d458f07ba6 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs @@ -54,14 +54,23 @@ internal sealed partial class TerminalTestReporter : IDisposable private bool? _shouldShowPassedTests; -#if NET7_0_OR_GREATER - [GeneratedRegex(@$"^ at ((?.+) in (?.+):line (?\d+)|(?.+))$", RegexOptions.ExplicitCapture, 1000)] - private static partial Regex GetFrameRegex(); -#else private static Regex? s_regex; +#if NET7_0_OR_GREATER + + [GeneratedRegex(@"^ at (?.+\))( in (?.+):line (?\d+))?$", RegexOptions.ExplicitCapture, 1000)] + internal static partial Regex GetStandardFrameRegex(); + + [GeneratedRegex(@"^ at (?.+\))", RegexOptions.ExplicitCapture, 1000)] + internal static partial Regex GetAOTFrameRegex(); + + internal static Regex GetFrameRegex() => s_regex ??= + System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported + ? GetStandardFrameRegex() + : GetAOTFrameRegex(); +#else [MemberNotNull(nameof(s_regex))] - private static Regex GetFrameRegex() + internal static Regex GetFrameRegex() { if (s_regex != null) { @@ -79,7 +88,9 @@ private static Regex GetFrameRegex() { // Get these resources: https://github.com/dotnet/runtime/blob/main/src/libraries/System.Private.CoreLib/src/Resources/Strings.resx #pragma warning disable RS0030 // Do not use banned APIs - MethodInfo? getResourceStringMethod = typeof(Environment).GetMethod("GetResourceString", BindingFlags.Static | BindingFlags.NonPublic, null, [typeof(string)], null); + MethodInfo? getResourceStringMethod = typeof(Environment).GetMethod( + "GetResourceString", + BindingFlags.Static | BindingFlags.NonPublic, null, [typeof(string)], null); #pragma warning restore RS0030 // Do not use banned APIs if (getResourceStringMethod is not null) { @@ -100,7 +111,7 @@ private static Regex GetFrameRegex() string inPattern = string.Format(CultureInfo.InvariantCulture, inString, "(?.+)", @"(?\d+)"); - s_regex = new Regex(@$"^ {atString} ((?.+) {inPattern}|(?.+))$", RegexOptions.Compiled | RegexOptions.ExplicitCapture, matchTimeout: TimeSpan.FromSeconds(1)); + s_regex = new Regex($@"^ {atString} (?.+\))( {inPattern})?$", RegexOptions.Compiled | RegexOptions.ExplicitCapture, matchTimeout: TimeSpan.FromSeconds(1)); return s_regex; } #endif @@ -676,13 +687,14 @@ private static void AppendAssemblyLinkTargetFrameworkAndArchitecture(ITerminal t bool weHaveFilePathAndCodeLine = !RoslynString.IsNullOrWhiteSpace(match.Groups["code"].Value); terminal.Append(PlatformResources.StackFrameAt); terminal.Append(' '); + if (weHaveFilePathAndCodeLine) { terminal.Append(match.Groups["code"].Value); } else { - terminal.Append(match.Groups["code1"].Value); + terminal.Append(match.Groups["line"].Value); } if (weHaveFilePathAndCodeLine) diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs index 58ad5b0aad..7d64c39c06 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs @@ -3,6 +3,7 @@ using System.Runtime.InteropServices; using System.Text; +using System.Text.RegularExpressions; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.OutputDevice.Terminal; @@ -42,6 +43,474 @@ public void AppendStackFrameFormatsStackTraceLineCorrectly() Assert.That(!terminal.Output.ToString().Contains(" :0")); } + public void StackTraceRegexCapturesLines() + { + string[] stackTraceLines = """ + at System.Text.RegularExpressions.RegexRunner.g__ThrowRegexTimeout|25_0() + at System.Text.RegularExpressions.Generated.F06D33C3F8C8C3FD257C1A1967E3A3BAC4BE9C8EC41CC9366C764C2205C68F0CE__GetFrameRegex_1.RunnerFactory.Runner.TryMatchAtCurrentPosition(ReadOnlySpan`1) in /_/artifacts/obj/Microsoft.Testing.Platform/Release/net8.0/System.Text.RegularExpressions.Generator/System.Text.RegularExpressions.Generator.RegexGenerator/RegexGenerator.g.cs:line 639 + at System.Text.RegularExpressions.Generated.F06D33C3F8C8C3FD257C1A1967E3A3BAC4BE9C8EC41CC9366C764C2205C68F0CE__GetFrameRegex_1.RunnerFactory.Runner.Scan(ReadOnlySpan`1) in /_/artifacts/obj/Microsoft.Testing.Platform/Release/net8.0/System.Text.RegularExpressions.Generator/System.Text.RegularExpressions.Generator.RegexGenerator/RegexGenerator.g.cs:line 537 + at System.Text.RegularExpressions.Regex.ScanInternal(RegexRunnerMode, Boolean, String, Int32, RegexRunner, ReadOnlySpan`1, Boolean) + at System.Text.RegularExpressions.Regex.RunSingleMatch(RegexRunnerMode, Int32, String, Int32, Int32, Int32) + at System.Text.RegularExpressions.Regex.Match(String) + at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.AppendStackFrame(ITerminal, String) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 650 + at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.FormatStackTrace(ITerminal, FlatException[], Int32) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 601 + at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.RenderTestCompleted(ITerminal , String , String, String, String , TestOutcome, TimeSpan, FlatException[] , String, String, String, String) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 517 + at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.<>c__DisplayClass27_0.b__0(ITerminal terminal) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 439 + at Microsoft.Testing.Platform.OutputDevice.Terminal.TestProgressStateAwareTerminal.WriteToTerminal(Action`1) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs:line 129 + at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.TestCompleted(String , String, String, String, String , TestOutcome, TimeSpan, FlatException[] , String, String, String, String) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 439 + at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.TestCompleted(String , String, String, String, String , TestOutcome, TimeSpan, String, Exception, String, String, String, String) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 386 + at Microsoft.Testing.Platform.OutputDevice.TerminalOutputDevice.ConsumeAsync(IDataProducer, IData, CancellationToken) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs:line 458 + at Microsoft.Testing.Platform.Messages.AsyncConsumerDataProcessor.ConsumeAsync() in /_/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs:line 74 + at Microsoft.Testing.Platform.Messages.AsyncConsumerDataProcessor.DrainDataAsync() in /_/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs:line 146 + at Microsoft.Testing.Platform.Messages.AsynchronousMessageBus.DrainDataAsync() in /_/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs:line 177 + at Microsoft.Testing.Platform.Messages.MessageBusProxy.DrainDataAsync() in /_/src/Platform/Microsoft.Testing.Platform/Messages/MessageBusProxy.cs:line 39 + at Microsoft.Testing.Platform.Hosts.CommonTestHost.NotifyTestSessionEndAsync(SessionUid, BaseMessageBus, ServiceProvider, CancellationToken) in /_/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs:line 192 + at Microsoft.Testing.Platform.Hosts.CommonTestHost.ExecuteRequestAsync(IPlatformOutputDevice, ITestSessionContext, ServiceProvider, BaseMessageBus, ITestFramework, ClientInfo) in /_/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs:line 133 + at Microsoft.Testing.Platform.Hosts.ConsoleTestHost.InternalRunAsync() in /_/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs:line 85 + at Microsoft.Testing.Platform.Hosts.ConsoleTestHost.InternalRunAsync() in /_/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs:line 117 + at Microsoft.Testing.Platform.Hosts.CommonTestHost.RunTestAppAsync(CancellationToken) in /_/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs:line 106 + at Microsoft.Testing.Platform.Hosts.CommonTestHost.RunAsync() in /_/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs:line 34 + at Microsoft.Testing.Platform.Hosts.CommonTestHost.RunAsync() in /_/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs:line 72 + at Microsoft.Testing.Platform.Builder.TestApplication.RunAsync() in /_/src/Platform/Microsoft.Testing.Platform/Builder/TestApplication.cs:line 244 + at TestingPlatformEntryPoint.Main(String[]) in /_/TUnit.TestProject/obj/Release/net8.0/osx-x64/TestPlatformEntryPoint.cs:line 16 + at TestingPlatformEntryPoint.
(String[]) + """.Split([Environment.NewLine], StringSplitOptions.RemoveEmptyEntries); + + Regex regex = TerminalTestReporter.GetFrameRegex(); + foreach (string stackTraceLine in stackTraceLines) + { + Match match = regex.Match(stackTraceLine); + Assert.IsTrue(match.Success); + Assert.IsTrue(match.Groups["code"].Success); + + bool hasFileAndLine = char.IsDigit(stackTraceLine.Last()); + Assert.That(match.Groups["file"].Success == hasFileAndLine); + Assert.That(match.Groups["line"].Success == hasFileAndLine); + } + } + +#if NET7_0_OR_GREATER + public void AOTStackTraceRegexCapturesLines() + { + string[] stackTraceLines = """ + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x42f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__1.MoveNext() + 0xad + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x42f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d + --- End of stack trace from previous location --- + at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 + at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 + at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b + at BenchmarkTest.ExceptionThrower.d__1.MoveNext() + 0xad + """.Split([Environment.NewLine], StringSplitOptions.RemoveEmptyEntries); + + Regex regex = TerminalTestReporter.GetAOTFrameRegex(); + foreach (string stackTraceLine in stackTraceLines.Where(line => + !line.StartsWith("--- ", StringComparison.Ordinal))) + { + Match match = regex.Match(stackTraceLine); + Assert.IsTrue(match.Success); + Assert.IsTrue(match.Groups["code"].Success); + + Assert.IsFalse(match.Groups["file"].Success); + Assert.IsFalse(match.Groups["line"].Success); + } + } +#endif + public void OutputFormattingIsCorrect() { var stringBuilderConsole = new StringBuilderConsole(); From dfdfcdfe0de7b8a80ac05f4878fcab804fd2a0e5 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 13:59:17 +0000 Subject: [PATCH 028/273] [main] Update dependencies from dotnet/arcade (#4190) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 2 +- global.json | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f867260244..9a3f711dcd 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,17 +1,17 @@ - + https://github.com/dotnet/arcade - 9ad0880a9f8450f4ac4e097cfe830e401ea3e22c + d0f89c635d780e183a97ad86af4f3c8d7e95977f - + https://github.com/dotnet/arcade - 9ad0880a9f8450f4ac4e097cfe830e401ea3e22c + d0f89c635d780e183a97ad86af4f3c8d7e95977f - + https://github.com/dotnet/arcade - 9ad0880a9f8450f4ac4e097cfe830e401ea3e22c + d0f89c635d780e183a97ad86af4f3c8d7e95977f https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage diff --git a/eng/Versions.props b/eng/Versions.props index 38501decc2..5b6258d206 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,7 +7,7 @@ preview - 10.0.0-beta.24576.1 + 10.0.0-beta.24577.1 17.13.0-preview.24572.7 1.5.0-preview.24576.1 diff --git a/global.json b/global.json index b72e6c86d4..ed958749c4 100644 --- a/global.json +++ b/global.json @@ -26,7 +26,7 @@ "rollForward": "latestFeature" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.24576.1", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.24577.1", "MSBuild.Sdk.Extras": "3.0.44" } } From defac5341593c4dcfe67861717dcc310067029f7 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 28 Nov 2024 06:20:10 -0800 Subject: [PATCH 029/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2591402 --- .../Resources/xlf/MSBuildResources.cs.xlf | 6 +++--- .../Resources/xlf/MSBuildResources.es.xlf | 6 +++--- .../Resources/xlf/MSBuildResources.fr.xlf | 6 +++--- .../Resources/xlf/MSBuildResources.it.xlf | 6 +++--- .../Resources/xlf/MSBuildResources.ja.xlf | 6 +++--- .../Resources/xlf/PlatformResources.cs.xlf | 6 +++--- .../Resources/xlf/PlatformResources.fr.xlf | 6 +++--- .../Resources/xlf/PlatformResources.it.xlf | 6 +++--- .../Resources/xlf/PlatformResources.ja.xlf | 6 +++--- .../Resources/xlf/PlatformResources.pt-BR.xlf | 6 +++--- .../Resources/xlf/PlatformResources.ru.xlf | 6 +++--- .../Resources/xlf/PlatformResources.tr.xlf | 6 +++--- .../Resources/xlf/PlatformResources.zh-Hans.xlf | 6 +++--- 13 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.cs.xlf index 72322ab120..4d5d498aab 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.cs.xlf @@ -34,11 +34,11 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + Nepovedlo se najít hostitele {0} pro architekturu{1}. -You can resolve the problem by installing the '{1}' .NET. +Tento problém můžete vyřešit instalací rozhraní .NET {1}. -The specified framework can be found at: +Zadanou architekturu najdete na adrese: - https://aka.ms/dotnet-download diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.es.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.es.xlf index 0a79556d63..b441e35b36 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.es.xlf @@ -34,11 +34,11 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + No se encontró el host "{0}" para la arquitectura "{1}". -You can resolve the problem by installing the '{1}' .NET. +Para resolver el problema, instale "{1}" .NET. -The specified framework can be found at: +El marco de trabajo especificado se puede encontrar en: - https://aka.ms/dotnet-download diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.fr.xlf index 2cf75dd865..4b952b1e7e 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.fr.xlf @@ -34,11 +34,11 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + Nous n'avons pas trouvé l’hôte '{0}' de l’architecture '{1}'. -You can resolve the problem by installing the '{1}' .NET. +Vous pouvez résoudre le problème en installant '{1}' .NET. -The specified framework can be found at: +L’infrastructure spécifiée se trouve à l’adresse suivante : - https://aka.ms/dotnet-download diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.it.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.it.xlf index 84acb581b1..2844eabf0c 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.it.xlf @@ -34,11 +34,11 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + Non è stato possibile trovare l'host '{0}' per l'architettura '{1}'. -You can resolve the problem by installing the '{1}' .NET. +È possibile risolvere il problema installando '{1}' .NET. -The specified framework can be found at: +Il framework specificato è disponibile all'indirizzo: - https://aka.ms/dotnet-download diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ja.xlf index 2446ab0a45..ebbd3e6934 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ja.xlf @@ -34,11 +34,11 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + '{1}' アーキテクチャの '{0}' ホストが見つかりませんでした。 -You can resolve the problem by installing the '{1}' .NET. +'{1}' .NET をインストールしてこの問題を解決することができます。 -The specified framework can be found at: +指定されたフレームワークは次の場所にあります: - https://aka.ms/dotnet-download diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index 7cf0a5fd4e..46d43b0409 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + Nebyl nalezen konfigurační soubor {0} zadaný pomocí parametru --config-file. @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + Určuje soubor testconfig.json. @@ -522,7 +522,7 @@ Dostupné hodnoty jsou Trace, Debug, Information, Warning, Error a Critical. Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + Určuje minimální počet testů, jejichž spuštění se očekává. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index eafa1d1900..1c5257eec3 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + Nous n’avons pas pu trouver le fichier de configuration « {0} » spécifié avec « --config-file ». @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + Spécifie un fichier testconfig.json. @@ -522,7 +522,7 @@ Les valeurs disponibles sont « Trace », « Debug », « Information », Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + Spécifie le nombre minimal de tests censés s’exécuter. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index 10fec28c72..ae174f67af 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + Impossibile trovare il file di configurazione '{0}' specificato con '--config-file'. @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + Specifica un file testconfig.json. @@ -522,7 +522,7 @@ I valori disponibili sono 'Trace', 'Debug', 'Information', 'Warning', 'Error' e Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + Specifica il numero minimo dei test che si prevede saranno eseguiti. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index 081184d1f8..2909707e34 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + '--config-file' で指定された構成ファイル '{0}' が見つかりませんでした。 @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + testconfig.json ファイルを指定します。 @@ -523,7 +523,7 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + 実行する必要があるテストの最小数を指定します。 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index 9e11d5bfe7..94a569cec7 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + Não foi possível encontrar o arquivo de configuração '{0}' especificado com '--config-file'. @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + Especifica um arquivo testconfig.json. @@ -522,7 +522,7 @@ Os valores disponíveis são 'Rastreamento', 'Depuração', 'Informação', 'Avi Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + Especifica o número mínimo de testes que devem ser executados. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index b9ccbc8183..09a6adb712 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + Не удалось найти файл конфигурации "{0}", указанный с параметром "--config-file". @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + Указывает файл testconfig.json. @@ -522,7 +522,7 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + Указывает минимальное число тестов, которые должны быть запущены. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 89430bf8ae..780626d190 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + '--config-file' ile belirtilen '{0}' yapılandırma dosyası bulunamadı. @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + testconfig.json dosyası belirtir. @@ -522,7 +522,7 @@ Kullanılabilir değerler: 'Trace', 'Debug', 'Information', 'Warning', 'Error' v Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + Çalıştırılması beklenen en düşük test sayısını belirtir. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 983303309c..2c01d09a7f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + 找不到使用 ‘--config-file’ 指定的配置文件“{0}”。 @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + 指定 testconfig.json 文件。 @@ -522,7 +522,7 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + 指定预期运行的最小测试数。 From c2910eaf2cc2c47377ddc2e652d40cdfaac9fe77 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 28 Nov 2024 06:20:44 -0800 Subject: [PATCH 030/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2591402 --- .../Resources/xlf/MSBuildResources.pt-BR.xlf | 8 ++++---- .../Resources/xlf/MSBuildResources.ru.xlf | 8 ++++---- .../Resources/xlf/MSBuildResources.tr.xlf | 6 +++--- .../Resources/xlf/MSBuildResources.zh-Hans.xlf | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pt-BR.xlf index 1e7c962212..7d18cd1dd3 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pt-BR.xlf @@ -34,12 +34,12 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + Não foi possível localizar o host '{0}' para a arquitetura '{1}'. -You can resolve the problem by installing the '{1}' .NET. +Você pode resolver o problema instalando o .NET '{1}'. -The specified framework can be found at: - - https://aka.ms/dotnet-download +A estrutura especificada pode ser encontrada em: + – https://aka.ms/dotnet-download diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ru.xlf index 6d90b2fc2a..8297566eff 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ru.xlf @@ -34,12 +34,12 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + Не удалось найти хост "{0}" для архитектуры "{1}". -You can resolve the problem by installing the '{1}' .NET. +Чтобы устранить проблему, установите ''{1}'' .NET. -The specified framework can be found at: - - https://aka.ms/dotnet-download +Указанную платформу можно найти по адресу: + — https://aka.ms/dotnet-download diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.tr.xlf index 35f1a622a3..b4934b11c0 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.tr.xlf @@ -34,11 +34,11 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + '{1}' mimarisi için '{0}' ana bilgisayarı bulunamadı. -You can resolve the problem by installing the '{1}' .NET. +'{1}' .NET’i yükleyerek sorunu çözebilirsiniz. -The specified framework can be found at: +Belirtilen çerçeve şu konumda bulunabilir: - https://aka.ms/dotnet-download diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hans.xlf index 8d38e43bea..86df598ffe 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hans.xlf @@ -34,11 +34,11 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + 找不到“{1}”体系结构的“{0}”主机。 -You can resolve the problem by installing the '{1}' .NET. +可以通过安装 “{1}” .NET 来解决此问题。 -The specified framework can be found at: +可在以下位置找到指定的框架: - https://aka.ms/dotnet-download From 7cf16163c453a58c97257d5f2ff8e1c080686662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Thu, 28 Nov 2024 17:12:10 +0100 Subject: [PATCH 031/273] Remove timeout from regex and improve test (#4189) --- .../Terminal/TerminalTestReporter.cs | 27 +- .../Terminal/TerminalTestReporterTests.cs | 486 +----------------- 2 files changed, 33 insertions(+), 480 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs index d458f07ba6..9016f23a74 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs @@ -54,23 +54,16 @@ internal sealed partial class TerminalTestReporter : IDisposable private bool? _shouldShowPassedTests; - private static Regex? s_regex; - #if NET7_0_OR_GREATER - - [GeneratedRegex(@"^ at (?.+\))( in (?.+):line (?\d+))?$", RegexOptions.ExplicitCapture, 1000)] - internal static partial Regex GetStandardFrameRegex(); - - [GeneratedRegex(@"^ at (?.+\))", RegexOptions.ExplicitCapture, 1000)] - internal static partial Regex GetAOTFrameRegex(); - - internal static Regex GetFrameRegex() => s_regex ??= - System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported - ? GetStandardFrameRegex() - : GetAOTFrameRegex(); + // Specifying no timeout, the regex is linear. And the timeout does not measure the regex only, but measures also any + // thread suspends, so the regex gets blamed incorrectly. + [GeneratedRegex(@$"^ at ((?.+) in (?.+):line (?\d+)|(?.+))$", RegexOptions.ExplicitCapture)] + private static partial Regex GetFrameRegex(); #else + private static Regex? s_regex; + [MemberNotNull(nameof(s_regex))] - internal static Regex GetFrameRegex() + private static Regex GetFrameRegex() { if (s_regex != null) { @@ -111,7 +104,9 @@ internal static Regex GetFrameRegex() string inPattern = string.Format(CultureInfo.InvariantCulture, inString, "(?.+)", @"(?\d+)"); - s_regex = new Regex($@"^ {atString} (?.+\))( {inPattern})?$", RegexOptions.Compiled | RegexOptions.ExplicitCapture, matchTimeout: TimeSpan.FromSeconds(1)); + // Specifying no timeout, the regex is linear. And the timeout does not measure the regex only, but measures also any + // thread suspends, so the regex gets blamed incorrectly. + s_regex = new Regex(@$"^ {atString} ((?.+) {inPattern}|(?.+))$", RegexOptions.Compiled | RegexOptions.ExplicitCapture); return s_regex; } #endif @@ -694,7 +689,7 @@ private static void AppendAssemblyLinkTargetFrameworkAndArchitecture(ITerminal t } else { - terminal.Append(match.Groups["line"].Value); + terminal.Append(match.Groups["code1"].Value); } if (weHaveFilePathAndCodeLine) diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs index 7d64c39c06..d47fe26699 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs @@ -3,7 +3,6 @@ using System.Runtime.InteropServices; using System.Text; -using System.Text.RegularExpressions; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.OutputDevice.Terminal; @@ -43,473 +42,32 @@ public void AppendStackFrameFormatsStackTraceLineCorrectly() Assert.That(!terminal.Output.ToString().Contains(" :0")); } - public void StackTraceRegexCapturesLines() + // Code with line when we have symbols + [Arguments( + " at TestingPlatformEntryPoint.Main(String[]) in /_/TUnit.TestProject/obj/Release/net8.0/osx-x64/TestPlatformEntryPoint.cs:line 16", + $" at TestingPlatformEntryPoint.Main(String[]) in /_/TUnit.TestProject/obj/Release/net8.0/osx-x64/TestPlatformEntryPoint.cs:16")] + // code without line when we don't have symbols + [Arguments( + " at TestingPlatformEntryPoint.
(String[])", + " at TestingPlatformEntryPoint.
(String[])")] + // stack trace when published as NativeAOT + [Arguments( + " at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d", + " at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d")] + // spanners that we want to keep, to not lose information + [Arguments( + "--- End of stack trace from previous location ---", + " --- End of stack trace from previous location ---")] + public void StackTraceRegexCapturesLines(string stackTraceLine, string expected) { - string[] stackTraceLines = """ - at System.Text.RegularExpressions.RegexRunner.g__ThrowRegexTimeout|25_0() - at System.Text.RegularExpressions.Generated.F06D33C3F8C8C3FD257C1A1967E3A3BAC4BE9C8EC41CC9366C764C2205C68F0CE__GetFrameRegex_1.RunnerFactory.Runner.TryMatchAtCurrentPosition(ReadOnlySpan`1) in /_/artifacts/obj/Microsoft.Testing.Platform/Release/net8.0/System.Text.RegularExpressions.Generator/System.Text.RegularExpressions.Generator.RegexGenerator/RegexGenerator.g.cs:line 639 - at System.Text.RegularExpressions.Generated.F06D33C3F8C8C3FD257C1A1967E3A3BAC4BE9C8EC41CC9366C764C2205C68F0CE__GetFrameRegex_1.RunnerFactory.Runner.Scan(ReadOnlySpan`1) in /_/artifacts/obj/Microsoft.Testing.Platform/Release/net8.0/System.Text.RegularExpressions.Generator/System.Text.RegularExpressions.Generator.RegexGenerator/RegexGenerator.g.cs:line 537 - at System.Text.RegularExpressions.Regex.ScanInternal(RegexRunnerMode, Boolean, String, Int32, RegexRunner, ReadOnlySpan`1, Boolean) - at System.Text.RegularExpressions.Regex.RunSingleMatch(RegexRunnerMode, Int32, String, Int32, Int32, Int32) - at System.Text.RegularExpressions.Regex.Match(String) - at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.AppendStackFrame(ITerminal, String) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 650 - at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.FormatStackTrace(ITerminal, FlatException[], Int32) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 601 - at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.RenderTestCompleted(ITerminal , String , String, String, String , TestOutcome, TimeSpan, FlatException[] , String, String, String, String) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 517 - at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.<>c__DisplayClass27_0.b__0(ITerminal terminal) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 439 - at Microsoft.Testing.Platform.OutputDevice.Terminal.TestProgressStateAwareTerminal.WriteToTerminal(Action`1) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs:line 129 - at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.TestCompleted(String , String, String, String, String , TestOutcome, TimeSpan, FlatException[] , String, String, String, String) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 439 - at Microsoft.Testing.Platform.OutputDevice.Terminal.TerminalTestReporter.TestCompleted(String , String, String, String, String , TestOutcome, TimeSpan, String, Exception, String, String, String, String) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs:line 386 - at Microsoft.Testing.Platform.OutputDevice.TerminalOutputDevice.ConsumeAsync(IDataProducer, IData, CancellationToken) in /_/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs:line 458 - at Microsoft.Testing.Platform.Messages.AsyncConsumerDataProcessor.ConsumeAsync() in /_/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs:line 74 - at Microsoft.Testing.Platform.Messages.AsyncConsumerDataProcessor.DrainDataAsync() in /_/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs:line 146 - at Microsoft.Testing.Platform.Messages.AsynchronousMessageBus.DrainDataAsync() in /_/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs:line 177 - at Microsoft.Testing.Platform.Messages.MessageBusProxy.DrainDataAsync() in /_/src/Platform/Microsoft.Testing.Platform/Messages/MessageBusProxy.cs:line 39 - at Microsoft.Testing.Platform.Hosts.CommonTestHost.NotifyTestSessionEndAsync(SessionUid, BaseMessageBus, ServiceProvider, CancellationToken) in /_/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs:line 192 - at Microsoft.Testing.Platform.Hosts.CommonTestHost.ExecuteRequestAsync(IPlatformOutputDevice, ITestSessionContext, ServiceProvider, BaseMessageBus, ITestFramework, ClientInfo) in /_/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs:line 133 - at Microsoft.Testing.Platform.Hosts.ConsoleTestHost.InternalRunAsync() in /_/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs:line 85 - at Microsoft.Testing.Platform.Hosts.ConsoleTestHost.InternalRunAsync() in /_/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs:line 117 - at Microsoft.Testing.Platform.Hosts.CommonTestHost.RunTestAppAsync(CancellationToken) in /_/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs:line 106 - at Microsoft.Testing.Platform.Hosts.CommonTestHost.RunAsync() in /_/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs:line 34 - at Microsoft.Testing.Platform.Hosts.CommonTestHost.RunAsync() in /_/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs:line 72 - at Microsoft.Testing.Platform.Builder.TestApplication.RunAsync() in /_/src/Platform/Microsoft.Testing.Platform/Builder/TestApplication.cs:line 244 - at TestingPlatformEntryPoint.Main(String[]) in /_/TUnit.TestProject/obj/Release/net8.0/osx-x64/TestPlatformEntryPoint.cs:line 16 - at TestingPlatformEntryPoint.
(String[]) - """.Split([Environment.NewLine], StringSplitOptions.RemoveEmptyEntries); - - Regex regex = TerminalTestReporter.GetFrameRegex(); - foreach (string stackTraceLine in stackTraceLines) - { - Match match = regex.Match(stackTraceLine); - Assert.IsTrue(match.Success); - Assert.IsTrue(match.Groups["code"].Success); + var terminal = new StringBuilderTerminal(); + TerminalTestReporter.AppendStackFrame(terminal, stackTraceLine); - bool hasFileAndLine = char.IsDigit(stackTraceLine.Last()); - Assert.That(match.Groups["file"].Success == hasFileAndLine); - Assert.That(match.Groups["line"].Success == hasFileAndLine); - } - } + // We add newline after every, but it is hard to put it in the attribute. + expected += Environment.NewLine; -#if NET7_0_OR_GREATER - public void AOTStackTraceRegexCapturesLines() - { - string[] stackTraceLines = """ - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x42f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__1.MoveNext() + 0xad - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x42f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__5.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x341 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__3.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x215 - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x17f - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__4.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__7.MoveNext() + 0x2ab - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d - --- End of stack trace from previous location --- - at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() + 0x20 - at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task) + 0xb2 - at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task, ConfigureAwaitOptions) + 0x4b - at BenchmarkTest.ExceptionThrower.d__1.MoveNext() + 0xad - """.Split([Environment.NewLine], StringSplitOptions.RemoveEmptyEntries); - - Regex regex = TerminalTestReporter.GetAOTFrameRegex(); - foreach (string stackTraceLine in stackTraceLines.Where(line => - !line.StartsWith("--- ", StringComparison.Ordinal))) - { - Match match = regex.Match(stackTraceLine); - Assert.IsTrue(match.Success); - Assert.IsTrue(match.Groups["code"].Success); - - Assert.IsFalse(match.Groups["file"].Success); - Assert.IsFalse(match.Groups["line"].Success); - } + Assert.AreEqual(expected, terminal.Output); } -#endif public void OutputFormattingIsCorrect() { From d5876b6da187fc23219e426a0bc02ea59b36c2f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 28 Nov 2024 17:30:39 +0100 Subject: [PATCH 032/273] [test] bump dotnet publish timeout to 90s (#4193) --- .../MSTest.Acceptance.IntegrationTests/NativeAotTests.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs index 21af4e042c..59dcb83da2 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs @@ -120,6 +120,7 @@ await DotnetCli.RunAsync( DotnetMuxerResult compilationResult = await DotnetCli.RunAsync( $"publish -m:1 -nodeReuse:false {generator.TargetAssetPath} -r {RID}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + timeoutInSeconds: 90, retryCount: 0); compilationResult.AssertOutputContains("Generating native code"); From a99c3c5b8c2562a661e5a5714a190d7139721923 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 28 Nov 2024 18:29:09 +0100 Subject: [PATCH 033/273] Fix merging of coverage using MS CC (#4194) --- .config/dotnet-tools.json | 13 +++++++++++++ Directory.Packages.props | 1 - eng/CodeCoverage.proj | 33 ++++++++++++++++++++++----------- 3 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 .config/dotnet-tools.json diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 0000000000..452b57a8d4 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,13 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "dotnet-coverage": { + "version": "17.12.6", + "commands": [ + "dotnet-coverage" + ], + "rollForward": false + } + } +} \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props index a43b584c91..df8a5e0bb0 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -75,7 +75,6 @@ - diff --git a/eng/CodeCoverage.proj b/eng/CodeCoverage.proj index 76ae926fba..72cc55e30c 100644 --- a/eng/CodeCoverage.proj +++ b/eng/CodeCoverage.proj @@ -8,45 +8,56 @@ - <_CodecovPath>$(PkgCodecov)\tools\Codecov.exe - <_ReportGeneratorPath>$(PkgReportGenerator)\tools\net47\ReportGenerator.exe + <_LocalDotNetPath>$(DotNetRoot)\dotnet.exe + $(ArtifactsCoverageDir)full\ + $(ArtifactsCoverageDir)unit\ + $(ArtifactsCoverageDir)integration\ + Cobertura.xml <_CoverageReports Include="$(ArtifactsTestResultsDir)\*.coverage" /> + <_CoverageReports Include="@(_CoverageReports->'"%(Identity)"', ' ')" /> <_UnitCoverageReports Include="@(_CoverageReports)" Condition="$([System.String]::Copy('%(Identity)').Contains('.UnitTests_'))" /> + <_UnitCoverageReports Include="@(_UnitCoverageReports->'"%(Identity)"', ' ')" /> <_IntegrationCoverageReports Include="@(_CoverageReports)" Condition="$([System.String]::Copy('%(Identity)').Contains('.IntegrationTests_'))" /> + <_IntegrationCoverageReports Include="@(_IntegrationCoverageReports->'"%(Identity)"', ' ')" /> + + + + + - - + + - - + + - - + + - <_CodecovFullArgs Include="-f;$(ArtifactsCoverageDir)full\Cobertura.xml" /> - <_CodecovUnitArgs Include="-f;$(ArtifactsCoverageDir)unit\Cobertura.xml" /> - <_CodecovIntegrationArgs Include="-f;$(ArtifactsCoverageDir)integration\Cobertura.xml" /> + <_CodecovFullArgs Include="-f;$(MergedFullCoverageDirectory)$(CoberturaFileName)" /> + <_CodecovUnitArgs Include="-f;$(MergedUnitCoverageDirectory)$(CoberturaFileName)" /> + <_CodecovIntegrationArgs Include="-f;$(MergedIntegrationCoverageDirectory)$(CoberturaFileName)" /> <_CodecovArgs Include="--required" /> From 48610a2991bb58cc1b132f20fed03101252cc3b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Fri, 29 Nov 2024 07:00:00 +0100 Subject: [PATCH 034/273] Revert "Show the text that timed out in regex match" (#4195) --- .../Terminal/TerminalTestReporter.cs | 25 +------------------ .../Resources/PlatformResources.resx | 6 +---- .../Resources/xlf/PlatformResources.cs.xlf | 5 ---- .../Resources/xlf/PlatformResources.de.xlf | 5 ---- .../Resources/xlf/PlatformResources.es.xlf | 5 ---- .../Resources/xlf/PlatformResources.fr.xlf | 5 ---- .../Resources/xlf/PlatformResources.it.xlf | 5 ---- .../Resources/xlf/PlatformResources.ja.xlf | 5 ---- .../Resources/xlf/PlatformResources.ko.xlf | 5 ---- .../Resources/xlf/PlatformResources.pl.xlf | 5 ---- .../Resources/xlf/PlatformResources.pt-BR.xlf | 5 ---- .../Resources/xlf/PlatformResources.ru.xlf | 5 ---- .../Resources/xlf/PlatformResources.tr.xlf | 5 ---- .../xlf/PlatformResources.zh-Hans.xlf | 5 ---- .../xlf/PlatformResources.zh-Hant.xlf | 5 ---- 15 files changed, 2 insertions(+), 94 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs index 9016f23a74..6c4134f0ea 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs @@ -4,13 +4,9 @@ #if !NET7_0_OR_GREATER using System.Diagnostics.CodeAnalysis; using System.Reflection; - #endif using System.Globalization; -#if !NETSTANDARD -using System.Runtime.ExceptionServices; -#endif using System.Text.RegularExpressions; using Microsoft.Testing.Platform.Helpers; @@ -657,26 +653,7 @@ private static void AppendAssemblyLinkTargetFrameworkAndArchitecture(ITerminal t internal /* for testing */ static void AppendStackFrame(ITerminal terminal, string stackTraceLine) { terminal.Append(DoubleIndentation); - Match match; - try - { - match = GetFrameRegex().Match(stackTraceLine); - } - catch (RegexMatchTimeoutException ex) - { - // Add the stack trace line that was being matched to test locally. - var newTimeoutException = new RegexMatchTimeoutException(string.Format(CultureInfo.CurrentCulture, PlatformResources.TimeoutInRegexStackTraceLineParsing, stackTraceLine), ex); -#if !NETSTANDARD - throw ex.StackTrace is null - ? newTimeoutException - // Otherwise preserve the stack trace, so we can tell if this was using - // the generated regex or not. - : ExceptionDispatchInfo.SetRemoteStackTrace(newTimeoutException, ex.StackTrace); -#else - throw newTimeoutException; -#endif - } - + Match match = GetFrameRegex().Match(stackTraceLine); if (match.Success) { bool weHaveFilePathAndCodeLine = !RoslynString.IsNullOrWhiteSpace(match.Groups["code"].Value); diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx index 36568d505e..5bd7f79c1a 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx +++ b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx @@ -671,8 +671,4 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is The configuration file '{0}' specified with '--config-file' could not be found. - - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - - \ No newline at end of file + diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index 46d43b0409..fcbdab68b9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -825,11 +825,6 @@ Platné hodnoty jsou Normal a Detailed. Výchozí hodnota je Normal. Nepovedlo se vyprázdnit protokoly před vypršením časového limitu {0} s. - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total Celkem diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index 0376d01bed..154d7a643b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -825,11 +825,6 @@ Gültige Werte sind „Normal“, „Detailed“. Der Standardwert ist „Normal Fehler beim Leeren von Protokollen vor dem Timeout von "{0}" Sekunden - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total Gesamt diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index 5715077b33..ffc6cc0328 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -825,11 +825,6 @@ Los valores válidos son 'Normal', 'Detallado'. El valor predeterminado es 'Norm No se pudieron vaciar los registros antes del tiempo de espera de “{0}” segundos - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total Total diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index 1c5257eec3..cd2f8e18d6 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -825,11 +825,6 @@ Les valeurs valides sont « Normal » et « Détaillé ». La valeur par dé Échec du vidage des journaux avant le délai d’expiration de « {0} » secondes - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total Total diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index ae174f67af..9f2e5fd171 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -825,11 +825,6 @@ I valori validi sono 'Normal', 'Detailed'. L'impostazione predefinita è 'Normal Non è stato possibile scaricare i log prima del timeout di '{0}' secondi - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total Totale diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index 2909707e34..d506fc0e50 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -826,11 +826,6 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. '{0}' 秒のタイムアウト前にログをフラッシュできませんでした - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total 合計 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index bdebab13af..9c15b13c2d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -825,11 +825,6 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. '{0}'초의 시간 제한 전에 로그를 플러시하지 못했습니다. - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total 합계 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index 533e43c562..b8e6cb922e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -825,11 +825,6 @@ Prawidłowe wartości to „Normalne”, „Szczegółowe”. Wartość domyśln Nie można opróżnić dzienników przed upływem limitu czasu wynoszącego „{0}” s - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total Łącznie diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index 94a569cec7..1f4c3e9aeb 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -825,11 +825,6 @@ Os valores válidos são “Normal”, “Detalhado”. O padrão é “Normal Falha ao liberar logs antes do tempo limite de '{0}' segundos - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total Total diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index 09a6adb712..48d7556f60 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -825,11 +825,6 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. Не удалось записать журналы на диск до истечения времени ожидания ("{0}" с) - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total Всего diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 780626d190..6c74b00cf7 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -825,11 +825,6 @@ Geçerli değerler: ‘Normal’, ‘Ayrıntılı’. Varsayılan değer: ‘Nor '{0}' saniyelik zaman aşımından önce günlükler boşaltılamadı - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total Toplam diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 2c01d09a7f..35c5ef5311 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -825,11 +825,6 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. 未能在“{0}”秒超时之前刷新日志 - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total 总计 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index 92158a8068..b9b18bdbaa 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -825,11 +825,6 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. 無法在 '{0}' 秒逾時前排清記錄 - - Parsing stack trace line with regex timed out. Input: '{0}' - Parsing stack trace line with regex timed out. Input: '{0}' - {0} is the line that was being matched - Total 總計 From 5f655beea41f4885161ab9f979378845c02bc78e Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Fri, 29 Nov 2024 14:37:17 +0000 Subject: [PATCH 035/273] [main] Update dependencies from devdiv/DevDiv/vs-code-coverage, dotnet/arcade (#4197) Co-authored-by: dotnet-maestro[bot] --- .config/dotnet-tools.json | 2 +- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- eng/common/native/install-dependencies.sh | 6 +----- global.json | 2 +- 5 files changed, 13 insertions(+), 17 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 452b57a8d4..4292ac645e 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,4 +10,4 @@ "rollForward": false } } -} \ No newline at end of file +} diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9a3f711dcd..f63c9c32ce 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,21 +1,21 @@ - + https://github.com/dotnet/arcade - d0f89c635d780e183a97ad86af4f3c8d7e95977f + e8de3415124309210e4cbd0105e4a9da8dc01696 - + https://github.com/dotnet/arcade - d0f89c635d780e183a97ad86af4f3c8d7e95977f + e8de3415124309210e4cbd0105e4a9da8dc01696 - + https://github.com/dotnet/arcade - d0f89c635d780e183a97ad86af4f3c8d7e95977f + e8de3415124309210e4cbd0105e4a9da8dc01696 - + https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage - 2d88381a218863f6b20537637b2bcfb0bc93686d + 1547dfdcb0794801b9ab81c88eb51e56b563a0c9 https://github.com/microsoft/testanywhere diff --git a/eng/Versions.props b/eng/Versions.props index 5b6258d206..1ef856fc21 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,8 +7,8 @@ preview - 10.0.0-beta.24577.1 - 17.13.0-preview.24572.7 + 10.0.0-beta.24578.2 + 17.13.0-preview.24579.2 1.5.0-preview.24576.1 1.0.0-alpha.24473.2 diff --git a/eng/common/native/install-dependencies.sh b/eng/common/native/install-dependencies.sh index dc396a9556..3eef7409f7 100644 --- a/eng/common/native/install-dependencies.sh +++ b/eng/common/native/install-dependencies.sh @@ -44,15 +44,11 @@ case "$os" in export HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 # Skip brew update for now, see https://github.com/actions/setup-python/issues/577 # brew update --preinstall - - # Temporarily uninstall pkg-config@0.29.2 to work around https://github.com/actions/runner-images/issues/10984 - brew uninstall --ignore-dependencies --force pkg-config@0.29.2 - brew bundle --no-upgrade --no-lock --file=- < Date: Sat, 30 Nov 2024 07:06:38 +0100 Subject: [PATCH 036/273] Add a MSTest sample with a program.cs (#4201) --- .../MSTestProjectWithExplicitMain.sln | 25 +++++++++++ .../MSTestProjectWithExplicitMain.csproj | 31 ++++++++++++++ .../MSTestSettings.cs | 4 ++ .../MSTestProjectWithExplicitMain/Program.cs | 42 +++++++++++++++++++ .../MSTestProjectWithExplicitMain/Test1.cs | 13 ++++++ 5 files changed, 115 insertions(+) create mode 100644 samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain.sln create mode 100644 samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain.csproj create mode 100644 samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/MSTestSettings.cs create mode 100644 samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/Program.cs create mode 100644 samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/Test1.cs diff --git a/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain.sln b/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain.sln new file mode 100644 index 0000000000..392762a899 --- /dev/null +++ b/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.13.35507.96 d17.13 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSTestProjectWithExplicitMain", "MSTestProjectWithExplicitMain\MSTestProjectWithExplicitMain.csproj", "{3F00FD7B-D9E6-42C6-8607-3186BFBD4A0F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3F00FD7B-D9E6-42C6-8607-3186BFBD4A0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3F00FD7B-D9E6-42C6-8607-3186BFBD4A0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3F00FD7B-D9E6-42C6-8607-3186BFBD4A0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3F00FD7B-D9E6-42C6-8607-3186BFBD4A0F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {68CE81DD-68F6-49B0-87AF-DC6223F45845} + EndGlobalSection +EndGlobal diff --git a/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain.csproj b/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain.csproj new file mode 100644 index 0000000000..83058077b3 --- /dev/null +++ b/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain.csproj @@ -0,0 +1,31 @@ + + + + net9.0 + latest + enable + enable + true + Exe + true + + true + + false + + + + + + + + + + + + + + diff --git a/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/MSTestSettings.cs b/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/MSTestSettings.cs new file mode 100644 index 0000000000..553a44aa64 --- /dev/null +++ b/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/MSTestSettings.cs @@ -0,0 +1,4 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel)] diff --git a/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/Program.cs b/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/Program.cs new file mode 100644 index 0000000000..d0f56c90bd --- /dev/null +++ b/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/Program.cs @@ -0,0 +1,42 @@ +// 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.Reflection; + +using Microsoft.Testing.Extensions; +using Microsoft.Testing.Platform.Builder; + +// Create the test application builder +ITestApplicationBuilder testApplicationBuilder = await TestApplication.CreateBuilderAsync(args); + +// Register the testing framework +testApplicationBuilder.AddMSTest(() => new[] { Assembly.GetExecutingAssembly() }); + +// Register Code Coverage extension +testApplicationBuilder.AddCodeCoverageProvider(); + +// Register TRX report extension +testApplicationBuilder.AddTrxReportProvider(); + +// Register Telemetry extension +testApplicationBuilder.AddAppInsightsTelemetryProvider(); + +// Alternatively, instead of registering everything manually, I could rely on the MSBuild hooks and use +// testApplicationBuilder.AddSelfRegisteredExtensions(args); +// This is what is called by the generated entry point + +// In addition to be using each extension helper method, we can directly register extensions to each of +// the extensibility area. For now, the following 3 are exposed: +// testApplicationBuilder.CommandLine +// testApplicationBuilder.TestHost +// testApplicationBuilder.TestHostControllers +// but the goal is to also expose all these areas: https://github.com/microsoft/testfx/blob/main/src/Platform/Microsoft.Testing.Platform/Builder/TestApplicationBuilder.cs#L57-L69 + +// NOTE that registering an extension is not enough and each extension has some activation criteria, +// most of the time the presence of a command line option but it could be anything (including nothing). + +// Build the test app +using ITestApplication testApplication = await testApplicationBuilder.BuildAsync(); + +// Run the test app +return await testApplication.RunAsync(); diff --git a/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/Test1.cs b/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/Test1.cs new file mode 100644 index 0000000000..21f9186303 --- /dev/null +++ b/samples/public/mstest-runner/MSTestProjectWithExplicitMain/MSTestProjectWithExplicitMain/Test1.cs @@ -0,0 +1,13 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace MSTestProjectWithExplicitMain; + +[TestClass] +public sealed class Test1 +{ + [TestMethod] + public void TestMethod1() + { + } +} From a3805f89a2d13fbd30bbaf00a88363c588d591c7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sat, 30 Nov 2024 22:04:36 +0100 Subject: [PATCH 037/273] [main] Update dependencies from devdiv/DevDiv/vs-code-coverage (#4202) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f63c9c32ce..8701a438f8 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,9 +13,9 @@ https://github.com/dotnet/arcade e8de3415124309210e4cbd0105e4a9da8dc01696 - + https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage - 1547dfdcb0794801b9ab81c88eb51e56b563a0c9 + 895c1757454b3f0b493cf9049facf983802985a0 https://github.com/microsoft/testanywhere diff --git a/eng/Versions.props b/eng/Versions.props index 1ef856fc21..a31bce1d05 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,7 +8,7 @@ 10.0.0-beta.24578.2 - 17.13.0-preview.24579.2 + 17.13.0-preview.24579.4 1.5.0-preview.24576.1 1.0.0-alpha.24473.2 From b7d281b4dfcb308ecff1e320d4c616ff9323f467 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 2 Dec 2024 10:28:02 +0100 Subject: [PATCH 038/273] Remove test workaround that alters Sdk targets (#4205) --- .../MSBuildTests.Solution.cs | 231 ------------------ 1 file changed, 231 deletions(-) diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs index e004a8ced4..7ad84c074d 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs @@ -11,28 +11,9 @@ public class MSBuildTests_Solution : AcceptanceTestBase private readonly AcceptanceFixture _acceptanceFixture; private const string AssetName = "MSTestProject"; - static MSBuildTests_Solution() - { - string dotnetMuxerSDK = Directory.GetDirectories(Path.Combine(RootFinder.Find(), ".dotnet", "sdk")).OrderByDescending(x => x).First(); - File.WriteAllText(Path.Combine(dotnetMuxerSDK, "Microsoft.Common.CrossTargeting.targets"), MicrosoftCommonCrossTargeting); - if (!File.Exists(Path.Combine(dotnetMuxerSDK, "Microsoft.Common.Test.targets"))) - { - File.WriteAllText(Path.Combine(dotnetMuxerSDK, "Microsoft.Common.Test.targets"), MicrosoftCommonTesttargets); - } - } - public MSBuildTests_Solution(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - private void CheckPatch() - { - // https://github.com/dotnet/sdk/issues/37712 - if (DateTime.UtcNow.Date > new DateTime(2024, 12, 1)) - { - throw new InvalidOperationException("Check if we can remove the patch!"); - } - } - internal static IEnumerable> GetBuildMatrix() { foreach (TestArgumentsEntry<(string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm)> entry in GetBuildMatrixSingleAndMultiTfmBuildConfiguration()) @@ -52,8 +33,6 @@ private void CheckPatch() [ArgumentsProvider(nameof(GetBuildMatrix))] public async Task MSBuildTests_UseMSBuildTestInfrastructure_Should_Run_Solution_Tests(string singleTfmOrMultiTfm, BuildConfiguration _, bool isMultiTfm, string command) { - CheckPatch(); - using TestAsset generator = await TestAsset.GenerateAssetAsync( AssetName, SourceCode @@ -155,215 +134,5 @@ public void TestMethod1() global using Microsoft.Testing.Platform.Builder; global using Microsoft.Testing.Internal.Framework; global using Microsoft.Testing.Platform.MSBuild; -"""; - - private const string MicrosoftCommonCrossTargeting = """ - - - - true - true - - - - - - - - - - <_ThisProjectBuildMetadata Include="$(MSBuildProjectFullPath)"> - @(_TargetFrameworkInfo) - @(_TargetFrameworkInfo->'%(TargetFrameworkMonikers)') - @(_TargetFrameworkInfo->'%(TargetPlatformMonikers)') - $(_AdditionalPropertiesFromProject) - false - @(_TargetFrameworkInfo->'%(IsRidAgnostic)') - - - false - $(Platform) - $(Platforms) - - - - - - <_TargetFramework Include="$(TargetFrameworks)" /> - - <_TargetFrameworkNormalized Include="@(_TargetFramework->Trim()->Distinct())" /> - <_InnerBuildProjects Include="$(MSBuildProjectFile)"> - TargetFramework=%(_TargetFrameworkNormalized.Identity) - - - - - - - - - - - - true - - - - - - - - - - - - - Build - - - - - - - - - - - - $([MSBuild]::IsRunningFromVisualStudio()) - $([MSBuild]::GetToolsDirectory32())\..\..\..\Common7\IDE\CommonExtensions\Microsoft\NuGet\NuGet.targets - $(MSBuildToolsPath)\NuGet.targets - - - - - - true - - - - - true - - - - true - - - - <_DirectoryBuildTargetsFile Condition="'$(_DirectoryBuildTargetsFile)' == ''">Directory.Build.targets - <_DirectoryBuildTargetsBasePath Condition="'$(_DirectoryBuildTargetsBasePath)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), '$(_DirectoryBuildTargetsFile)')) - $([System.IO.Path]::Combine('$(_DirectoryBuildTargetsBasePath)', '$(_DirectoryBuildTargetsFile)')) - - - - false - - - -"""; - - private const string MicrosoftCommonTesttargets = """ - - - """; } From 3e7ac66744ee70c7e7f38ba47f9693bea566db15 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 2 Dec 2024 10:33:09 +0100 Subject: [PATCH 039/273] Implement codefix for MSTEST0037: Use proper 'Assert' methods (#4162) --- .../CodeFixResources.Designer.cs | 9 + .../CodeFixResources.resx | 3 + .../UseProperAssertMethodsFixer.cs | 209 ++++++++ .../xlf/CodeFixResources.cs.xlf | 5 + .../xlf/CodeFixResources.de.xlf | 5 + .../xlf/CodeFixResources.es.xlf | 5 + .../xlf/CodeFixResources.fr.xlf | 5 + .../xlf/CodeFixResources.it.xlf | 5 + .../xlf/CodeFixResources.ja.xlf | 5 + .../xlf/CodeFixResources.ko.xlf | 5 + .../xlf/CodeFixResources.pl.xlf | 5 + .../xlf/CodeFixResources.pt-BR.xlf | 5 + .../xlf/CodeFixResources.ru.xlf | 5 + .../xlf/CodeFixResources.tr.xlf | 5 + .../xlf/CodeFixResources.zh-Hans.xlf | 5 + .../xlf/CodeFixResources.zh-Hant.xlf | 5 + .../ITypeSymbolExtensions.cs | 6 + .../UseProperAssertMethodsAnalyzer.cs | 224 +++++++-- .../UseProperAssertMethodsAnalyzerTests.cs | 459 ++++++++++++++++-- .../Verifiers/CSharpCodeFixVerifier`2.cs | 4 + 20 files changed, 917 insertions(+), 62 deletions(-) create mode 100644 src/Analyzers/MSTest.Analyzers.CodeFixes/UseProperAssertMethodsFixer.cs diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs index 442d0dc282..23c6c67073 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs @@ -203,5 +203,14 @@ internal static string UseAttributeOnTestMethodFix { return ResourceManager.GetString("UseAttributeOnTestMethodFix", resourceCulture); } } + + /// + /// Looks up a localized string similar to Use '{0}'. + /// + internal static string UseProperAssertMethodsFix { + get { + return ResourceManager.GetString("UseProperAssertMethodsFix", resourceCulture); + } + } } } diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx index 6e97d9e1a8..a3f8296b3e 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx @@ -165,4 +165,7 @@ Use 'Assert.ThrowsException<T>' instead of '[ExpectedException]' attribute + + Use '{0}' + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/UseProperAssertMethodsFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/UseProperAssertMethodsFixer.cs new file mode 100644 index 0000000000..9350d06abf --- /dev/null +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/UseProperAssertMethodsFixer.cs @@ -0,0 +1,209 @@ +// 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 System.Composition; +using System.Diagnostics; +using System.Globalization; + +using Analyzer.Utilities; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.Formatting; + +using MSTest.Analyzers.Helpers; + +namespace MSTest.Analyzers; + +[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(UseProperAssertMethodsFixer))] +[Shared] +public sealed class UseProperAssertMethodsFixer : CodeFixProvider +{ + public sealed override ImmutableArray FixableDiagnosticIds { get; } + = ImmutableArray.Create(DiagnosticIds.UseProperAssertMethodsRuleId); + + public override FixAllProvider GetFixAllProvider() + // See https://github.com/dotnet/roslyn/blob/main/docs/analyzers/FixAllProvider.md for more information on Fix All Providers + => WellKnownFixAllProviders.BatchFixer; + + public override async Task RegisterCodeFixesAsync(CodeFixContext context) + { + SyntaxNode root = await context.Document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + Diagnostic diagnostic = context.Diagnostics[0]; + string? mode = diagnostic.Properties[UseProperAssertMethodsAnalyzer.CodeFixModeKey]; + string? properAssertMethodName = diagnostic.Properties[UseProperAssertMethodsAnalyzer.ProperAssertMethodNameKey]; + if (mode is null || properAssertMethodName is null) + { + Debug.Fail($"Both '{nameof(mode)}' and '{properAssertMethodName}' are expected to be non-null."); + return; + } + + SyntaxNode diagnosticNode = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); + if (diagnosticNode is not InvocationExpressionSyntax invocation) + { + Debug.Fail($"Is this an interesting scenario where IInvocationOperation for Assert call isn't associated with InvocationExpressionSyntax? SyntaxNode type: '{diagnosticNode.GetType()}', Text: '{diagnosticNode.GetText()}'"); + return; + } + + SyntaxNode methodNameIdentifier = invocation.Expression; + if (methodNameIdentifier is MemberAccessExpressionSyntax memberAccess) + { + methodNameIdentifier = memberAccess.Name; + } + + if (methodNameIdentifier is not SimpleNameSyntax simpleNameSyntax) + { + Debug.Fail($"Is this an interesting scenario where we are unable to retrieve SimpleNameSyntax corresponding to the assert method? SyntaxNode type: '{methodNameIdentifier}', Text: '{methodNameIdentifier.GetText()}'."); + return; + } + + Func>? createChangedDocument = null; + switch (mode) + { + case UseProperAssertMethodsAnalyzer.CodeFixModeSimple: + createChangedDocument = ct => FixAssertMethodForSimpleModeAsync(context.Document, diagnostic.AdditionalLocations[0], diagnostic.AdditionalLocations[1], root, simpleNameSyntax, properAssertMethodName, ct); + break; + case UseProperAssertMethodsAnalyzer.CodeFixModeAddArgument: + createChangedDocument = ct => FixAssertMethodForAddArgumentModeAsync(context.Document, diagnostic.AdditionalLocations[0], diagnostic.AdditionalLocations[1], diagnostic.AdditionalLocations[2], root, simpleNameSyntax, properAssertMethodName, ct); + break; + case UseProperAssertMethodsAnalyzer.CodeFixModeRemoveArgument: + createChangedDocument = ct => FixAssertMethodForRemoveArgumentModeAsync(context.Document, diagnostic.AdditionalLocations, root, simpleNameSyntax, properAssertMethodName, diagnostic.Properties.ContainsKey(UseProperAssertMethodsAnalyzer.NeedsNullableBooleanCastKey), ct); + break; + default: + break; + } + + if (createChangedDocument is not null) + { + context.RegisterCodeFix( + CodeAction.Create( + title: string.Format(CultureInfo.InvariantCulture, CodeFixResources.UseProperAssertMethodsFix, properAssertMethodName), + createChangedDocument, + equivalenceKey: nameof(UseProperAssertMethodsFixer)), + diagnostic); + } + } + + private static async Task FixAssertMethodForSimpleModeAsync(Document document, Location conditionLocationToBeReplaced, Location replacementExpressionLocation, SyntaxNode root, SimpleNameSyntax simpleNameSyntax, string properAssertMethodName, CancellationToken cancellationToken) + { + // This doesn't properly handle cases like Assert.IsTrue(message: "My message", condition: x == null) + // The proper handling of this may be Assert.IsNull(message: "My message", value: x) + // Or: Assert.IsNull(x, "My message") + // For now this is not handled. + if (root.FindNode(conditionLocationToBeReplaced.SourceSpan) is not ArgumentSyntax conditionNodeToBeReplaced) + { + return document; + } + + if (root.FindNode(replacementExpressionLocation.SourceSpan) is not ExpressionSyntax replacementExpressionNode) + { + return document; + } + + DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); + FixInvocationMethodName(editor, simpleNameSyntax, properAssertMethodName); + editor.ReplaceNode(conditionNodeToBeReplaced, SyntaxFactory.Argument(replacementExpressionNode).WithAdditionalAnnotations(Formatter.Annotation)); + + return editor.GetChangedDocument(); + } + + private static async Task FixAssertMethodForAddArgumentModeAsync(Document document, Location conditionLocation, Location expectedLocation, Location actualLocation, SyntaxNode root, SimpleNameSyntax simpleNameSyntax, string properAssertMethodName, CancellationToken cancellationToken) + { + // This doesn't properly handle cases like Assert.IsTrue(message: "My message", condition: x == y) + // The proper handling of this may be Assert.AreEqual(message: "My message", expected: x, actual: y) + // Or: Assert.AreEqual(x, y, "My message") + // For now this is not handled. + if (root.FindNode(conditionLocation.SourceSpan) is not ArgumentSyntax conditionNode) + { + return document; + } + + if (conditionNode.Parent is not ArgumentListSyntax argumentList) + { + return document; + } + + if (root.FindNode(expectedLocation.SourceSpan) is not ExpressionSyntax expectedNode) + { + return document; + } + + if (root.FindNode(actualLocation.SourceSpan) is not ExpressionSyntax actualNode) + { + return document; + } + + DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); + FixInvocationMethodName(editor, simpleNameSyntax, properAssertMethodName); + + ArgumentListSyntax newArgumentList = argumentList; + newArgumentList = newArgumentList.ReplaceNode(conditionNode, SyntaxFactory.Argument(expectedNode).WithAdditionalAnnotations(Formatter.Annotation)); + int insertionIndex = argumentList.Arguments.IndexOf(conditionNode) + 1; + newArgumentList = newArgumentList.WithArguments(newArgumentList.Arguments.Insert(insertionIndex, SyntaxFactory.Argument(actualNode).WithAdditionalAnnotations(Formatter.Annotation))); + + editor.ReplaceNode(argumentList, newArgumentList); + + return editor.GetChangedDocument(); + } + + private static async Task FixAssertMethodForRemoveArgumentModeAsync( + Document document, + IReadOnlyList additionalLocations, + SyntaxNode root, + SimpleNameSyntax simpleNameSyntax, + string properAssertMethodName, + bool needsNullableBoolCast, + CancellationToken cancellationToken) + { + // This doesn't properly handle cases like Assert.AreEqual(message: "My message", expected: true, actual: x) + // The proper handling of this may be Assert.IsTrue(message: "My message", condition: x) + // Or: Assert.IsTrue(x, "My message") + // For now this is not handled. + if (root.FindNode(additionalLocations[0].SourceSpan) is not ArgumentSyntax expectedArgumentToRemove) + { + return document; + } + + if (expectedArgumentToRemove.Parent is not ArgumentListSyntax argumentList) + { + return document; + } + + DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); + FixInvocationMethodName(editor, simpleNameSyntax, properAssertMethodName); + + int argumentIndexToRemove = argumentList.Arguments.IndexOf(expectedArgumentToRemove); + ArgumentListSyntax newArgumentList; + if (additionalLocations.Count > 1 && needsNullableBoolCast && + root.FindNode(additionalLocations[1].SourceSpan) is ArgumentSyntax actualArgument) + { + Compilation compilation = editor.SemanticModel.Compilation; + var castExpression = (CastExpressionSyntax)editor.Generator.CastExpression( + compilation.GetSpecialType(SpecialType.System_Nullable_T).Construct(compilation.GetSpecialType(SpecialType.System_Boolean)), + actualArgument.Expression); + newArgumentList = argumentList.WithArguments( + argumentList.Arguments.Replace(actualArgument, SyntaxFactory.Argument(castExpression)).RemoveAt(argumentIndexToRemove)); + } + else + { + newArgumentList = argumentList.WithArguments(argumentList.Arguments.RemoveAt(argumentIndexToRemove)); + } + + editor.ReplaceNode(argumentList, newArgumentList); + + return editor.GetChangedDocument(); + } + + private static void FixInvocationMethodName(DocumentEditor editor, SimpleNameSyntax simpleNameSyntax, string properAssertMethodName) + // NOTE: Switching Assert.IsTrue(x == y) to Assert.AreEqual(x, y) MAY produce an overload resolution error. + // For example, Assert.AreEqual("string", true) will fail the inference for generic argument. + // This is not very common and is currently not handled properly. + // If needed, we can adjust the codefix to account for that case and + // produce a GenericNameSyntax (e.g, AreEqual) instead of IdentifierNameSyntax (e.g, AreEqual). + => editor.ReplaceNode(simpleNameSyntax, SyntaxFactory.IdentifierName(properAssertMethodName)); +} diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf index db5674fdf1..52437221ca 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf @@ -82,6 +82,11 @@ Přidat [TestMethod] + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf index 50a6abafdd..09100d9ed2 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf @@ -82,6 +82,11 @@ „[TestMethod]“ hinzufügen + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf index 12e4190d26..2858582c3b 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf @@ -82,6 +82,11 @@ Agregar '[TestMethod]' + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf index 8889521f4a..2efae20a2f 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf @@ -82,6 +82,11 @@ Ajouter « [TestMethod] » + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf index 478c90b34b..d8b88fbb48 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf @@ -82,6 +82,11 @@ Aggiungi '[TestMethod]' + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf index 21dd08acd7..7ac61d85fa 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf @@ -82,6 +82,11 @@ '[TestMethod]' の追加 + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf index 06ce6bd200..ea68841a9c 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf @@ -82,6 +82,11 @@ '[TestMethod]' 추가 + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf index 0debfd4fc0..bb4f55e225 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf @@ -82,6 +82,11 @@ Dodaj „[TestMethod]” + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf index a4cf86f456..0ebb07b529 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf @@ -82,6 +82,11 @@ Adicionar ''[TestMethod]" + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf index b53cdeb2f9..b1c1938023 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf @@ -82,6 +82,11 @@ Добавить "[TestMethod]" + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf index d770bdb04f..07a03d4d10 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf @@ -82,6 +82,11 @@ '[TestMethod]' ekle + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf index 6049a3b42f..3c8412618a 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf @@ -82,6 +82,11 @@ 添加“[TestMethod]” + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf index baf429ed2c..64444c7af9 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf @@ -82,6 +82,11 @@ 新增 '[TestMethod]' + + Use '{0}' + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ITypeSymbolExtensions.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ITypeSymbolExtensions.cs index 86ee2ec619..dbd736e80a 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ITypeSymbolExtensions.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ITypeSymbolExtensions.cs @@ -87,4 +87,10 @@ public static bool DerivesFrom([NotNullWhen(returnValue: true)] this ITypeSymbol return false; } + + public static bool IsNullableValueType([NotNullWhen(returnValue: true)] this ITypeSymbol? typeSymbol) + => typeSymbol != null && typeSymbol.IsValueType && typeSymbol.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T; + + public static bool IsNullableOfBoolean([NotNullWhen(returnValue: true)] this ITypeSymbol? typeSymbol) + => typeSymbol.IsNullableValueType() && ((INamedTypeSymbol)typeSymbol).TypeArguments[0].SpecialType == SpecialType.System_Boolean; } diff --git a/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs index 223400bc52..f76566038a 100644 --- a/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs @@ -2,9 +2,9 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Immutable; -using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using Analyzer.Utilities; using Analyzer.Utilities.Extensions; using Microsoft.CodeAnalysis; @@ -53,6 +53,66 @@ private enum EqualityCheckStatus NotEquals, } + internal const string ProperAssertMethodNameKey = nameof(ProperAssertMethodNameKey); + + /// + /// Only the presence of this key in properties bag indicates that a cast is needed. + /// The value of the key is always null. + /// + internal const string NeedsNullableBooleanCastKey = nameof(NeedsNullableBooleanCastKey); + + /// + /// Key in the properties bag that has value one of CodeFixModeSimple, CodeFixModeAddArgument, or CodeFixModeRemoveArgument. + /// + internal const string CodeFixModeKey = nameof(CodeFixModeKey); + + /// + /// This mode means the codefix operation is as follows: + /// + /// Find the right assert method name from the properties bag using . + /// Replace the identifier syntax for the invocation with the right assert method name. The identifier syntax is calculated by the codefix. + /// Replace the syntax node from the first additional locations with the node from second additional locations. + /// + /// Example: For Assert.IsTrue(x == null), it will become Assert.IsNull(x). + /// The value for ProperAssertMethodNameKey is "IsNull". + /// The first additional location will point to the "x == null" node. + /// The second additional location will point to the "x" node. + /// + internal const string CodeFixModeSimple = nameof(CodeFixModeSimple); + + /// + /// This mode means the codefix operation is as follows: + /// + /// Find the right assert method name from the properties bag using . + /// Replace the identifier syntax for the invocation with the right assert method name. The identifier syntax is calculated by the codefix. + /// Replace the syntax node from the first additional locations with the node from second additional locations. + /// Add new argument which is identical to the node from third additional locations. + /// + /// Example: For Assert.IsTrue(x == y), it will become Assert.AreEqual(y, x). + /// The value for ProperAssertMethodNameKey is "AreEqual". + /// The first additional location will point to the "x == y" node. + /// The second additional location will point to the "y" node. + /// The third additional location will point to the "x" node. + /// + internal const string CodeFixModeAddArgument = nameof(CodeFixModeAddArgument); + + /// + /// This mode means the codefix operation is as follows: + /// + /// Find the right assert method name from the properties bag using . + /// Replace the identifier syntax for the invocation with the right assert method name. The identifier syntax is calculated by the codefix. + /// Remove the argument which the second additional locations points to. + /// + /// Example: For Assert.AreEqual(false, x), it will become Assert.IsFalse(x). + /// The value for ProperAssertMethodNameKey is "IsFalse". + /// The first additional location will point to the "false" node. + /// The second additional location will point to the "x" node, in case a cast is needed. + /// + /// + /// If is present, then the produced code will be Assert.IsFalse((bool?)x);. + /// + internal const string CodeFixModeRemoveArgument = nameof(CodeFixModeRemoveArgument); + private static readonly LocalizableResourceString Title = new(nameof(Resources.UseProperAssertMethodsTitle), Resources.ResourceManager, typeof(Resources)); private static readonly LocalizableResourceString MessageFormat = new(nameof(Resources.UseProperAssertMethodsMessageFormat), Resources.ResourceManager, typeof(Resources)); @@ -118,31 +178,67 @@ private static void AnalyzeInvocationOperation(OperationAnalysisContext context, } } - private static bool IsIsNullPattern(IOperation operation) - => operation is IIsPatternOperation { Pattern: IConstantPatternOperation { Value: { } constantPatternValue } } && - constantPatternValue.WalkDownConversion() is ILiteralOperation { ConstantValue: { HasValue: true, Value: null } }; + private static bool IsIsNullPattern(IOperation operation, [NotNullWhen(true)] out SyntaxNode? expressionUnderTest) + { + if (operation is IIsPatternOperation { Pattern: IConstantPatternOperation { Value: { } constantPatternValue } } isPatternOperation && + constantPatternValue.WalkDownConversion() is ILiteralOperation { ConstantValue: { HasValue: true, Value: null } }) + { + expressionUnderTest = isPatternOperation.Value.Syntax; + return true; + } + + expressionUnderTest = null; + return false; + } + + private static bool IsIsNotNullPattern(IOperation operation, [NotNullWhen(true)] out SyntaxNode? expressionUnderTest) + { + if (operation is IIsPatternOperation { Pattern: INegatedPatternOperation { Pattern: IConstantPatternOperation { Value: { } constantPatternValue } } } isPatternOperation && + constantPatternValue.WalkDownConversion() is ILiteralOperation { ConstantValue: { HasValue: true, Value: null } }) + { + expressionUnderTest = isPatternOperation.Value.Syntax; + return true; + } - private static bool IsIsNotNullPattern(IOperation operation) - => operation is IIsPatternOperation { Pattern: INegatedPatternOperation { Pattern: IConstantPatternOperation { Value: { } constantPatternValue } } } && - constantPatternValue.WalkDownConversion() is ILiteralOperation { ConstantValue: { HasValue: true, Value: null } }; + expressionUnderTest = null; + return false; + } // TODO: Recognize 'null == something' (i.e, when null is the left operand) - private static bool IsEqualsNullBinaryOperator(IOperation operation) - => operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.Equals, RightOperand: { } rightOperand } && - rightOperand.WalkDownConversion() is ILiteralOperation { ConstantValue: { HasValue: true, Value: null } }; + private static bool IsEqualsNullBinaryOperator(IOperation operation, [NotNullWhen(true)] out SyntaxNode? expressionUnderTest) + { + if (operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.Equals, RightOperand: { } rightOperand } binaryOperation && + rightOperand.WalkDownConversion() is ILiteralOperation { ConstantValue: { HasValue: true, Value: null } }) + { + expressionUnderTest = binaryOperation.LeftOperand.Syntax; + return true; + } + + expressionUnderTest = null; + return false; + } // TODO: Recognize 'null != something' (i.e, when null is the left operand) - private static bool IsNotEqualsNullBinaryOperator(IOperation operation) - => operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.NotEquals, RightOperand: { } rightOperand } && - rightOperand.WalkDownConversion() is ILiteralOperation { ConstantValue: { HasValue: true, Value: null } }; + private static bool IsNotEqualsNullBinaryOperator(IOperation operation, [NotNullWhen(true)] out SyntaxNode? expressionUnderTest) + { + if (operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.NotEquals, RightOperand: { } rightOperand } binaryOperation && + rightOperand.WalkDownConversion() is ILiteralOperation { ConstantValue: { HasValue: true, Value: null } }) + { + expressionUnderTest = binaryOperation.LeftOperand.Syntax; + return true; + } - private static NullCheckStatus RecognizeNullCheck(IOperation operation) + expressionUnderTest = null; + return false; + } + + private static NullCheckStatus RecognizeNullCheck(IOperation operation, /*We cannot express this is not null when NullCheckStatis is not Unknown*/ out SyntaxNode? expressionUnderTest) { - if (IsIsNullPattern(operation) || IsEqualsNullBinaryOperator(operation)) + if (IsIsNullPattern(operation, out expressionUnderTest) || IsEqualsNullBinaryOperator(operation, out expressionUnderTest)) { return NullCheckStatus.IsNull; } - else if (IsIsNotNullPattern(operation) || IsNotEqualsNullBinaryOperator(operation)) + else if (IsIsNotNullPattern(operation, out expressionUnderTest) || IsNotEqualsNullBinaryOperator(operation, out expressionUnderTest)) { return NullCheckStatus.IsNotNull; } @@ -150,52 +246,91 @@ private static NullCheckStatus RecognizeNullCheck(IOperation operation) return NullCheckStatus.Unknown; } - private static EqualityCheckStatus RecognizeEqualityCheck(IOperation operation) + private static EqualityCheckStatus RecognizeEqualityCheck(IOperation operation, out SyntaxNode? toBecomeExpected, out SyntaxNode? toBecomeActual) { - if (operation is IIsPatternOperation { Pattern: IConstantPatternOperation } or - IBinaryOperation { OperatorKind: BinaryOperatorKind.Equals }) + if (operation is IIsPatternOperation { Pattern: IConstantPatternOperation constantPattern1 } isPattern1) { + toBecomeExpected = constantPattern1.Syntax; + toBecomeActual = isPattern1.Value.Syntax; return EqualityCheckStatus.Equals; } - else if (operation is IIsPatternOperation { Pattern: INegatedPatternOperation { Pattern: IConstantPatternOperation } } or - IBinaryOperation { OperatorKind: BinaryOperatorKind.NotEquals }) + else if (operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.Equals } binaryOperation1) + { + // This is quite arbitrary. We can do extra checks to see which one (if any) looks like a "constant" and make it the expected. + toBecomeExpected = binaryOperation1.RightOperand.Syntax; + toBecomeActual = binaryOperation1.LeftOperand.Syntax; + return EqualityCheckStatus.Equals; + } + else if (operation is IIsPatternOperation { Pattern: INegatedPatternOperation { Pattern: IConstantPatternOperation constantPattern2 } } isPattern2) + { + toBecomeExpected = constantPattern2.Syntax; + toBecomeActual = isPattern2.Value.Syntax; + return EqualityCheckStatus.NotEquals; + } + else if (operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.NotEquals } binaryOperation2) { + // This is quite arbitrary. We can do extra checks to see which one (if any) looks like a "constant" and make it the expected. + toBecomeExpected = binaryOperation2.RightOperand.Syntax; + toBecomeActual = binaryOperation2.LeftOperand.Syntax; return EqualityCheckStatus.NotEquals; } + toBecomeExpected = null; + toBecomeActual = null; return EqualityCheckStatus.Unknown; } private static void AnalyzeIsTrueOrIsFalseInvocation(OperationAnalysisContext context, IOperation conditionArgument, bool isTrueInvocation) { - NullCheckStatus nullCheckStatus = RecognizeNullCheck(conditionArgument); + RoslynDebug.Assert(context.Operation is IInvocationOperation, "Expected IInvocationOperation."); + + NullCheckStatus nullCheckStatus = RecognizeNullCheck(conditionArgument, out SyntaxNode? expressionUnderTest); if (nullCheckStatus != NullCheckStatus.Unknown) { - Debug.Assert(nullCheckStatus is NullCheckStatus.IsNull or NullCheckStatus.IsNotNull, "Unexpected NullCheckStatus value."); + RoslynDebug.Assert(expressionUnderTest is not null, $"Unexpected null for '{nameof(expressionUnderTest)}'."); + RoslynDebug.Assert(nullCheckStatus is NullCheckStatus.IsNull or NullCheckStatus.IsNotNull, "Unexpected NullCheckStatus value."); bool shouldUseIsNull = isTrueInvocation ? nullCheckStatus == NullCheckStatus.IsNull : nullCheckStatus == NullCheckStatus.IsNotNull; + // Here, the codefix will want to switch something like Assert.IsTrue(x == null) with Assert.IsNull(x) + // This is the "simple" mode. + // The message is: Use 'Assert.{0}' instead of 'Assert.{1}'. + string properAssertMethod = shouldUseIsNull ? "IsNull" : "IsNotNull"; context.ReportDiagnostic(context.Operation.CreateDiagnostic( Rule, - shouldUseIsNull ? "IsNull" : "IsNotNull", + additionalLocations: ImmutableArray.Create(conditionArgument.Syntax.GetLocation(), expressionUnderTest.GetLocation()), + properties: ImmutableDictionary.Empty + .Add(ProperAssertMethodNameKey, properAssertMethod) + .Add(CodeFixModeKey, CodeFixModeSimple), + properAssertMethod, isTrueInvocation ? "IsTrue" : "IsFalse")); return; } - EqualityCheckStatus equalityCheckStatus = RecognizeEqualityCheck(conditionArgument); + EqualityCheckStatus equalityCheckStatus = RecognizeEqualityCheck(conditionArgument, out SyntaxNode? toBecomeExpected, out SyntaxNode? toBecomeActual); if (equalityCheckStatus != EqualityCheckStatus.Unknown) { - Debug.Assert(equalityCheckStatus is EqualityCheckStatus.Equals or EqualityCheckStatus.NotEquals, "Unexpected EqualityCheckStatus value."); + RoslynDebug.Assert(toBecomeExpected is not null, $"Unexpected null for '{nameof(toBecomeExpected)}'."); + RoslynDebug.Assert(toBecomeActual is not null, $"Unexpected null for '{nameof(toBecomeActual)}'."); + RoslynDebug.Assert(equalityCheckStatus is EqualityCheckStatus.Equals or EqualityCheckStatus.NotEquals, "Unexpected EqualityCheckStatus value."); bool shouldUseAreEqual = isTrueInvocation ? equalityCheckStatus == EqualityCheckStatus.Equals : equalityCheckStatus == EqualityCheckStatus.NotEquals; + // Here, the codefix will want to switch something like Assert.IsTrue(x == y) with Assert.AreEqual(x, y) + // This is the "add argument" mode. + // The message is: Use 'Assert.{0}' instead of 'Assert.{1}'. + string properAssertMethod = shouldUseAreEqual ? "AreEqual" : "AreNotEqual"; context.ReportDiagnostic(context.Operation.CreateDiagnostic( Rule, - shouldUseAreEqual ? "AreEqual" : "AreNotEqual", + additionalLocations: ImmutableArray.Create(conditionArgument.Syntax.GetLocation(), toBecomeExpected.GetLocation(), toBecomeActual.GetLocation()), + properties: ImmutableDictionary.Empty + .Add(ProperAssertMethodNameKey, properAssertMethod) + .Add(CodeFixModeKey, CodeFixModeAddArgument), + properAssertMethod, isTrueInvocation ? "IsTrue" : "IsFalse")); return; } @@ -209,20 +344,48 @@ private static void AnalyzeAreEqualOrAreNotEqualInvocation(OperationAnalysisCont { bool shouldUseIsTrue = expectedLiteralBoolean; + // Here, the codefix will want to switch something like Assert.AreEqual(true, x) with Assert.IsTrue(x) + // This is the "remove argument" mode. + // The message is: Use 'Assert.{0}' instead of 'Assert.{1}'. + string properAssertMethod = shouldUseIsTrue ? "IsTrue" : "IsFalse"; + + bool codeFixShouldAddCast = TryGetSecondArgumentValue((IInvocationOperation)context.Operation, out IOperation? actualArgumentValue) && + actualArgumentValue.Type is { } actualType && + actualType.SpecialType != SpecialType.System_Boolean && + !actualType.IsNullableOfBoolean(); + + ImmutableDictionary properties = ImmutableDictionary.Empty + .Add(ProperAssertMethodNameKey, properAssertMethod) + .Add(CodeFixModeKey, CodeFixModeRemoveArgument); + + if (codeFixShouldAddCast) + { + properties = properties.Add(NeedsNullableBooleanCastKey, null); + } + context.ReportDiagnostic(context.Operation.CreateDiagnostic( Rule, - shouldUseIsTrue ? "IsTrue" : "IsFalse", + additionalLocations: ImmutableArray.Create(expectedArgument.Syntax.GetLocation(), actualArgumentValue?.Syntax.GetLocation() ?? Location.None), + properties: properties, + properAssertMethod, isAreEqualInvocation ? "AreEqual" : "AreNotEqual")); } else if (expectedArgument is ILiteralOperation { ConstantValue: { HasValue: true, Value: null } }) { bool shouldUseIsNull = isAreEqualInvocation; + // Here, the codefix will want to switch something like Assert.AreEqual(null, x) with Assert.IsNull(x) + // This is the "remove argument" mode. + // The message is: Use 'Assert.{0}' instead of 'Assert.{1}'. + string properAssertMethod = shouldUseIsNull ? "IsNull" : "IsNotNull"; context.ReportDiagnostic(context.Operation.CreateDiagnostic( Rule, - shouldUseIsNull ? "IsNull" : "IsNotNull", + additionalLocations: ImmutableArray.Create(expectedArgument.Syntax.GetLocation()), + properties: ImmutableDictionary.Empty + .Add(ProperAssertMethodNameKey, properAssertMethod) + .Add(CodeFixModeKey, CodeFixModeRemoveArgument), properAssertMethod, isAreEqualInvocation ? "AreEqual" : "AreNotEqual")); } } @@ -230,6 +393,9 @@ private static void AnalyzeAreEqualOrAreNotEqualInvocation(OperationAnalysisCont private static bool TryGetFirstArgumentValue(IInvocationOperation operation, [NotNullWhen(true)] out IOperation? argumentValue) => TryGetArgumentValueForParameterOrdinal(operation, 0, out argumentValue); + private static bool TryGetSecondArgumentValue(IInvocationOperation operation, [NotNullWhen(true)] out IOperation? argumentValue) + => TryGetArgumentValueForParameterOrdinal(operation, 1, out argumentValue); + private static bool TryGetArgumentValueForParameterOrdinal(IInvocationOperation operation, int ordinal, [NotNullWhen(true)] out IOperation? argumentValue) { argumentValue = operation.Arguments.FirstOrDefault(arg => arg.Parameter?.Ordinal == ordinal)?.Value?.WalkDownConversion(); diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs index a1238fd7a2..61c1187523 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs @@ -3,7 +3,7 @@ using VerifyCS = MSTest.Analyzers.Test.CSharpCodeFixVerifier< MSTest.Analyzers.UseProperAssertMethodsAnalyzer, - Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + MSTest.Analyzers.UseProperAssertMethodsFixer>; namespace MSTest.Analyzers.Test; @@ -28,10 +28,26 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsNull(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNull' instead of 'Assert.IsTrue' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsNull", "IsTrue")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNull", "IsTrue"), + fixedCode); } public async Task WhenAssertIsTrueWithIsNullArgument() @@ -51,10 +67,26 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsNull(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNull' instead of 'Assert.IsTrue' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsNull", "IsTrue")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNull", "IsTrue"), + fixedCode); } public async Task WhenAssertIsTrueWithNotEqualsNullArgument() @@ -74,10 +106,26 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsNotNull(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNotNull' instead of 'Assert.IsTrue' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsNotNull", "IsTrue")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNotNull", "IsTrue"), + fixedCode); } public async Task WhenAssertIsTrueWithIsNotNullArgument() @@ -97,10 +145,26 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsNotNull(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNotNull' instead of 'Assert.IsTrue' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsNotNull", "IsTrue")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNotNull", "IsTrue"), + fixedCode); } public async Task WhenAssertIsFalseWithEqualsNullArgument() @@ -120,10 +184,26 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsNotNull(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNotNull' instead of 'Assert.IsFalse' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsNotNull", "IsFalse")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNotNull", "IsFalse"), + fixedCode); } public async Task WhenAssertIsFalseWithIsNullArgument() @@ -143,10 +223,26 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsNotNull(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNotNull' instead of 'Assert.IsFalse' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsNotNull", "IsFalse")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNotNull", "IsFalse"), + fixedCode); } public async Task WhenAssertIsFalseWithNotEqualsNullArgument() @@ -166,10 +262,26 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsNull(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNull' instead of 'Assert.IsFalse' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsNull", "IsFalse")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNull", "IsFalse"), + fixedCode); } public async Task WhenAssertIsFalseWithIsNotNullArgument() @@ -189,10 +301,26 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsNull(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNull' instead of 'Assert.IsFalse' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsNull", "IsFalse")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNull", "IsFalse"), + fixedCode); } public async Task WhenAssertIsTrueAndArgumentIsEquality() @@ -213,10 +341,27 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + object y = new object(); + Assert.AreEqual(y, x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(11,9): info MSTEST0037: Use 'Assert.AreEqual' instead of 'Assert.IsTrue' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("AreEqual", "IsTrue")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("AreEqual", "IsTrue"), + fixedCode); } public async Task WhenAssertIsTrueAndArgumentIsInequality() @@ -237,10 +382,27 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + object y = new object(); + Assert.AreNotEqual(y, x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(11,9): info MSTEST0037: Use 'Assert.AreNotEqual' instead of 'Assert.IsTrue' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("AreNotEqual", "IsTrue")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("AreNotEqual", "IsTrue"), + fixedCode); } public async Task WhenAssertIsFalseAndArgumentIsEquality() @@ -261,10 +423,27 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + object y = new object(); + Assert.AreNotEqual(y, x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(11,9): info MSTEST0037: Use 'Assert.AreNotEqual' instead of 'Assert.IsFalse' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("AreNotEqual", "IsFalse")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("AreNotEqual", "IsFalse"), + fixedCode); } public async Task WhenAssertIsFalseAndArgumentIsInequality() @@ -285,10 +464,27 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + object y = new object(); + Assert.AreEqual(y, x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(11,9): info MSTEST0037: Use 'Assert.AreEqual' instead of 'Assert.IsFalse' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("AreEqual", "IsFalse")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("AreEqual", "IsFalse"), + fixedCode); } public async Task WhenAssertAreEqualAndExpectedIsNull() @@ -308,10 +504,26 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsNull(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNull' instead of 'Assert.AreEqual' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsNull", "AreEqual")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNull", "AreEqual"), + fixedCode); } public async Task WhenAssertAreNotEqualAndExpectedIsNull() @@ -331,10 +543,26 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsNotNull(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNotNull' instead of 'Assert.AreNotEqual' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsNotNull", "AreNotEqual")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNotNull", "AreNotEqual"), + fixedCode); } public async Task WhenAssertAreEqualAndExpectedIsTrue() @@ -354,10 +582,153 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsTrue((bool?)x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( + code, + // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsTrue' instead of 'Assert.AreEqual' + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsTrue", "AreEqual"), + fixedCode); + } + + public async Task WhenAssertAreEqualAndExpectedIsTrue_CastNotAddedWhenTypeIsBool() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + bool x = false; + {|#0:Assert.AreEqual(true, x)|}; + } + } + """; + + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + bool x = false; + Assert.IsTrue(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsTrue' instead of 'Assert.AreEqual' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsTrue", "AreEqual")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsTrue", "AreEqual"), + fixedCode); + } + + public async Task WhenAssertAreEqualAndExpectedIsTrue_CastNotAddedWhenTypeIsNullableBool() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + bool? x = false; + {|#0:Assert.AreEqual(true, x)|}; + } + } + """; + + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + bool? x = false; + Assert.IsTrue(x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( + code, + // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsTrue' instead of 'Assert.AreEqual' + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsTrue", "AreEqual"), + fixedCode); + } + + public async Task WhenAssertAreEqualAndExpectedIsTrue_CastShouldBeAddedWithParentheses() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + {|#0:Assert.AreEqual(true, new C() + new C())|}; + } + } + + public class C + { + public static object operator +(C c1, C c2) + => true; + } + """; + + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + Assert.IsTrue((bool?)(new C() + new C())); + } + } + + public class C + { + public static object operator +(C c1, C c2) + => true; + } + """; + + await VerifyCS.VerifyCodeFixAsync( + code, + // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsTrue' instead of 'Assert.AreEqual' + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsTrue", "AreEqual"), + fixedCode); } public async Task WhenAssertAreNotEqualAndExpectedIsTrue() @@ -372,6 +743,9 @@ public class MyTestClass public void MyTestMethod() { object x = new object(); + // Note: Assert.IsFalse(x) has different semantics. So no diagnostic. + // We currently don't produce a diagnostic even if the type of 'x' is boolean. + // But we could special case that. Assert.AreNotEqual(true, x); } } @@ -397,10 +771,26 @@ public void MyTestMethod() } """; - await VerifyCS.VerifyAnalyzerAsync( + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + object x = new object(); + Assert.IsFalse((bool?)x); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync( code, // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsFalse' instead of 'Assert.AreEqual' - VerifyCS.Diagnostic().WithLocation(0).WithArguments("IsFalse", "AreEqual")); + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsFalse", "AreEqual"), + fixedCode); } public async Task WhenAssertAreNotEqualAndExpectedIsFalse() @@ -415,6 +805,9 @@ public class MyTestClass public void MyTestMethod() { object x = new object(); + // Note: Assert.IsTrue(x) has different semantics. So no diagnostic. + // We currently don't produce a diagnostic even if the type of 'x' is boolean. + // But we could special case that. Assert.AreNotEqual(false, x); } } diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2.cs index 54e1de1980..7d98b387cf 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2.cs @@ -19,6 +19,10 @@ public static partial class CSharpCodeFixVerifier public static DiagnosticResult Diagnostic() => CSharpCodeFixVerifier.Diagnostic(); + /// + public static DiagnosticResult DiagnosticIgnoringAdditionalLocations() + => CSharpCodeFixVerifier.Diagnostic().WithOptions(DiagnosticOptions.IgnoreAdditionalLocations); + /// public static DiagnosticResult Diagnostic(string diagnosticId) => CSharpCodeFixVerifier.Diagnostic(diagnosticId); From cb4a08d6b3846c38a9ab9a59e34c88ad0ab23db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 2 Dec 2024 16:05:12 +0100 Subject: [PATCH 040/273] Use dotnet-coverage 17.13.0 (#4211) --- .config/dotnet-tools.json | 4 ++-- eng/CodeCoverage.proj | 5 ----- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 4292ac645e..e358ff55e2 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,11 +3,11 @@ "isRoot": true, "tools": { "dotnet-coverage": { - "version": "17.12.6", + "version": "17.13.0", "commands": [ "dotnet-coverage" ], "rollForward": false } } -} +} \ No newline at end of file diff --git a/eng/CodeCoverage.proj b/eng/CodeCoverage.proj index 72cc55e30c..c336517d96 100644 --- a/eng/CodeCoverage.proj +++ b/eng/CodeCoverage.proj @@ -31,11 +31,6 @@ - - - - - From b4e40bc4d1a502d244d0b6bf503ec980eb44769d Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 2 Dec 2024 16:27:23 +0100 Subject: [PATCH 041/273] Remove VB from `NonNullableReferenceNotInitializedSuppressor` (#4210) --- .../NonNullableReferenceNotInitializedSuppressor.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Analyzers/MSTest.Analyzers/NonNullableReferenceNotInitializedSuppressor.cs b/src/Analyzers/MSTest.Analyzers/NonNullableReferenceNotInitializedSuppressor.cs index edaaf60a89..e895647dbc 100644 --- a/src/Analyzers/MSTest.Analyzers/NonNullableReferenceNotInitializedSuppressor.cs +++ b/src/Analyzers/MSTest.Analyzers/NonNullableReferenceNotInitializedSuppressor.cs @@ -15,7 +15,9 @@ namespace MSTest.Analyzers; /// /// MSTEST0028: . /// -[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] +#pragma warning disable RS1004 // Recommend adding language support to diagnostic analyzer - This suppressor is not valid for VB +[DiagnosticAnalyzer(LanguageNames.CSharp)] +#pragma warning restore RS1004 // Recommend adding language support to diagnostic analyzer public sealed class NonNullableReferenceNotInitializedSuppressor : DiagnosticSuppressor { // CS8618: Non-nullable variable must contain a non-null value when exiting constructor. Consider declaring it as nullable. From 70f973c972ae558b96a75a68f1109e4c3c907862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 2 Dec 2024 16:28:20 +0100 Subject: [PATCH 042/273] Ensure all analyzers we consume are previews (#4214) --- eng/Analyzers.props | 2 +- src/Analyzers/MSTest.Analyzers/MSTest.Analyzers.csproj | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/eng/Analyzers.props b/eng/Analyzers.props index 15c8273caf..e1bae4dd9e 100644 --- a/eng/Analyzers.props +++ b/eng/Analyzers.props @@ -3,7 +3,7 @@ true - latest-recommended + preview-recommended true diff --git a/src/Analyzers/MSTest.Analyzers/MSTest.Analyzers.csproj b/src/Analyzers/MSTest.Analyzers/MSTest.Analyzers.csproj index b7ded067c4..217d171183 100644 --- a/src/Analyzers/MSTest.Analyzers/MSTest.Analyzers.csproj +++ b/src/Analyzers/MSTest.Analyzers/MSTest.Analyzers.csproj @@ -4,7 +4,6 @@ netstandard2.0 false true - Latest *$(MSBuildProjectFile)* From d685c63f3d67714258f150ce0c8248f30cc3b1ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 2 Dec 2024 20:02:12 +0100 Subject: [PATCH 043/273] Introduce and use warning and error output messages (#4217) --- .../CrashDumpProcessLifetimeHandler.cs | 4 +- .../HangDumpProcessLifetimeHandler.cs | 8 +-- .../TrxDataConsumer.cs | 2 +- .../ObjectModel/MessageLoggerAdapter.cs | 4 +- .../Hosts/TestHostBuilder.cs | 2 +- .../Hosts/TestHostControllersTestHost.cs | 4 +- .../Hosts/ToolsTestHost.cs | 8 +-- .../ErrorMessageOutputDeviceData.cs | 9 ++++ .../FormattedTextOutputDeviceDataBuilder.cs | 16 ------ .../OutputDevice/TerminalOutputDevice.cs | 51 +++++++------------ .../WarningMessageOutputDeviceData.cs | 9 ++++ .../PublicAPI/PublicAPI.Unshipped.txt | 6 +++ .../Requests/TestHostTestFrameworkInvoker.cs | 2 +- .../Services/TestApplicationResult.cs | 2 +- 14 files changed, 61 insertions(+), 66 deletions(-) create mode 100644 src/Platform/Microsoft.Testing.Platform/OutputDevice/ErrorMessageOutputDeviceData.cs delete mode 100644 src/Platform/Microsoft.Testing.Platform/OutputDevice/FormattedTextOutputDeviceDataBuilder.cs create mode 100644 src/Platform/Microsoft.Testing.Platform/OutputDevice/WarningMessageOutputDeviceData.cs diff --git a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs index 9fdcbf8e24..8c92fc9a91 100644 --- a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs +++ b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs @@ -65,7 +65,7 @@ public async Task OnTestHostProcessExitedAsync(ITestHostProcessInformation testH } ApplicationStateGuard.Ensure(_netCoreCrashDumpGeneratorConfiguration.DumpFileNamePattern is not null); - await _outputDisplay.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CrashDumpProcessCrashedDumpFileCreated, testHostProcessInformation.PID))); + await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CrashDumpProcessCrashedDumpFileCreated, testHostProcessInformation.PID))); string expectedDumpFile = _netCoreCrashDumpGeneratorConfiguration.DumpFileNamePattern.Replace("%p", testHostProcessInformation.PID.ToString(CultureInfo.InvariantCulture)); if (File.Exists(expectedDumpFile)) @@ -74,7 +74,7 @@ public async Task OnTestHostProcessExitedAsync(ITestHostProcessInformation testH } else { - await _outputDisplay.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashDumpFile, expectedDumpFile))); + await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CannotFindExpectedCrashDumpFile, expectedDumpFile))); foreach (string dumpFile in Directory.GetFiles(Path.GetDirectoryName(expectedDumpFile)!, "*.dmp")) { await _messageBus.PublishAsync(this, new FileArtifact(new FileInfo(dumpFile), CrashDumpResources.CrashDumpDisplayName, CrashDumpResources.CrashDumpArtifactDescription)); diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs index e09eab94e6..077c7ae384 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs +++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs @@ -325,7 +325,7 @@ private async Task TakeDumpAsync() ApplicationStateGuard.Ensure(_dumpType is not null); await _logger.LogInformationAsync($"Hang dump timeout({_activityTimerValue}) expired."); - await _outputDisplay.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(string.Format(CultureInfo.InvariantCulture, ExtensionResources.HangDumpTimeoutExpired, _activityTimerValue))); + await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, ExtensionResources.HangDumpTimeoutExpired, _activityTimerValue))); string finalDumpFileName = _dumpFileNamePattern.Replace("%p", _testHostProcessInformation.PID.ToString(CultureInfo.InvariantCulture)); finalDumpFileName = Path.Combine(_configuration.GetTestResultDirectory(), finalDumpFileName); @@ -339,11 +339,11 @@ private async Task TakeDumpAsync() using (FileStream fs = File.OpenWrite(hangTestsFileName)) using (StreamWriter sw = new(fs)) { - await _outputDisplay.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(ExtensionResources.RunningTestsWhileDumping)); + await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(ExtensionResources.RunningTestsWhileDumping)); foreach ((string testName, int seconds) in tests.Tests) { await sw.WriteLineAsync($"[{TimeSpan.FromSeconds(seconds)}] {testName}"); - await _outputDisplay.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText($"[{TimeSpan.FromSeconds(seconds)}] {testName}")); + await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData($"[{TimeSpan.FromSeconds(seconds)}] {testName}")); } } @@ -352,7 +352,7 @@ private async Task TakeDumpAsync() await _logger.LogInformationAsync($"Creating dump filename {finalDumpFileName}"); - await _outputDisplay.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(string.Format(CultureInfo.InvariantCulture, ExtensionResources.CreatingDumpFile, finalDumpFileName))); + await _outputDisplay.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, ExtensionResources.CreatingDumpFile, finalDumpFileName))); #if NETCOREAPP DiagnosticsClient diagnosticsClient = new(_testHostProcessInformation.PID); diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxDataConsumer.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxDataConsumer.cs index 2ec8c47815..f7b963c788 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxDataConsumer.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxDataConsumer.cs @@ -230,7 +230,7 @@ public async Task OnTestSessionFinishingAsync(SessionUid sessionUid, Cancellatio { if (!_adapterSupportTrxCapability) { - await _outputDisplay.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateYellowConsoleColorText(string.Format(CultureInfo.InvariantCulture, ExtensionResources.TrxReportFrameworkDoesNotSupportTrxReportCapability, _testFramework.DisplayName, _testFramework.Uid))); + await _outputDisplay.DisplayAsync(this, new WarningMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, ExtensionResources.TrxReportFrameworkDoesNotSupportTrxReportCapability, _testFramework.DisplayName, _testFramework.Uid))); } ApplicationStateGuard.Ensure(_testStartTime is not null); diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/MessageLoggerAdapter.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/MessageLoggerAdapter.cs index 98110bf4bb..68dd0bc29d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/MessageLoggerAdapter.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/MessageLoggerAdapter.cs @@ -53,11 +53,11 @@ public void SendMessage(TestMessageLevel testMessageLevel, string message) break; case TestMessageLevel.Warning: _logger.LogWarning(message); - _outputDevice.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateYellowConsoleColorText(message)).Await(); + _outputDevice.DisplayAsync(this, new WarningMessageOutputDeviceData(message)).Await(); break; case TestMessageLevel.Error: _logger.LogError(message); - _outputDevice.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(message)).Await(); + _outputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(message)).Await(); break; default: throw new NotSupportedException($"Unsupported logging level '{testMessageLevel}'."); diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs index 674335a56c..ff99764694 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs @@ -270,7 +270,7 @@ public async Task BuildAsync( if (!loggingState.CommandLineParseResult.HasTool && !commandLineValidationResult.IsValid) { await DisplayBannerIfEnabledAsync(loggingState, platformOutputDevice, testFrameworkCapabilities); - await platformOutputDevice.DisplayAsync(commandLineHandler, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(commandLineValidationResult.ErrorMessage)); + await platformOutputDevice.DisplayAsync(commandLineHandler, new ErrorMessageOutputDeviceData(commandLineValidationResult.ErrorMessage)); await commandLineHandler.PrintHelpAsync(platformOutputDevice); return new InformativeCommandLineTestHost(ExitCodes.InvalidCommandLine, serviceProvider); } diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs index f88b94fa54..baa794cb23 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs @@ -203,7 +203,7 @@ protected override async Task InternalRunAsync() displayErrorMessageBuilder.AppendLine(CultureInfo.InvariantCulture, $"Provider '{extension.DisplayName}' (UID: {extension.Uid}) failed with error: {errorMessage}"); } - await platformOutputDevice.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(displayErrorMessageBuilder.ToString())); + await platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(displayErrorMessageBuilder.ToString())); await _logger.LogErrorAsync(logErrorMessageBuilder.ToString()); return ExitCodes.InvalidPlatformSetup; } @@ -322,7 +322,7 @@ protected override async Task InternalRunAsync() if (!_testHostGracefullyClosed && !abortRun.IsCancellationRequested) { - await platformOutputDevice.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(string.Format(CultureInfo.InvariantCulture, PlatformResources.TestProcessDidNotExitGracefullyErrorMessage, exitCode))); + await platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, PlatformResources.TestProcessDidNotExitGracefullyErrorMessage, exitCode))); } await _logger.LogInformationAsync($"TestHostControllersTestHost ended with exit code '{exitCode}' (real test host exit code '{testHostProcess.ExitCode}')' in '{consoleRunStarted.Elapsed}'"); diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs index ee472d57fd..d39d047676 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs @@ -64,21 +64,21 @@ public async Task RunAsync() { if (UnknownOptions(out string? unknownOptionsError, tool)) { - await _platformOutputDevice.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(unknownOptionsError)); + await _platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(unknownOptionsError)); console.WriteLine(); return ExitCodes.InvalidCommandLine; } if (ExtensionArgumentArityAreInvalid(out string? arityErrors, tool)) { - await _platformOutputDevice.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(arityErrors)); + await _platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(arityErrors)); return ExitCodes.InvalidCommandLine; } ValidationResult optionsArgumentsValidationResult = await ValidateOptionsArgumentsAsync(tool); if (!optionsArgumentsValidationResult.IsValid) { - await _platformOutputDevice.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(optionsArgumentsValidationResult.ErrorMessage)); + await _platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(optionsArgumentsValidationResult.ErrorMessage)); return ExitCodes.InvalidCommandLine; } @@ -86,7 +86,7 @@ public async Task RunAsync() } } - await _platformOutputDevice.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText($"Tool '{toolNameToRun}' not found in the list of registered tools.")); + await _platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData($"Tool '{toolNameToRun}' not found in the list of registered tools.")); await _commandLineHandler.PrintHelpAsync(_platformOutputDevice); return ExitCodes.InvalidCommandLine; } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/ErrorMessageOutputDeviceData.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/ErrorMessageOutputDeviceData.cs new file mode 100644 index 0000000000..e7b5cc0cb3 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/ErrorMessageOutputDeviceData.cs @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.Testing.Platform.OutputDevice; + +public sealed class ErrorMessageOutputDeviceData(string message) : IOutputDeviceData +{ + public string Message { get; } = message; +} diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/FormattedTextOutputDeviceDataBuilder.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/FormattedTextOutputDeviceDataBuilder.cs deleted file mode 100644 index cb396fb974..0000000000 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/FormattedTextOutputDeviceDataBuilder.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -namespace Microsoft.Testing.Platform.OutputDevice; - -internal static class FormattedTextOutputDeviceDataBuilder -{ - public static FormattedTextOutputDeviceData CreateGreenConsoleColorText(string text) - => new(text) { ForegroundColor = new SystemConsoleColor { ConsoleColor = ConsoleColor.Green } }; - - public static FormattedTextOutputDeviceData CreateRedConsoleColorText(string text) - => new(text) { ForegroundColor = new SystemConsoleColor { ConsoleColor = ConsoleColor.Red } }; - - public static FormattedTextOutputDeviceData CreateYellowConsoleColorText(string text) - => new(text) { ForegroundColor = new SystemConsoleColor { ConsoleColor = ConsoleColor.Yellow } }; -} diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs index a0601b4491..05b5a39fc3 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs @@ -367,43 +367,30 @@ public async Task DisplayAsync(IOutputDeviceDataProducer producer, IOutputDevice { switch (data) { - case FormattedTextOutputDeviceData formattedTextOutputDeviceData: - if (formattedTextOutputDeviceData.ForegroundColor is SystemConsoleColor color) - { - switch (color.ConsoleColor) - { - case ConsoleColor.Red: - _terminalTestReporter.WriteErrorMessage(_assemblyName, _targetFramework, _shortArchitecture, executionId: null, formattedTextOutputDeviceData.Text, formattedTextOutputDeviceData.Padding); - break; - case ConsoleColor.Yellow: - _terminalTestReporter.WriteWarningMessage(_assemblyName, _targetFramework, _shortArchitecture, executionId: null, formattedTextOutputDeviceData.Text, formattedTextOutputDeviceData.Padding); - break; - default: - _terminalTestReporter.WriteMessage(formattedTextOutputDeviceData.Text, color, formattedTextOutputDeviceData.Padding); - break; - } - } - else - { - _terminalTestReporter.WriteMessage(formattedTextOutputDeviceData.Text, padding: formattedTextOutputDeviceData.Padding); - } + case FormattedTextOutputDeviceData formattedTextData: + await LogDebugAsync(formattedTextData.Text); + _terminalTestReporter.WriteMessage(formattedTextData.Text, formattedTextData.ForegroundColor as SystemConsoleColor, formattedTextData.Padding); + break; + case TextOutputDeviceData textData: + await LogDebugAsync(textData.Text); + _terminalTestReporter.WriteMessage(textData.Text); break; - case TextOutputDeviceData textOutputDeviceData: - { - await LogDebugAsync(textOutputDeviceData.Text); - _terminalTestReporter.WriteMessage(textOutputDeviceData.Text); - break; - } + case WarningMessageOutputDeviceData warningData: + await LogDebugAsync(warningData.Message); + _terminalTestReporter.WriteWarningMessage(_assemblyName, _targetFramework, _shortArchitecture, executionId: null, warningData.Message, null); + break; - case ExceptionOutputDeviceData exceptionOutputDeviceData: - { - await LogDebugAsync(exceptionOutputDeviceData.Exception.ToString()); - _terminalTestReporter.WriteErrorMessage(_assemblyName, _targetFramework, _shortArchitecture, executionId: null, exceptionOutputDeviceData.Exception); + case ErrorMessageOutputDeviceData errorData: + await LogDebugAsync(errorData.Message); + _terminalTestReporter.WriteErrorMessage(_assemblyName, _targetFramework, _shortArchitecture, executionId: null, errorData.Message, null); + break; - break; - } + case ExceptionOutputDeviceData exceptionOutputDeviceData: + await LogDebugAsync(exceptionOutputDeviceData.Exception.ToString()); + _terminalTestReporter.WriteErrorMessage(_assemblyName, _targetFramework, _shortArchitecture, executionId: null, exceptionOutputDeviceData.Exception); + break; } } } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/WarningMessageOutputDeviceData.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/WarningMessageOutputDeviceData.cs new file mode 100644 index 0000000000..f4b9ee22cb --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/WarningMessageOutputDeviceData.cs @@ -0,0 +1,9 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.Testing.Platform.OutputDevice; + +public sealed class WarningMessageOutputDeviceData(string message) : IOutputDeviceData +{ + public string Message { get; } = message; +} diff --git a/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt b/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt index 96d3604bb5..3976e688ef 100644 --- a/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt @@ -1,5 +1,11 @@ #nullable enable Microsoft.Testing.Platform.Extensions.Messages.TestMetadataProperty.TestMetadataProperty(string! key) -> void +Microsoft.Testing.Platform.OutputDevice.ErrorMessageOutputDeviceData +Microsoft.Testing.Platform.OutputDevice.ErrorMessageOutputDeviceData.ErrorMessageOutputDeviceData(string! message) -> void +Microsoft.Testing.Platform.OutputDevice.ErrorMessageOutputDeviceData.Message.get -> string! +Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData +Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData.Message.get -> string! +Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData.WarningMessageOutputDeviceData(string! message) -> void [TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty [TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutput.get -> string! [TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutput.init -> void diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs b/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs index b43a13b355..b52d8e99e5 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs @@ -79,7 +79,7 @@ private async Task HandleTestSessionResultAsync(bool isSuccess, string? warningM if (warningMessage is not null) { IOutputDevice outputDisplay = ServiceProvider.GetOutputDevice(); - await outputDisplay.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateYellowConsoleColorText(warningMessage)); + await outputDisplay.DisplayAsync(this, new WarningMessageOutputDeviceData(warningMessage)); } if (!isSuccess) diff --git a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs index e01fad11fe..3304d317de 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs @@ -121,7 +121,7 @@ public async Task SetTestAdapterTestSessionFailureAsync(string errorMessage) { TestAdapterTestSessionFailureErrorMessage = errorMessage; _testAdapterTestSessionFailure = true; - await _outputService.DisplayAsync(this, FormattedTextOutputDeviceDataBuilder.CreateRedConsoleColorText(errorMessage)); + await _outputService.DisplayAsync(this, new ErrorMessageOutputDeviceData(errorMessage)); } public Statistics GetStatistics() From b06fc7261effe6d8c378b3cd6a0dea742c391795 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 3 Dec 2024 09:08:45 +0100 Subject: [PATCH 044/273] Temporary restore `FormattedTextOutputDeviceDataBuilder` (#4220) --- .../FormattedTextOutputDeviceDataBuilder.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/Platform/Microsoft.Testing.Platform/OutputDevice/FormattedTextOutputDeviceDataBuilder.cs diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/FormattedTextOutputDeviceDataBuilder.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/FormattedTextOutputDeviceDataBuilder.cs new file mode 100644 index 0000000000..0741b46c0d --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/FormattedTextOutputDeviceDataBuilder.cs @@ -0,0 +1,20 @@ +// 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.ComponentModel; + +namespace Microsoft.Testing.Platform.OutputDevice; + +[EditorBrowsable(EditorBrowsableState.Never)] +[Obsolete("Do not use this class. This is present temporarily for internal usages (in Retry extension) and will be removed after fixing the internal usages", error: true)] +internal static class FormattedTextOutputDeviceDataBuilder +{ + public static FormattedTextOutputDeviceData CreateGreenConsoleColorText(string text) + => new(text) { ForegroundColor = new SystemConsoleColor() { ConsoleColor = ConsoleColor.Green } }; + + public static FormattedTextOutputDeviceData CreateRedConsoleColorText(string text) + => new(text) { ForegroundColor = new SystemConsoleColor() { ConsoleColor = ConsoleColor.Red } }; + + public static FormattedTextOutputDeviceData CreateYellowConsoleColorText(string text) + => new(text) { ForegroundColor = new SystemConsoleColor() { ConsoleColor = ConsoleColor.Yellow } }; +} From a4d8395aaae898d8faede287b625ea91d07c4895 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 09:08:57 +0100 Subject: [PATCH 045/273] [main] Bump dotnet-coverage from 17.13.0 to 17.13.1 (#4219) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .config/dotnet-tools.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index e358ff55e2..29d00e9d35 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-coverage": { - "version": "17.13.0", + "version": "17.13.1", "commands": [ "dotnet-coverage" ], From 0a3816b2bad6b20144c14a0f0103f67ed6519337 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 3 Dec 2024 15:50:14 +0100 Subject: [PATCH 046/273] [main] Update dependencies from devdiv/DevDiv/vs-code-coverage (#4222) Co-authored-by: dotnet-maestro[bot] --- .config/dotnet-tools.json | 2 +- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 29d00e9d35..be6c1fa878 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,4 +10,4 @@ "rollForward": false } } -} \ No newline at end of file +} diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 8701a438f8..36af61a05d 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,9 +13,9 @@ https://github.com/dotnet/arcade e8de3415124309210e4cbd0105e4a9da8dc01696 - + https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage - 895c1757454b3f0b493cf9049facf983802985a0 + a657d717d57fcaf8f3ab3330b168f420e92b7a42 https://github.com/microsoft/testanywhere diff --git a/eng/Versions.props b/eng/Versions.props index a31bce1d05..d922796051 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,7 +8,7 @@ 10.0.0-beta.24578.2 - 17.13.0-preview.24579.4 + 17.13.1-preview.24603.1 1.5.0-preview.24576.1 1.0.0-alpha.24473.2 From 61c098dfbe428776cace4d789d0f86304155ef87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 3 Dec 2024 15:51:08 +0100 Subject: [PATCH 047/273] Obsolete public types that should not be public (#4208) Co-authored-by: Youssef Victor --- .editorconfig | 3 + TestFx.sln | 7 ++ src/Adapter/MSTest.TestAdapter/Constants.cs | 2 + .../Execution/LogMessageListener.cs | 5 ++ .../Execution/TestAssemblyInfo.cs | 5 ++ .../Execution/TestClassInfo.cs | 5 ++ .../Execution/TestExecutionManager.cs | 5 ++ .../Execution/TestMethodInfo.cs | 5 ++ .../Execution/TestRunCancellationToken.cs | 5 ++ .../Extensions/TestResultExtensions.cs | 5 ++ .../Extensions/UnitTestOutcomeExtensions.cs | 5 ++ .../MSTest.TestAdapter.csproj | 4 + .../MSTest.TestAdapter/MSTestSettings.cs | 5 ++ .../ObjectModel/TestMethod.cs | 5 ++ .../ObjectModel/UnitTestOutcome.cs | 5 ++ .../ObjectModel/UnitTestResult.cs | 5 ++ .../RunConfigurationSettings.cs | 5 ++ .../VSTestAdapter/MSTestDiscoverer.cs | 5 ++ .../VSTestAdapter/MSTestExecutor.cs | 5 ++ .../AssemblyResolver.cs | 5 ++ .../Constants.cs | 2 + .../Deployment/TestRunDirectories.cs | 5 ++ .../Interfaces/IAdapterTraceLogger.cs | 5 ++ .../Interfaces/IFileOperations.cs | 5 ++ .../Interfaces/IReflectionOperations.cs | 5 ++ .../Interfaces/ISettingsProvider.cs | 5 ++ .../Interfaces/ITestDeployment.cs | 5 ++ .../Interfaces/ITestSource.cs | 5 ++ .../Interfaces/ITestSourceHost.cs | 5 ++ .../Interfaces/IThreadOperations.cs | 5 ++ .../Interfaces/ITraceListener.cs | 5 ++ .../Interfaces/ITraceListenerManager.cs | 5 ++ .../MSTestAdapter.PlatformServices.csproj | 4 + .../RecursiveDirectoryPath.cs | 5 ++ .../Services/FileOperations.cs | 5 ++ .../Services/MSTestAdapterSettings.cs | 5 ++ .../Services/ReflectionOperations.cs | 5 ++ .../Services/SettingsProvider.cs | 5 ++ .../Services/TestContextImplementation.cs | 5 ++ .../Services/TestDataSource.cs | 5 ++ .../Services/TestDeployment.cs | 5 ++ .../Services/TestSource.cs | 5 ++ .../Services/TestSourceHost.cs | 5 ++ .../Services/ThreadOperations.cs | 5 ++ .../Services/ThreadSafeStringWriter.cs | 5 ++ .../Services/TraceListener.cs | 5 ++ .../Services/TraceListenerManager.cs | 5 ++ .../Services/TraceLogger.cs | 5 ++ .../Utilities/VSInstallationUtilities.cs | 5 ++ .../WellKnownTypeProvider.cs | 3 +- .../MSTest.Internal.Analyzers.csproj | 18 +++++ .../MSTestObsoleteTypesSuppressor.cs | 42 +++++++++++ .../WellKnownTypeNames.cs | 20 +++++ test/.editorconfig | 74 ++++++------------- .../MSTest.IntegrationTests.csproj | 4 + ...rmServices.Desktop.IntegrationTests.csproj | 4 + ...tAdapter.PlatformServices.UnitTests.csproj | 4 + .../MSTestAdapter.UnitTests.csproj | 4 + 58 files changed, 356 insertions(+), 54 deletions(-) create mode 100644 src/Analyzers/MSTest.Internal.Analyzers/MSTest.Internal.Analyzers.csproj create mode 100644 src/Analyzers/MSTest.Internal.Analyzers/MSTestObsoleteTypesSuppressor.cs create mode 100644 src/Analyzers/MSTest.Internal.Analyzers/WellKnownTypeNames.cs diff --git a/.editorconfig b/.editorconfig index e323c80086..be3939f63d 100644 --- a/.editorconfig +++ b/.editorconfig @@ -66,6 +66,9 @@ tab_width = 4 # Do not set end_of_line property, this is causing issues with Linux, # see https://github.com/dotnet/roslyn/issues/55526 +# MSTESTOBS: Type or member is obsolete +dotnet_diagnostic.MSTESTOBS.severity = none + #### .NET Coding Conventions #### ## Organize usings diff --git a/TestFx.sln b/TestFx.sln index c8f431085a..2a974cdced 100644 --- a/TestFx.sln +++ b/TestFx.sln @@ -209,6 +209,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Testing.Platform. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Testing.Extensions.MSBuild", "src\Platform\Microsoft.Testing.Extensions.MSBuild\Microsoft.Testing.Extensions.MSBuild.csproj", "{8CE782A2-7374-4916-9C69-1F87E51A64A9}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSTest.Internal.Analyzers", "src\Analyzers\MSTest.Internal.Analyzers\MSTest.Internal.Analyzers.csproj", "{4A93E1A2-B61E-31B2-33F2-478156A9B5E7}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -483,6 +485,10 @@ Global {8CE782A2-7374-4916-9C69-1F87E51A64A9}.Debug|Any CPU.Build.0 = Debug|Any CPU {8CE782A2-7374-4916-9C69-1F87E51A64A9}.Release|Any CPU.ActiveCfg = Release|Any CPU {8CE782A2-7374-4916-9C69-1F87E51A64A9}.Release|Any CPU.Build.0 = Release|Any CPU + {4A93E1A2-B61E-31B2-33F2-478156A9B5E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4A93E1A2-B61E-31B2-33F2-478156A9B5E7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4A93E1A2-B61E-31B2-33F2-478156A9B5E7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4A93E1A2-B61E-31B2-33F2-478156A9B5E7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -567,6 +573,7 @@ Global {573C617F-6BB2-403A-AD87-E00A7FD537F0} = {BB874DF1-44FE-415A-B634-A6B829107890} {F422398C-72CD-43EA-AC8E-E0DBD08E5563} = {BB874DF1-44FE-415A-B634-A6B829107890} {8CE782A2-7374-4916-9C69-1F87E51A64A9} = {6AEE1440-FDF0-4729-8196-B24D0E333550} + {4A93E1A2-B61E-31B2-33F2-478156A9B5E7} = {E7F15C9C-3928-47AD-8462-64FD29FFCA54} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {31E0F4D5-975A-41CC-933E-545B2201FAF9} diff --git a/src/Adapter/MSTest.TestAdapter/Constants.cs b/src/Adapter/MSTest.TestAdapter/Constants.cs index 057ebb6bfa..f110859dc8 100644 --- a/src/Adapter/MSTest.TestAdapter/Constants.cs +++ b/src/Adapter/MSTest.TestAdapter/Constants.cs @@ -10,6 +10,8 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// internal static class Constants { + internal const string PublicTypeObsoleteMessage = "We will remove or hide this type starting with v4. If you are using this type, reach out to our team on https://github.com/microsoft/testfx."; + /// /// The 3rd level entry (class) name in the hierarchy array. /// diff --git a/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs b/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs index d4c34388a2..41df65ebee 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs @@ -14,6 +14,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// Listens for log messages and Debug.WriteLine /// Note that this class is not thread-safe and thus should only be used when unit tests are being run serially. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class LogMessageListener : IDisposable { private static readonly Lock TraceLock = new(); diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs index 3535d58cc0..c89657609d 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs @@ -18,6 +18,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// Defines TestAssembly Info object. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TestAssemblyInfo { private readonly Lock _assemblyInfoExecuteSyncObject = new(); diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index a4a22576c2..07423c3608 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -20,6 +20,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// Defines the TestClassInfo object. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TestClassInfo { private readonly Lock _testClassExecuteSyncObject = new(); diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs index 928465b7f7..f3a8913b9d 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs @@ -19,6 +19,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// Class responsible for execution of tests at assembly level and sending tests via framework handle. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TestExecutionManager { /// diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs index 5457c046d8..b6d05a1b25 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs @@ -21,6 +21,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// Defines the TestMethod Info object. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TestMethodInfo : ITestMethod { /// diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs index 14ca69684a..2bf81e04f7 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs @@ -8,6 +8,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// /// Cancellation token supporting cancellation of a test run. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TestRunCancellationToken { /// diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs index be7f3963cd..301984dbb1 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs @@ -7,6 +7,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public static class TestResultExtensions { /// diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs index 3ca83f6648..0e05bd2bb0 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs @@ -7,6 +7,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public static class UnitTestOutcomeExtensions { /// diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj index ccb26d8c0f..61b5a1173c 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj @@ -49,6 +49,10 @@ + + Analyzer + false + diff --git a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs index 6aa0c4c10f..2574a2b81d 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs +++ b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs @@ -20,6 +20,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// Adapter Settings for the run. /// [Serializable] +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class MSTestSettings { /// diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs index 9da709697a..e245e2bc3c 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs @@ -16,6 +16,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; /// /// TestMethod contains information about a unit test method that needs to be executed. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif [Serializable] public sealed class TestMethod : ITestMethod { diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestOutcome.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestOutcome.cs index ec561946dd..a519c454eb 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestOutcome.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestOutcome.cs @@ -6,6 +6,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; /// /// Outcome of a test. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public enum UnitTestOutcome : int { /// diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs index 42113cd838..38975edd70 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs @@ -14,6 +14,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; [Serializable] [DebuggerDisplay("{DisplayName} ({Outcome})")] +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class UnitTestResult { /// diff --git a/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs b/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs index ff48f1945e..2f6613ffe4 100644 --- a/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs +++ b/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs @@ -13,6 +13,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class RunConfigurationSettings { /// diff --git a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs index 47a01bf4f6..3f3a15d2fb 100644 --- a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs +++ b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs @@ -16,6 +16,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; [FileExtension(".appx")] [FileExtension(".dll")] [FileExtension(".exe")] +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class MSTestDiscoverer : ITestDiscoverer { /// diff --git a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs index fcad29af3a..ecdf3e498a 100644 --- a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs +++ b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs @@ -15,6 +15,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// Contains the execution logic for this adapter. /// [ExtensionUri(Constants.ExecutorUriString)] +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class MSTestExecutor : ITestExecutor { private readonly CancellationToken _cancellationToken; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs index 36b4c02954..ba2917c1eb 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs @@ -21,6 +21,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// Since we don't want to put our assemblies to GAC and they are not in tests dir, we use custom way to resolve them. /// #if NETFRAMEWORK +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public #else internal sealed diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Constants.cs b/src/Adapter/MSTestAdapter.PlatformServices/Constants.cs index 1f520a471d..e9207ebaab 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Constants.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Constants.cs @@ -39,4 +39,6 @@ internal class Constants #endif private const string DeploymentItemsLabel = "DeploymentItems"; + + internal const string PublicTypeObsoleteMessage = "We will remove or hide this type starting with v4. If you are using this type, reach out to our team on https://github.com/microsoft/testfx."; } diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs index d2c4ae94cd..ecb0a273d8 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs @@ -10,6 +10,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Dep /// /// The test run directories. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif [Serializable] public class TestRunDirectories { diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IAdapterTraceLogger.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IAdapterTraceLogger.cs index fe24dca9b5..14d14d6337 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IAdapterTraceLogger.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IAdapterTraceLogger.cs @@ -8,6 +8,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// A service to log any trace messages from the adapter that would be shown in *.TpTrace files. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public interface IAdapterTraceLogger { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs index 206ac6919c..3ae7c05162 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs @@ -8,6 +8,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// This service is responsible for any file based operations. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public interface IFileOperations { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs index 1da84b921c..29a90e3033 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs @@ -9,6 +9,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// This service is responsible for platform specific reflection operations. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public interface IReflectionOperations { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs index dea8101ba8..e0939a3976 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs @@ -8,6 +8,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// To read settings from the runsettings xml for the corresponding platform service. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public interface ISettingsProvider { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs index ea58e010fa..aeeee1826a 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs @@ -11,6 +11,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// The TestDeployment interface. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public interface ITestDeployment { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs index ea3ef22285..3bd96ce786 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs @@ -9,6 +9,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// This platform service is responsible for any data or operations to validate /// the test sources provided to the adapter. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public interface ITestSource { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs index dde72572f4..5f4f73b8bf 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs @@ -8,6 +8,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// A host that loads the test source.This can be in isolation for desktop using an AppDomain or just loading the source in the current context. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public interface ITestSourceHost : IDisposable { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IThreadOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IThreadOperations.cs index 7c35f75628..f03762ff1d 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IThreadOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IThreadOperations.cs @@ -6,6 +6,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// This service is responsible for any thread operations specific to a platform. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public interface IThreadOperations { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListener.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListener.cs index 97f449210c..6bc98aaec5 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListener.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListener.cs @@ -6,6 +6,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// Operations on the TraceListener object that is implemented differently for each platform. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public interface ITraceListener { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListenerManager.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListenerManager.cs index 062ed5c9e2..9dbe78d52e 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListenerManager.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListenerManager.cs @@ -7,6 +7,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// Manager to perform operations on the TraceListener object passed as parameter. /// These operations are implemented differently for each platform service. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public interface ITraceListenerManager { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/MSTestAdapter.PlatformServices.csproj b/src/Adapter/MSTestAdapter.PlatformServices/MSTestAdapter.PlatformServices.csproj index 7752d8d63a..4be35846e8 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/MSTestAdapter.PlatformServices.csproj +++ b/src/Adapter/MSTestAdapter.PlatformServices/MSTestAdapter.PlatformServices.csproj @@ -32,6 +32,10 @@ + + Analyzer + false + diff --git a/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs b/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs index 3162c23030..7aaea3d496 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs @@ -20,6 +20,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// For each directory we need to have two info 1) path 2) includeSubDirectories. /// [Serializable] +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1603:DocumentationMustContainValidXml", Justification = "Reviewed. Suppression is ok here.")] public class RecursiveDirectoryPath : MarshalByRefObject { diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs index 82064d7c5b..04475207db 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs @@ -18,6 +18,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// The file operations. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class FileOperations : IFileOperations { private readonly ConcurrentDictionary _assemblyCache = new(); diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs index 9ceb4b58d9..0949dec0f6 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs @@ -12,6 +12,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class MSTestAdapterSettings { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs index 4dfbe0b35f..2bb0157c76 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs @@ -14,6 +14,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// This service is responsible for platform specific reflection operations. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class ReflectionOperations : IReflectionOperations { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs index 2846da17e6..baf259c3dc 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs @@ -14,6 +14,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// Class to read settings from the runsettings xml for the desktop. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class MSTestSettingsProvider : ISettingsProvider { #if !WINDOWS_UWP diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs index b67fa921c0..2a2823bd5e 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs @@ -20,6 +20,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// The virtual string properties of the TestContext are retrieved from the property dictionary /// like GetProperty<string>("TestName") or GetProperty<string>("FullyQualifiedTestClassName"). /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TestContextImplementation : TestContext, ITestContext { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs index 04b6218b9e..24dbc96867 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs @@ -26,6 +26,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// the tests since it can only be found at the test output directory. DO NOT call into this platform service outside of the appdomain context if you do not want to hit /// a ReflectionTypeLoadException. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TestDataSource : ITestDataSource { #if NETFRAMEWORK diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs index 74c88e6d38..7fe557a194 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs @@ -25,6 +25,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// The test deployment. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TestDeployment : ITestDeployment { #if !WINDOWS_UWP diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs index 9261cdb897..13d03b2955 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs @@ -17,6 +17,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// This platform service is responsible for any data or operations to validate /// the test sources provided to the adapter. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TestSource : ITestSource { #if WINDOWS_UWP || WIN_UI diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs index 482c4f9b94..25e8a8e3ce 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs @@ -23,6 +23,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// A host that loads the test source. This can be in isolation for desktop using an AppDomain or just loading the source in the current context. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TestSourceHost : ITestSourceHost { #if !WINDOWS_UWP diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs index bea00ebe35..c67aa5a18e 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs @@ -12,6 +12,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// This service is responsible for any Async operations specific to a platform. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class ThreadOperations : IThreadOperations { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs index edebecf31b..32d35b7e18 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs @@ -8,6 +8,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// AsyncContext aware, thread safe string writer that allows output writes from different threads to end up in the same async local context. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class ThreadSafeStringWriter : StringWriter { #if DEBUG diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs index 36ec699eed..d63c8e0363 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs @@ -16,6 +16,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// The virtual operations of the TraceListener are implemented here /// like Close(), Dispose() etc. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TraceListenerWrapper : #if !WINDOWS_UWP && !WIN_UI TextWriterTraceListener, diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs index 9aff10dc67..4c06279271 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs @@ -13,6 +13,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// Internal implementation of TraceListenerManager exposed to the user. /// Responsible for performing Add(), Remove(), Close(), Dispose() operations on traceListener object. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class TraceListenerManager : ITraceListenerManager { #if !WINDOWS_UWP && !WIN_UI diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceLogger.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceLogger.cs index 73e691f00c..44baf76b71 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceLogger.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceLogger.cs @@ -9,6 +9,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// A service to log any trace messages from the adapter that would be shown in *.TpTrace files. /// +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public class AdapterTraceLogger : IAdapterTraceLogger { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs index 1775e61d6c..d2ea62d3d0 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs @@ -10,6 +10,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; +#if NET6_0_OR_GREATER +[Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] +#else +[Obsolete(Constants.PublicTypeObsoleteMessage)] +#endif public static class VSInstallationUtilities { /// diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs index c0d16fbee5..13290e5703 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs @@ -178,7 +178,8 @@ private bool TryGetOrCreateTypeByMetadataNameSlow( /// Predicate to check the 's type argument. /// True if is a with its /// type argument satisfying , false otherwise. - internal bool IsTaskOfType([NotNullWhen(returnValue: true)] ITypeSymbol? typeSymbol, Func typeArgumentPredicate) => typeSymbol != null + internal bool IsTaskOfType([NotNullWhen(returnValue: true)] ITypeSymbol? typeSymbol, Func typeArgumentPredicate) + => typeSymbol != null && typeSymbol.OriginalDefinition != null && SymbolEqualityComparer.Default.Equals(typeSymbol.OriginalDefinition, GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingTasksTask1)) diff --git a/src/Analyzers/MSTest.Internal.Analyzers/MSTest.Internal.Analyzers.csproj b/src/Analyzers/MSTest.Internal.Analyzers/MSTest.Internal.Analyzers.csproj new file mode 100644 index 0000000000..d2e12ea51d --- /dev/null +++ b/src/Analyzers/MSTest.Internal.Analyzers/MSTest.Internal.Analyzers.csproj @@ -0,0 +1,18 @@ + + + + netstandard2.0 + true + false + false + + + *$(MSBuildProjectFile)* + + + + + + + + diff --git a/src/Analyzers/MSTest.Internal.Analyzers/MSTestObsoleteTypesSuppressor.cs b/src/Analyzers/MSTest.Internal.Analyzers/MSTestObsoleteTypesSuppressor.cs new file mode 100644 index 0000000000..2474a61e66 --- /dev/null +++ b/src/Analyzers/MSTest.Internal.Analyzers/MSTestObsoleteTypesSuppressor.cs @@ -0,0 +1,42 @@ +// 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 System.Globalization; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; + +namespace MSTest.Internal.Analyzers; + +/// +/// MSTESTINT1: Suppress type is obsolete for known MSTest types. +/// +#pragma warning disable RS1004 // Recommend adding language support to diagnostic analyzer - For internal use only. We don't have VB code. +[DiagnosticAnalyzer(LanguageNames.CSharp)] +#pragma warning restore RS1004 // Recommend adding language support to diagnostic analyzer +public sealed class MSTestObsoleteTypesSuppressor : DiagnosticSuppressor +{ + // CS0618: Member is obsolete. + // https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs0618 + private const string SuppressedDiagnosticId = "CS0618"; + + internal static readonly SuppressionDescriptor Rule = + new("MSTESTINT1", SuppressedDiagnosticId, "Type is obsolete only so we can change accessibility"); + + public override ImmutableArray SupportedSuppressions { get; } = ImmutableArray.Create(Rule); + + public override void ReportSuppressions(SuppressionAnalysisContext context) + { + foreach (Diagnostic diagnostic in context.ReportedDiagnostics) + { + // It's very tedious to list all types that we obsoleted. We know for sure that this message is + // for types that can be used internally but not externally. + const string PublicTypeObsoleteMessage = "We will remove or hide this type starting with v4. If you are using this type, reach out to our team on https://github.com/microsoft/testfx."; + if (diagnostic.GetMessage(CultureInfo.InvariantCulture).Contains(PublicTypeObsoleteMessage)) + { + context.ReportSuppression(Suppression.Create(Rule, diagnostic)); + } + } + } +} diff --git a/src/Analyzers/MSTest.Internal.Analyzers/WellKnownTypeNames.cs b/src/Analyzers/MSTest.Internal.Analyzers/WellKnownTypeNames.cs new file mode 100644 index 0000000000..9ef8eb536e --- /dev/null +++ b/src/Analyzers/MSTest.Internal.Analyzers/WellKnownTypeNames.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace MSTest.Analyzers.Helpers; + +internal static class WellKnownTypeNames +{ + public const string System = "System"; + public const string SystemCollectionsGenericIEnumerable1 = "System.Collections.Generic.IEnumerable`1"; + public const string SystemDescriptionAttribute = "System.ComponentModel.DescriptionAttribute"; + public const string SystemIAsyncDisposable = "System.IAsyncDisposable"; + public const string SystemIDisposable = "System.IDisposable"; + public const string SystemNullable = "System.Nullable`1"; + public const string SystemReflectionMethodInfo = "System.Reflection.MethodInfo"; + public const string SystemRuntimeCompilerServicesITuple = "System.Runtime.CompilerServices.ITuple"; + public const string SystemThreadingTasksTask = "System.Threading.Tasks.Task"; + public const string SystemThreadingTasksTask1 = "System.Threading.Tasks.Task`1"; + public const string SystemThreadingTasksValueTask = "System.Threading.Tasks.ValueTask"; + public const string SystemThreadingTasksValueTask1 = "System.Threading.Tasks.ValueTask`1"; +} diff --git a/test/.editorconfig b/test/.editorconfig index d2c074affd..26a155ee3a 100644 --- a/test/.editorconfig +++ b/test/.editorconfig @@ -8,56 +8,24 @@ root = false #### .NET Coding Conventions #### -# VSTHRD200: Use "Async" suffix for async methods -dotnet_diagnostic.VSTHRD200.severity = suggestion - -# SA1118: Parameter should not span multiple lines -dotnet_diagnostic.SA1118.severity = suggestion - -# SA1201: Elements should appear in the correct order -dotnet_diagnostic.SA1201.severity = suggestion - -# SA1203: Constants should appear before fields -dotnet_diagnostic.SA1203.severity = suggestion - -# SA1311: Static readonly fields should begin with upper-case letter -dotnet_diagnostic.SA1311.severity = none - -# SA1602: Enumeration items should be documented -dotnet_diagnostic.SA1602.severity = none - -# CA1000: Do not declare static members on generic types -dotnet_diagnostic.CA1000.severity = suggestion - -# CA1018: Mark attributes with AttributeUsageAttribute -dotnet_diagnostic.CA1018.severity = none - -# CA1707: Identifiers should not contain underscores -dotnet_diagnostic.CA1707.severity = none - -# CA1711: Identifiers should not have incorrect suffix -dotnet_diagnostic.CA1711.severity = none - -# CA1816: Dispose methods should call SuppressFinalize -dotnet_diagnostic.CA1816.severity = none - -# CA1822: Mark members as static -dotnet_diagnostic.CA1822.severity = none - -# CA1852: Type can be sealed -dotnet_diagnostic.CA1852.severity = none - -# CA1859: Change return type to be more specific -dotnet_diagnostic.CA1859.severity = none - -# CA1861: Avoid constant arrays as arguments -dotnet_diagnostic.CA1861.severity = none - -# CA2201: Do not raise reserved exception types -dotnet_diagnostic.CA2201.severity = none - -# CA3075: Insecure DTD processing in XML -dotnet_diagnostic.CA3075.severity = none - -# IDE0060: Remove unused parameter -dotnet_diagnostic.IDE0060.severity = none +dotnet_diagnostic.VSTHRD200.severity = suggestion # VSTHRD200: Use "Async" suffix for async methods + +dotnet_diagnostic.SA1118.severity = suggestion # SA1118: Parameter should not span multiple lines +dotnet_diagnostic.SA1201.severity = suggestion # SA1201: Elements should appear in the correct order +dotnet_diagnostic.SA1203.severity = suggestion # SA1203: Constants should appear before fields +dotnet_diagnostic.SA1311.severity = none # SA1311: Static readonly fields should begin with upper-case letter +dotnet_diagnostic.SA1602.severity = none # SA1602: Enumeration items should be documented + +dotnet_diagnostic.CA1000.severity = suggestion # CA1000: Do not declare static members on generic types +dotnet_diagnostic.CA1018.severity = none # CA1018: Mark attributes with AttributeUsageAttribute +dotnet_diagnostic.CA1707.severity = none # CA1707: Identifiers should not contain underscores +dotnet_diagnostic.CA1711.severity = none # CA1711: Identifiers should not have incorrect suffix +dotnet_diagnostic.CA1816.severity = none # CA1816: Dispose methods should call SuppressFinalize +dotnet_diagnostic.CA1822.severity = none # CA1822: Mark members as static +dotnet_diagnostic.CA1852.severity = none # CA1852: Type can be sealed +dotnet_diagnostic.CA1859.severity = none # CA1859: Change return type to be more specific +dotnet_diagnostic.CA1861.severity = none # CA1861: Avoid constant arrays as arguments +dotnet_diagnostic.CA2201.severity = none # CA2201: Do not raise reserved exception types +dotnet_diagnostic.CA3075.severity = none # CA3075: Insecure DTD processing in XML + +dotnet_diagnostic.IDE0060.severity = none # IDE0060: Remove unused parameter diff --git a/test/IntegrationTests/MSTest.IntegrationTests/MSTest.IntegrationTests.csproj b/test/IntegrationTests/MSTest.IntegrationTests/MSTest.IntegrationTests.csproj index 43e0e78f28..e2c766f3d8 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/MSTest.IntegrationTests.csproj +++ b/test/IntegrationTests/MSTest.IntegrationTests/MSTest.IntegrationTests.csproj @@ -20,6 +20,10 @@ + + Analyzer + false + diff --git a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/PlatformServices.Desktop.IntegrationTests.csproj b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/PlatformServices.Desktop.IntegrationTests.csproj index 6a81eaca13..be8d574df6 100644 --- a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/PlatformServices.Desktop.IntegrationTests.csproj +++ b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/PlatformServices.Desktop.IntegrationTests.csproj @@ -8,6 +8,10 @@ + + Analyzer + false + diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/MSTestAdapter.PlatformServices.UnitTests.csproj b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/MSTestAdapter.PlatformServices.UnitTests.csproj index 576e802897..b6f427823c 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/MSTestAdapter.PlatformServices.UnitTests.csproj +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/MSTestAdapter.PlatformServices.UnitTests.csproj @@ -25,6 +25,10 @@ + + Analyzer + false + diff --git a/test/UnitTests/MSTestAdapter.UnitTests/MSTestAdapter.UnitTests.csproj b/test/UnitTests/MSTestAdapter.UnitTests/MSTestAdapter.UnitTests.csproj index 46dc781e59..41e859407b 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/MSTestAdapter.UnitTests.csproj +++ b/test/UnitTests/MSTestAdapter.UnitTests/MSTestAdapter.UnitTests.csproj @@ -22,6 +22,10 @@ + + Analyzer + false + From 13fe4ef01afb8fde1790843ae98d34cd82d76224 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 3 Dec 2024 07:05:52 -0800 Subject: [PATCH 048/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2594144 --- .../Resources/xlf/MSBuildResources.de.xlf | 6 +++--- .../Resources/xlf/MSBuildResources.ko.xlf | 6 +++--- .../Resources/xlf/PlatformResources.de.xlf | 6 +++--- .../Resources/xlf/PlatformResources.es.xlf | 6 +++--- .../Resources/xlf/PlatformResources.ko.xlf | 6 +++--- .../Resources/xlf/PlatformResources.pl.xlf | 6 +++--- .../Resources/xlf/PlatformResources.zh-Hant.xlf | 6 +++--- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.de.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.de.xlf index 57afa3c6cc..9df371921e 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.de.xlf @@ -34,11 +34,11 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + Der Host „{0}“ für die Architektur „{1}“ wurde nicht gefunden. -You can resolve the problem by installing the '{1}' .NET. +Sie können das Problem beheben, indem Sie das .NET „{1}“ installieren. -The specified framework can be found at: +Das angegebene Framework finden Sie unter: - https://aka.ms/dotnet-download diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ko.xlf index e55406eb5a..bcf296a8bf 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.ko.xlf @@ -34,11 +34,11 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + '{1}' 아키텍처에 대한 '{0}' 호스트를 찾을 수 없습니다. -You can resolve the problem by installing the '{1}' .NET. +'{1}' .NET을 설치하여 문제를 해결할 수 있습니다. -The specified framework can be found at: +다음 위치에서 지정된 프레임워크를 찾을 수 있습니다. - https://aka.ms/dotnet-download diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index 154d7a643b..4cc60a09ab 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + Die mit „--config-file“ angegebene Konfigurationsdatei „{0}“ wurde nicht gefunden. @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + Gibt eine testconfig.json-Datei an. @@ -522,7 +522,7 @@ Die verfügbaren Werte sind "Trace", "Debug", "Information", "Warning", "Error" Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + Gibt die Mindestanzahl von Tests an, die ausgeführt werden sollen. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index ffc6cc0328..e77b5cb8a2 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + No se ha encontrado el archivo de configuración "{0}" especificado con "--config-file". @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + Especifica un archivo testconfig.json. @@ -522,7 +522,7 @@ Los valores disponibles son 'Seguimiento', 'Depurar', 'Información', 'Advertenc Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + Especifica el número mínimo de pruebas que se espera que se ejecuten. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index 9c15b13c2d..4d044167b3 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + '--config-file'으로 지정된 구성 파일 '{0}' 찾을 수 없습니다. @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + testconfig.json 파일을 지정합니다. @@ -522,7 +522,7 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + 실행될 것으로 예상되는 최소 테스트 수를 지정합니다. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index b8e6cb922e..f9085027fc 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + Nie można odnaleźć pliku konfiguracji „{0}” określonego za pomocą parametru „--config-file”. @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + Określa plik testconfig.json. @@ -522,7 +522,7 @@ Dostępne wartości to „Trace”, „Debug”, „Information”, „Warning Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + Określa minimalną liczbę testów, które mają zostać uruchomione. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index b9b18bdbaa..105285b9c3 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -159,7 +159,7 @@ The configuration file '{0}' specified with '--config-file' could not be found. - The configuration file '{0}' specified with '--config-file' could not be found. + 找不到以 '--config-file' 指定的設定檔 '{0}'。 @@ -423,7 +423,7 @@ Specifies a testconfig.json file. - Specifies a testconfig.json file. + 指定 testconfig.json 檔案。 @@ -522,7 +522,7 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an Specifies the minimum number of tests that are expected to run. - Specifies the minimum number of tests that are expected to run. + 指定預期執行的測試數目下限。 From fe1dffdd9ec8cb24c371cc33ee07cbb4dabfcf34 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 3 Dec 2024 07:06:25 -0800 Subject: [PATCH 049/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2594144 --- .../Resources/xlf/MSBuildResources.pl.xlf | 6 +++--- .../Resources/xlf/MSBuildResources.zh-Hant.xlf | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pl.xlf index 2de569adf6..379ac3ff97 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.pl.xlf @@ -34,11 +34,11 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + Nie można odnaleźć hosta „{0}” dla architektury „{1}”. -You can resolve the problem by installing the '{1}' .NET. +Problem można rozwiązać, instalując program .NET „{1}”. -The specified framework can be found at: +Określoną strukturę można znaleźć pod adresem: - https://aka.ms/dotnet-download diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hant.xlf index 50f79ba0bb..392c6a45ae 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Resources/xlf/MSBuildResources.zh-Hant.xlf @@ -34,11 +34,11 @@ You can resolve the problem by installing the '{1}' .NET. The specified framework can be found at: - https://aka.ms/dotnet-download - Could not find '{0}' host for the '{1}' architecture. + 找不到 '{1}' 結構的 '{0}' 主機。 -You can resolve the problem by installing the '{1}' .NET. +您可以安裝 '{1}' .NET 來解決問題。 -The specified framework can be found at: +您可以在以下位置找到指定的架構: - https://aka.ms/dotnet-download From 59dc620cfcc7bc705563da623b0313d336de6c9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 3 Dec 2024 17:37:59 +0100 Subject: [PATCH 050/273] Changelog for 3.6.4 --- docs/Changelog.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docs/Changelog.md b/docs/Changelog.md index df9bda0bf4..842ec327f1 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -4,6 +4,28 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) +## [3.6.4] - 2024-12-03 + +See full log [here](https://github.com/microsoft/testfx/compare/v3.6.3...v3.6.4) + +### Fixed + +* Bump MS CC to 17.13.0 by @Evangelink in [#4212](https://github.com/microsoft/testfx/pull/4212) +* Bump vulnerable deps by @Evangelink in [#4218)(https://github.com/microsoft/testfx/pull/4218) + +### Artifacts + +* MSTest: [3.6.4](https://www.nuget.org/packages/MSTest/3.6.4) +* MSTest.TestFramework: [3.6.4](https://www.nuget.org/packages/MSTest.TestFramework/3.6.4) +* MSTest.TestAdapter: [3.6.4](https://www.nuget.org/packages/MSTest.TestAdapter/3.6.4) +* MSTest.Analyzers: [3.6.4](https://www.nuget.org/packages/MSTest.Analyzers/3.6.4) +* MSTest.Sdk: [3.6.4](https://www.nuget.org/packages/MSTest.Sdk/3.6.4) +* Microsoft.Testing.Extensions.CrashDump: [1.4.3](https://www.nuget.org/packages/Microsoft.Testing.Extensions.CrashDump/1.4.3) +* Microsoft.Testing.Extensions.HangDump: [1.4.3](https://www.nuget.org/packages/Microsoft.Testing.Extensions.HangDump/1.4.3) +* Microsoft.Testing.Extensions.HotReload: [1.4.3](https://www.nuget.org/packages/Microsoft.Testing.Extensions.HotReload/1.4.3) +* Microsoft.Testing.Extensions.Retry: [1.4.3](https://www.nuget.org/packages/Microsoft.Testing.Extensions.Retry/1.4.3) +* Microsoft.Testing.Extensions.TrxReport: [1.4.3](https://www.nuget.org/packages/Microsoft.Testing.Extensions.TrxReport/1.4.3) + ## [3.6.3] - 2024-11-12 See full log [here](https://github.com/microsoft/testfx/compare/v3.6.2...v3.6.3) From b115f39a059e199577cb6773673378349cdbea80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 3 Dec 2024 18:25:26 +0100 Subject: [PATCH 051/273] Fix analyzers package to support VB.NET (#4224) --- .../MSTest.Analyzers.Package/MSTest.Analyzers.Package.csproj | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Analyzers/MSTest.Analyzers.Package/MSTest.Analyzers.Package.csproj b/src/Analyzers/MSTest.Analyzers.Package/MSTest.Analyzers.Package.csproj index 1055a3ecab..36f7766c50 100644 --- a/src/Analyzers/MSTest.Analyzers.Package/MSTest.Analyzers.Package.csproj +++ b/src/Analyzers/MSTest.Analyzers.Package/MSTest.Analyzers.Package.csproj @@ -34,7 +34,9 @@ - + + + From e5283fd9fd52105710020e512128068d117e2551 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 09:04:59 +0100 Subject: [PATCH 052/273] [main] Bump MicrosoftTestingInternalFrameworkVersion from 1.5.0-preview.24576.1 to 1.5.0-preview.24577.4 (#4227) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- eng/Versions.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eng/Versions.props b/eng/Versions.props index d922796051..53a78262fc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,7 +10,7 @@ 10.0.0-beta.24578.2 17.13.1-preview.24603.1 - 1.5.0-preview.24576.1 + 1.5.0-preview.24577.4 1.0.0-alpha.24473.2 From cb496c22e33aab9fec9363da5486e80d3437fa3e Mon Sep 17 00:00:00 2001 From: Mariam Abdullah <122357303+mariam-abdulla@users.noreply.github.com> Date: Wed, 4 Dec 2024 09:38:46 +0100 Subject: [PATCH 053/273] Fix concurrency issue in TerminalTestReporter (#4229) --- .../Terminal/TerminalTestReporter.cs | 21 ++++++++----------- 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs index 6c4134f0ea..0c8543d807 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs @@ -6,6 +6,7 @@ using System.Reflection; #endif +using System.Collections.Concurrent; using System.Globalization; using System.Text.RegularExpressions; @@ -30,7 +31,7 @@ internal sealed partial class TerminalTestReporter : IDisposable internal Func CreateStopwatch { get; set; } = SystemStopwatch.StartNew; - private readonly Dictionary _assemblies = new(); + private readonly ConcurrentDictionary _assemblies = new(); private readonly List _artifacts = new(); @@ -164,19 +165,15 @@ public void AssemblyRunStarted(string assembly, string? targetFramework, string? private TestProgressState GetOrAddAssemblyRun(string assembly, string? targetFramework, string? architecture, string? executionId) { string key = $"{assembly}|{targetFramework}|{architecture}|{executionId}"; - if (_assemblies.TryGetValue(key, out TestProgressState? asm)) + return _assemblies.GetOrAdd(key, _ => { - return asm; - } - - IStopwatch sw = CreateStopwatch(); - var assemblyRun = new TestProgressState(assembly, targetFramework, architecture, sw); - int slotIndex = _terminalWithProgress.AddWorker(assemblyRun); - assemblyRun.SlotIndex = slotIndex; + IStopwatch sw = CreateStopwatch(); + var assemblyRun = new TestProgressState(assembly, targetFramework, architecture, sw); + int slotIndex = _terminalWithProgress.AddWorker(assemblyRun); + assemblyRun.SlotIndex = slotIndex; - _assemblies.Add(key, assemblyRun); - - return assemblyRun; + return assemblyRun; + }); } internal void TestExecutionCompleted(DateTimeOffset endTime) From 88872f56539c0c206f6a41a5adea766e00aaefcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 4 Dec 2024 10:59:27 +0100 Subject: [PATCH 054/273] Fix insertion from testanywhere repo (#4230) --- Directory.Packages.props | 3 ++- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- src/Package/MSTest.Sdk/MSTest.Sdk.csproj | 2 +- .../DiagnosticTests.cs | 7 +++--- .../ExecutionTests.cs | 7 +++--- .../HelpInfoTests.cs | 14 +++++++----- .../Helpers/AcceptanceTestBase.cs | 19 +++++++--------- .../MSBuildTests.ConfigurationFile.cs | 10 +++++---- .../MSBuildTests.Solution.cs | 7 +++--- .../MSBuildTests.Test.cs | 22 ++++++++++++------- ...latform.Acceptance.IntegrationTests.csproj | 8 +++---- .../TimeoutTests.cs | 7 +++--- .../TrxTests.cs | 7 +++--- 14 files changed, 66 insertions(+), 53 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index df8a5e0bb0..d87626fa7e 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -17,6 +17,7 @@ 17.12.0 1.49.0 17.12.0 + 1.5.0-preview.24577.4 4.3.1 4.3.1 @@ -41,7 +42,7 @@ - + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 36af61a05d..f289bc1aeb 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -17,9 +17,9 @@ https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage a657d717d57fcaf8f3ab3330b168f420e92b7a42 - + https://github.com/microsoft/testanywhere - f01fa388c7ec30f4f92ee01c2db94cc8e7a93ae8 + 16e36e5fb2a4c3cae9dd5e0b041f72dce371d300 https://github.com/microsoft/testanywhere diff --git a/eng/Versions.props b/eng/Versions.props index 53a78262fc..8abc136c95 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,7 +10,7 @@ 10.0.0-beta.24578.2 17.13.1-preview.24603.1 - 1.5.0-preview.24577.4 + 1.5.0-preview.24603.5 1.0.0-alpha.24473.2 diff --git a/src/Package/MSTest.Sdk/MSTest.Sdk.csproj b/src/Package/MSTest.Sdk/MSTest.Sdk.csproj index 601f6ccd2f..ed9f10179d 100644 --- a/src/Package/MSTest.Sdk/MSTest.Sdk.csproj +++ b/src/Package/MSTest.Sdk/MSTest.Sdk.csproj @@ -35,7 +35,7 @@ - <_TemplateProperties>MSTestEngineVersion=$(MSTestEngineVersion);MSTestVersion=$(Version);MicrosoftTestingPlatformVersion=$(Version.Replace('$(VersionPrefix)', '$(TestingPlatformVersionPrefix)'));MicrosoftTestingEntrepriseExtensionsVersion=$(MicrosoftTestingInternalFrameworkVersion);MicrosoftNETTestSdkVersion=$(MicrosoftNETTestSdkVersion);MicrosoftTestingExtensionsCodeCoverageVersion=$(MicrosoftTestingExtensionsCodeCoverageVersion);MicrosoftPlaywrightVersion=$(MicrosoftPlaywrightVersion);AspireHostingTestingVersion=$(AspireHostingTestingVersion);MicrosoftTestingExtensionsFakesVersion=$(MicrosoftTestingExtensionsFakesVersion) + <_TemplateProperties>MSTestEngineVersion=$(MSTestEngineVersion);MSTestVersion=$(Version);MicrosoftTestingPlatformVersion=$(Version.Replace('$(VersionPrefix)', '$(TestingPlatformVersionPrefix)'));MicrosoftTestingEntrepriseExtensionsVersion=$(MicrosoftTestingExtensionsRetryVersion);MicrosoftNETTestSdkVersion=$(MicrosoftNETTestSdkVersion);MicrosoftTestingExtensionsCodeCoverageVersion=$(MicrosoftTestingExtensionsCodeCoverageVersion);MicrosoftPlaywrightVersion=$(MicrosoftPlaywrightVersion);AspireHostingTestingVersion=$(AspireHostingTestingVersion);MicrosoftTestingExtensionsFakesVersion=$(MicrosoftTestingExtensionsFakesVersion) - - + + @@ -278,7 +278,8 @@ public void TestMethod1() TestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); } } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs index bdc4d4b550..b925c1cefc 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs @@ -143,8 +143,8 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test - - + + @@ -271,7 +271,8 @@ internal class Capabilities : ITestFrameworkCapabilities TestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); yield return (AssetName2, AssetName2, TestCode2 diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs index 4292684d6e..1f66b97679 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs @@ -669,8 +669,8 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test - - + + @@ -724,8 +724,8 @@ public void TestMethod1() - - + + @@ -764,12 +764,14 @@ public void TestMethod1() NoExtensionTestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); yield return (AllExtensionsAssetName, AllExtensionsAssetName, AllExtensionsTestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); } } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs index de978129ff..093d37d5b9 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs @@ -57,18 +57,13 @@ static AcceptanceTestBase() var cpmPropFileDoc = XDocument.Load(Path.Combine(RootFinder.Find(), "Directory.Packages.props")); MicrosoftNETTestSdkVersion = cpmPropFileDoc.Descendants("MicrosoftNETTestSdkVersion").Single().Value; - var versionsPropFileDoc = XDocument.Load(Path.Combine(RootFinder.Find(), "eng", "Versions.props")); -#if MSTEST_DOWNLOADED - MSTestVersion = ExtractVersionFromVersionPropsFile(versionsPropFileDoc, "MSTestVersion"); - MicrosoftTestingPlatformVersion = ExtractVersionFromVersionPropsFile(versionsPropFileDoc, "MSTestVersion"); - MicrosoftTestingEnterpriseExtensionsVersion = ExtractVersionFromPackage(Constants.ArtifactsPackagesShipping, "Microsoft.Testing.Extensions."); - MSTestEngineVersion = ExtractVersionFromPackage(Constants.ArtifactsPackagesShipping, "MSTest.Engine"); -#else + var versionsPropsFileDoc = XDocument.Load(Path.Combine(RootFinder.Find(), "eng", "Versions.props")); + var directoryPackagesPropsFileDoc = XDocument.Load(Path.Combine(RootFinder.Find(), "Directory.Packages.props")); MSTestVersion = ExtractVersionFromPackage(Constants.ArtifactsPackagesShipping, "MSTest.TestFramework."); MicrosoftTestingPlatformVersion = ExtractVersionFromPackage(Constants.ArtifactsPackagesShipping, "Microsoft.Testing.Platform."); - MicrosoftTestingEnterpriseExtensionsVersion = ExtractVersionFromVersionPropsFile(versionsPropFileDoc, "MicrosoftTestingInternalFrameworkVersion"); - MSTestEngineVersion = ExtractVersionFromVersionPropsFile(versionsPropFileDoc, "MSTestEngineVersion"); -#endif + MicrosoftTestingEnterpriseExtensionsVersion = ExtractVersionFromXmlFile(versionsPropsFileDoc, "MicrosoftTestingExtensionsRetryVersion"); + MicrosoftTestingInternalFrameworkVersion = ExtractVersionFromXmlFile(directoryPackagesPropsFileDoc, "MicrosoftTestingInternalFrameworkVersion"); + MSTestEngineVersion = ExtractVersionFromXmlFile(versionsPropsFileDoc, "MSTestEngineVersion"); } protected AcceptanceTestBase(ITestExecutionContext testExecutionContext) @@ -95,6 +90,8 @@ protected AcceptanceTestBase(ITestExecutionContext testExecutionContext) public static string MicrosoftTestingEnterpriseExtensionsVersion { get; private set; } + public static string MicrosoftTestingInternalFrameworkVersion { get; private set; } + internal static IEnumerable> GetBuildMatrixTfmBuildVerbConfiguration() { foreach (TestArgumentsEntry tfm in TargetFrameworks.All) @@ -181,7 +178,7 @@ private static string ExtractVersionFromPackage(string rootFolder, string packag return packageFullName.Substring(packagePrefixName.Length, packageFullName.Length - packagePrefixName.Length - NuGetPackageExtensionName.Length); } - private static string ExtractVersionFromVersionPropsFile(XDocument versionPropsXmlDocument, string entryName) + private static string ExtractVersionFromXmlFile(XDocument versionPropsXmlDocument, string entryName) { XElement[] matches = versionPropsXmlDocument.Descendants(entryName).ToArray(); return matches.Length != 1 diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs index 6db6765313..8d3e9286c2 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs @@ -20,7 +20,8 @@ public async Task ConfigFileGeneration_CorrectlyCreateAndCacheAndCleaned(string .PatchCodeWithReplace("$TargetFrameworks$", tfm) .PatchCodeWithReplace("$JsonContent$", ConfigurationContent) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -v:normal -nodeReuse:false {testAsset.TargetAssetPath} -c {compilationMode}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); @@ -58,7 +59,8 @@ public async Task ConfigFileGeneration_NoConfigurationFile_TaskWontRun(string tf .PatchCodeWithReplace("$TargetFrameworks$", tfm) .PatchCodeWithReplace("$JsonContent$", ConfigurationContent) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); File.Delete(Path.Combine(testAsset.TargetAssetPath, "testconfig.json")); @@ -95,8 +97,8 @@ public async Task ConfigFileGeneration_NoConfigurationFile_TaskWontRun(string tf - - + + diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs index 7ad84c074d..60043750e6 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs @@ -38,7 +38,8 @@ public async Task MSBuildTests_UseMSBuildTestInfrastructure_Should_Run_Solution_ SourceCode .PatchCodeWithReplace("$TargetFrameworks$", isMultiTfm ? $"{singleTfmOrMultiTfm}" : $"{singleTfmOrMultiTfm}") .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); string projectContent = File.ReadAllText(Directory.GetFiles(generator.TargetAssetPath, "MSBuildTests.csproj", SearchOption.AllDirectories).Single()); string programSourceContent = File.ReadAllText(Directory.GetFiles(generator.TargetAssetPath, "Program.cs", SearchOption.AllDirectories).Single()); @@ -104,8 +105,8 @@ public async Task MSBuildTests_UseMSBuildTestInfrastructure_Should_Run_Solution_ - - + + diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs index 9c3b9f9e8c..d057c61852 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs @@ -79,7 +79,8 @@ private async Task InvokeTestingPlatform_Target_Should_Execute_Tests_Without_Sho .PatchCodeWithReplace("$TargetFrameworks$", isMultiTfm ? $"{tfm}" : $"{tfm}") .PatchCodeWithReplace("$AssertValue$", testSucceeded.ToString().ToLowerInvariant()) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); string testResultFolder = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N")); DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{testCommand} -p:TestingPlatformCommandLineArguments=\"--results-directory %22{testResultFolder}%22\" -p:Configuration={compilationMode} -p:nodeReuse=false -bl:{binlogFile} \"{testAsset.TargetAssetPath}\"", _acceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); @@ -107,7 +108,8 @@ private async Task InvokeTestingPlatform_Target_Should_Build_Without_Warnings_An .PatchCodeWithReplace("$TargetFrameworks$", isMultiTfm ? $"{tfm}" : $"{tfm}") .PatchCodeWithReplace("$AssertValue$", testSucceeded.ToString().ToLowerInvariant()) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); string testResultFolder = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N")); @@ -146,7 +148,8 @@ public async Task Invoke_DotnetTest_With_Arch_Switch_x86_Should_Work() .PatchCodeWithReplace("$TargetFrameworks$", $"{TargetFrameworks.NetCurrent.Arguments}") .PatchCodeWithReplace("$AssertValue$", bool.TrueString.ToLowerInvariant()) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); await DotnetCli.RunAsync( $"test --arch x86 -p:TestingPlatformDotnetTestSupport=True -p:Configuration=Release -p:nodeReuse=false -bl:{binlogFile} \"{testAsset.TargetAssetPath}\"", @@ -177,7 +180,8 @@ public async Task Invoke_DotnetTest_With_Incompatible_Arch() .PatchCodeWithReplace("$TargetFrameworks$", $"{TargetFrameworks.NetCurrent.Arguments}") .PatchCodeWithReplace("$AssertValue$", bool.TrueString.ToLowerInvariant()) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); DotnetMuxerResult result = await DotnetCli.RunAsync( $"test --arch {incompatibleArchitecture} -p:TestingPlatformDotnetTestSupport=True \"{testAsset.TargetAssetPath}\"", _acceptanceFixture.NuGetGlobalPackagesFolder.Path, @@ -219,7 +223,8 @@ public async Task Invoke_DotnetTest_With_DOTNET_HOST_PATH_Should_Work() .PatchCodeWithReplace("$TargetFrameworks$", $"{TargetFrameworks.NetCurrent.Arguments}") .PatchCodeWithReplace("$AssertValue$", bool.TrueString.ToLowerInvariant()) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); await DotnetCli.RunAsync( $"test -p:TestingPlatformDotnetTestSupport=True -p:Configuration=Release -p:nodeReuse=false -bl:{binlogFile} \"{testAsset.TargetAssetPath}\"", @@ -268,7 +273,8 @@ public async Task InvokeTestingPlatform_Target_Showing_Error_And_Do_Not_Capture_ .PatchCodeWithReplace("$TargetFrameworks$", $"{tfm}") .PatchCodeWithReplace("$AssertValue$", testSucceeded.ToString().ToLowerInvariant()) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{testCommand} -p:TestingPlatformShowTestsFailure=True -p:TestingPlatformCaptureOutput=False -p:Configuration={compilationMode} -p:nodeReuse=false -bl:{binlogFile} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); Assert.Contains("error test failed: TestMethod2 (", compilationResult.StandardOutput); @@ -295,8 +301,8 @@ public async Task InvokeTestingPlatform_Target_Showing_Error_And_Do_Not_Capture_ - - + + diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj index 7e0e340d94..992db4d4d1 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj @@ -16,8 +16,8 @@ - - + + @@ -36,8 +36,8 @@ - - + + diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs index 273938bc3c..fb370f1722 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs @@ -110,8 +110,8 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test - - + + @@ -149,7 +149,8 @@ public void TestMethod1() TestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); } } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs index f49bd2ca50..4fd844ccc6 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs @@ -221,8 +221,8 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test - - + + @@ -319,7 +319,8 @@ public void TestMethod1(string s) TestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) + .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); yield return (WithSkippedTest, AssetNameUsingMSTest, MSTestCode .PatchTargetFrameworks(TargetFrameworks.All) From aede0da21133fb046d953ccc73d370044e6c476c Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 4 Dec 2024 13:38:27 +0100 Subject: [PATCH 055/273] Only push output device messages to Test Explorer, don't push logs (#4178) --- .../CommandLine/CommandLineHandler.cs | 120 ++++++------ .../CommandLine/ICommandLineHandler.cs | 2 +- .../Hosts/CommonTestHost.cs | 16 +- .../Hosts/ConsoleTestHost.cs | 3 +- .../Hosts/ServerTestHost.cs | 61 ++++-- .../Hosts/TestHostBuilder.cs | 59 +++--- .../Hosts/TestHostControllersTestHost.cs | 8 +- .../Hosts/ToolsTestHost.cs | 14 +- .../Logging/ServerLoggerForwarder.cs | 182 ------------------ .../Logging/ServerLoggerForwarderProvider.cs | 35 ---- .../OutputDevice/IPlatformOutputDevice.cs | 5 +- .../OutputDevice/OutputDeviceManager.cs | 17 +- .../OutputDevice/ProxyOutputDevice.cs | 65 +++++++ .../Resources/PlatformResources.resx | 25 ++- .../Resources/xlf/PlatformResources.cs.xlf | 35 ++++ .../Resources/xlf/PlatformResources.de.xlf | 35 ++++ .../Resources/xlf/PlatformResources.es.xlf | 35 ++++ .../Resources/xlf/PlatformResources.fr.xlf | 35 ++++ .../Resources/xlf/PlatformResources.it.xlf | 35 ++++ .../Resources/xlf/PlatformResources.ja.xlf | 35 ++++ .../Resources/xlf/PlatformResources.ko.xlf | 35 ++++ .../Resources/xlf/PlatformResources.pl.xlf | 35 ++++ .../Resources/xlf/PlatformResources.pt-BR.xlf | 35 ++++ .../Resources/xlf/PlatformResources.ru.xlf | 35 ++++ .../Resources/xlf/PlatformResources.tr.xlf | 35 ++++ .../xlf/PlatformResources.zh-Hans.xlf | 35 ++++ .../xlf/PlatformResources.zh-Hant.xlf | 35 ++++ .../JsonRpc/ServerModePerCallOutputDevice.cs | 135 ++++++++++++- .../ServerMode/LogsCollector.cs | 3 +- .../ServerModeTests.cs | 2 +- ...latform.Acceptance.IntegrationTests.csproj | 5 +- .../ServerLoggingTests.cs | 178 +++++++++++++++++ .../Logging/ServerLoggerForwarderTests.cs | 57 ------ 33 files changed, 1030 insertions(+), 417 deletions(-) delete mode 100644 src/Platform/Microsoft.Testing.Platform/Logging/ServerLoggerForwarder.cs delete mode 100644 src/Platform/Microsoft.Testing.Platform/Logging/ServerLoggerForwarderProvider.cs create mode 100644 src/Platform/Microsoft.Testing.Platform/OutputDevice/ProxyOutputDevice.cs create mode 100644 test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs delete mode 100644 test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/ServerLoggerForwarderTests.cs diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineHandler.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineHandler.cs index 8fb0dba1ba..f883315001 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineHandler.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineHandler.cs @@ -51,13 +51,13 @@ public CommandLineHandler(CommandLineParseResult parseResult, IReadOnlyCollectio internal CommandLineParseResult ParseResult { get; } - public async Task PrintInfoAsync(IPlatformOutputDevice platformOutputDevice, IReadOnlyList? availableTools = null) + public async Task PrintInfoAsync(IOutputDevice outputDevice, IReadOnlyList? availableTools = null) { // /!\ Info should not be localized as it serves debugging purposes. await DisplayPlatformInfoAsync(); - await platformOutputDevice.DisplayAsync(this, EmptyText); - await DisplayBuiltInExtensionsInfoAsync(platformOutputDevice); - await platformOutputDevice.DisplayAsync(this, EmptyText); + await outputDevice.DisplayAsync(this, EmptyText); + await DisplayBuiltInExtensionsInfoAsync(outputDevice); + await outputDevice.DisplayAsync(this, EmptyText); List toolExtensions = []; List nonToolExtensions = []; @@ -73,24 +73,24 @@ public async Task PrintInfoAsync(IPlatformOutputDevice platformOutputDevice, IRe } } - await DisplayRegisteredExtensionsInfoAsync(platformOutputDevice, nonToolExtensions); - await platformOutputDevice.DisplayAsync(this, EmptyText); - await DisplayRegisteredToolsInfoAsync(platformOutputDevice, availableTools, toolExtensions); - await platformOutputDevice.DisplayAsync(this, EmptyText); + await DisplayRegisteredExtensionsInfoAsync(outputDevice, nonToolExtensions); + await outputDevice.DisplayAsync(this, EmptyText); + await DisplayRegisteredToolsInfoAsync(outputDevice, availableTools, toolExtensions); + await outputDevice.DisplayAsync(this, EmptyText); return; async Task DisplayPlatformInfoAsync() { // Product title, do not translate. - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData("Microsoft Testing Platform:")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData("Microsoft Testing Platform:")); // TODO: Replace Assembly with IAssembly AssemblyInformationalVersionAttribute? version = Assembly.GetExecutingAssembly().GetCustomAttribute(); string versionInfo = version?.InformationalVersion ?? "Not Available"; - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($" Version: {versionInfo}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($" Version: {versionInfo}")); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($" Dynamic Code Supported: {_runtimeFeature.IsDynamicCodeSupported}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($" Dynamic Code Supported: {_runtimeFeature.IsDynamicCodeSupported}")); // TODO: Replace RuntimeInformation with IRuntimeInformation #if NETCOREAPP @@ -98,42 +98,42 @@ async Task DisplayPlatformInfoAsync() #else string runtimeInformation = $"{RuntimeInformation.FrameworkDescription}"; #endif - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($" Runtime information: {runtimeInformation}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($" Runtime information: {runtimeInformation}")); #if !NETCOREAPP #pragma warning disable IL3000 // Avoid accessing Assembly file path when publishing as a single file, this branch run only in .NET Framework string runtimeLocation = typeof(object).Assembly?.Location ?? "Not Found"; #pragma warning restore IL3000 // Avoid accessing Assembly file path when publishing as a single file - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($" Runtime location: {runtimeLocation}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($" Runtime location: {runtimeLocation}")); #endif string moduleName = _testApplicationModuleInfo.GetCurrentTestApplicationFullPath(); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($" Test module: {moduleName}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($" Test module: {moduleName}")); } - async Task DisplayOptionsAsync(IPlatformOutputDevice platformOutputDevice, IEnumerable options, int indentLevel) + async Task DisplayOptionsAsync(IOutputDevice outputDevice, IEnumerable options, int indentLevel) { string optionNameIndent = new(' ', indentLevel * 2); string optionInfoIndent = new(' ', (indentLevel + 1) * 2); foreach (CommandLineOption option in options.OrderBy(x => x.Name)) { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($"{optionNameIndent}--{option.Name}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($"{optionNameIndent}--{option.Name}")); if (option.Arity.Min == option.Arity.Max) { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($"{optionInfoIndent}Arity: {option.Arity.Min}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($"{optionInfoIndent}Arity: {option.Arity.Min}")); } else { string maxArityValue = option.Arity.Max == int.MaxValue ? "N" : $"{option.Arity.Max}"; - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($"{optionInfoIndent}Arity: {option.Arity.Min}..{maxArityValue}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($"{optionInfoIndent}Arity: {option.Arity.Min}..{maxArityValue}")); } - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($"{optionInfoIndent}Hidden: {option.IsHidden}")); - await platformOutputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData($"Description: {option.Description}") { Padding = optionInfoIndent.Length }); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($"{optionInfoIndent}Hidden: {option.IsHidden}")); + await outputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData($"Description: {option.Description}") { Padding = optionInfoIndent.Length }); } } - async Task DisplayProvidersAsync(IPlatformOutputDevice platformOutputDevice, IEnumerable optionsProviders, int indentLevel) + async Task DisplayProvidersAsync(IOutputDevice outputDevice, IEnumerable optionsProviders, int indentLevel) { string providerIdIndent = new(' ', indentLevel * 2); string providerInfoIndent = new(' ', (indentLevel + 1) * 2); @@ -145,69 +145,69 @@ async Task DisplayProvidersAsync(IPlatformOutputDevice platformOutputDevice, IEn if (isFirst) { isFirst = false; - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($"{providerIdIndent}{provider.Uid}")); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($"{providerInfoIndent}Name: {provider.DisplayName}")); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($"{providerInfoIndent}Version: {provider.Version}")); - await platformOutputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData($"Description: {provider.Description}") { Padding = providerInfoIndent.Length }); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($"{providerInfoIndent}Options:")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($"{providerIdIndent}{provider.Uid}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($"{providerInfoIndent}Name: {provider.DisplayName}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($"{providerInfoIndent}Version: {provider.Version}")); + await outputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData($"Description: {provider.Description}") { Padding = providerInfoIndent.Length }); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($"{providerInfoIndent}Options:")); } - await DisplayOptionsAsync(platformOutputDevice, provider.GetCommandLineOptions(), indentLevel + 2); + await DisplayOptionsAsync(outputDevice, provider.GetCommandLineOptions(), indentLevel + 2); } } } - async Task DisplayBuiltInExtensionsInfoAsync(IPlatformOutputDevice platformOutputDevice) + async Task DisplayBuiltInExtensionsInfoAsync(IOutputDevice outputDevice) { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData("Built-in command line providers:")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData("Built-in command line providers:")); if (SystemCommandLineOptionsProviders.Count == 0) { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(" There are no built-in command line providers.")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(" There are no built-in command line providers.")); } else { - await DisplayProvidersAsync(platformOutputDevice, SystemCommandLineOptionsProviders, 1); + await DisplayProvidersAsync(outputDevice, SystemCommandLineOptionsProviders, 1); } } - async Task DisplayRegisteredExtensionsInfoAsync(IPlatformOutputDevice platformOutputDevice, List nonToolExtensions) + async Task DisplayRegisteredExtensionsInfoAsync(IOutputDevice outputDevice, List nonToolExtensions) { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData("Registered command line providers:")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData("Registered command line providers:")); if (nonToolExtensions.Count == 0) { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(" There are no registered command line providers.")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(" There are no registered command line providers.")); } else { - await DisplayProvidersAsync(platformOutputDevice, nonToolExtensions, 1); + await DisplayProvidersAsync(outputDevice, nonToolExtensions, 1); } } - async Task DisplayRegisteredToolsInfoAsync(IPlatformOutputDevice platformOutputDevice, IReadOnlyList? availableTools, List toolExtensions) + async Task DisplayRegisteredToolsInfoAsync(IOutputDevice outputDevice, IReadOnlyList? availableTools, List toolExtensions) { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData("Registered tools:")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData("Registered tools:")); if (availableTools is null || availableTools.Count == 0) { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(" There are no registered tools.")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(" There are no registered tools.")); } else { var groupedToolExtensions = toolExtensions.GroupBy(x => x.ToolName).ToDictionary(x => x.Key, x => x.ToList()); foreach (ITool tool in availableTools.OrderBy(x => x.Uid)) { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($" {tool.Uid}")); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($" Command: {tool.Name}")); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($" Name: {tool.DisplayName}")); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData($" Version: {tool.Version}")); - await platformOutputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData($"Description: {tool.Description}") { Padding = 4 }); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(" Tool command line providers:")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($" {tool.Uid}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($" Command: {tool.Name}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($" Name: {tool.DisplayName}")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData($" Version: {tool.Version}")); + await outputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData($"Description: {tool.Description}") { Padding = 4 }); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(" Tool command line providers:")); if (groupedToolExtensions.TryGetValue(tool.Name, out List? providers)) { - await DisplayProvidersAsync(platformOutputDevice, providers, 3); + await DisplayProvidersAsync(outputDevice, providers, 3); } else { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(" There are no registered command line providers.")); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(" There are no registered command line providers.")); } } } @@ -232,7 +232,7 @@ public bool TryGetOptionArgumentList(string optionName, [NotNullWhen(true)] out public bool IsDotNetTestPipeInvoked() => IsOptionSet(PlatformCommandLineProvider.DotNetTestPipeOptionKey); #pragma warning disable IDE0060 // Remove unused parameter, temporary we don't use it. - public async Task PrintHelpAsync(IPlatformOutputDevice platformOutputDevice, IReadOnlyList? availableTools = null) + public async Task PrintHelpAsync(IOutputDevice outputDevice, IReadOnlyList? availableTools = null) #pragma warning restore IDE0060 // Remove unused parameter { string applicationName = GetApplicationName(_testApplicationModuleInfo); @@ -240,7 +240,7 @@ public async Task PrintHelpAsync(IPlatformOutputDevice platformOutputDevice, IRe // Temporary disabled, we don't remove the code because could be useful in future. // PrintApplicationToolUsage(availableTools, applicationName); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(string.Empty)); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(string.Empty)); // Local functions static string GetApplicationName(ITestApplicationModuleInfo testApplicationModuleInfo) @@ -267,9 +267,9 @@ async Task PrintOptionsAsync(IEnumerable opti foreach (CommandLineOption? option in options) { - await platformOutputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData($"--{option.Name}") { Padding = 4 }); - await platformOutputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData(option.Description) { Padding = 8 }); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(string.Empty)); + await outputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData($"--{option.Name}") { Padding = 4 }); + await outputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData(option.Description) { Padding = 8 }); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(string.Empty)); } return options.Length != 0; @@ -277,15 +277,15 @@ async Task PrintOptionsAsync(IEnumerable opti async Task PrintApplicationUsageAsync(string applicationName) { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(string.Format(CultureInfo.InvariantCulture, PlatformResources.HelpApplicationUsage, applicationName))); - await platformOutputDevice.DisplayAsync(this, EmptyText); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(PlatformResources.HelpExecuteTestApplication)); - await platformOutputDevice.DisplayAsync(this, EmptyText); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(string.Format(CultureInfo.InvariantCulture, PlatformResources.HelpApplicationUsage, applicationName))); + await outputDevice.DisplayAsync(this, EmptyText); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(PlatformResources.HelpExecuteTestApplication)); + await outputDevice.DisplayAsync(this, EmptyText); RoslynDebug.Assert( !SystemCommandLineOptionsProviders.OfType().Any(), "System command line options should not have any tool option registered."); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(PlatformResources.HelpOptions)); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(PlatformResources.HelpOptions)); ICommandLineOptionsProvider[] nonToolsExtensionProviders = ExtensionsCommandLineOptionsProviders .Where(provider => provider is not IToolCommandLineOptionsProvider) @@ -293,15 +293,15 @@ async Task PrintApplicationUsageAsync(string applicationName) // By default, only system options are built-in but some extensions (e.g. retry) are considered as built-in too, // so we need to union the 2 collections before printing the options. await PrintOptionsAsync(SystemCommandLineOptionsProviders.Union(nonToolsExtensionProviders), 1, builtInOnly: true); - await platformOutputDevice.DisplayAsync(this, EmptyText); + await outputDevice.DisplayAsync(this, EmptyText); - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(PlatformResources.HelpExtensionOptions)); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(PlatformResources.HelpExtensionOptions)); if (!await PrintOptionsAsync(nonToolsExtensionProviders, 1)) { - await platformOutputDevice.DisplayAsync(this, new TextOutputDeviceData(PlatformResources.HelpNoExtensionRegistered)); + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(PlatformResources.HelpNoExtensionRegistered)); } - await platformOutputDevice.DisplayAsync(this, EmptyText); + await outputDevice.DisplayAsync(this, EmptyText); } // Temporary disabled, we don't remove the code because could be useful in future. diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineHandler.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineHandler.cs index 97cb900e77..eb91a4513d 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineHandler.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineHandler.cs @@ -10,5 +10,5 @@ internal interface ICommandLineHandler { bool IsHelpInvoked(); - Task PrintHelpAsync(IPlatformOutputDevice platformOutputDevice, IReadOnlyList? availableTools = null); + Task PrintHelpAsync(IOutputDevice outputDevice, IReadOnlyList? availableTools = null); } diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs index 15ea8f2ccd..0e146d7e9c 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/CommonTestHost.cs @@ -69,7 +69,11 @@ public async Task RunAsync() await DisposeServiceProviderAsync(ServiceProvider, isProcessShutdown: true); await DisposeHelper.DisposeAsync(ServiceProvider.GetService()); await DisposeHelper.DisposeAsync(PushOnlyProtocol); - await DisposeHelper.DisposeAsync(ServiceProvider.GetTestApplicationCancellationTokenSource()); + + // This is intentional that we are not disposing the CTS. + // An unobserved task exception could be raised after the dispose, and we want to use OutputDevice there + // which needs CTS down the path. + // await DisposeHelper.DisposeAsync(ServiceProvider.GetTestApplicationCancellationTokenSource()); } if (testApplicationCancellationToken.IsCancellationRequested) @@ -119,7 +123,7 @@ private async Task RunTestAppAsync(CancellationToken testApplicationCancell protected abstract Task InternalRunAsync(); - protected static async Task ExecuteRequestAsync(IPlatformOutputDevice outputDevice, ITestSessionContext testSessionInfo, + protected static async Task ExecuteRequestAsync(ProxyOutputDevice outputDevice, ITestSessionContext testSessionInfo, ServiceProvider serviceProvider, BaseMessageBus baseMessageBus, ITestFramework testFramework, TestHost.ClientInfo client) { CancellationToken testSessionCancellationToken = serviceProvider.GetTestSessionContext().CancellationToken; @@ -142,12 +146,12 @@ protected static async Task ExecuteRequestAsync(IPlatformOutputDevice outputDevi await DisplayAfterSessionEndRunAsync(outputDevice, testSessionInfo, testSessionCancellationToken); } - private static async Task DisplayBeforeSessionStartAsync(IPlatformOutputDevice outputDevice, ITestSessionContext sessionInfo, CancellationToken cancellationToken) + private static async Task DisplayBeforeSessionStartAsync(ProxyOutputDevice outputDevice, ITestSessionContext sessionInfo, CancellationToken cancellationToken) { // Display before session start await outputDevice.DisplayBeforeSessionStartAsync(); - if (outputDevice is ITestSessionLifetimeHandler testSessionLifetimeHandler) + if (outputDevice.OriginalOutputDevice is ITestSessionLifetimeHandler testSessionLifetimeHandler) { await testSessionLifetimeHandler.OnTestSessionStartingAsync( sessionInfo.SessionId, @@ -155,13 +159,13 @@ await testSessionLifetimeHandler.OnTestSessionStartingAsync( } } - private static async Task DisplayAfterSessionEndRunAsync(IPlatformOutputDevice outputDevice, ITestSessionContext sessionInfo, CancellationToken cancellationToken) + private static async Task DisplayAfterSessionEndRunAsync(ProxyOutputDevice outputDevice, ITestSessionContext sessionInfo, CancellationToken cancellationToken) { // Display after session end await outputDevice.DisplayAfterSessionEndRunAsync(); // We want to ensure that the output service is the last one to run - if (outputDevice is ITestSessionLifetimeHandler testSessionLifetimeHandlerFinishing) + if (outputDevice.OriginalOutputDevice is ITestSessionLifetimeHandler testSessionLifetimeHandlerFinishing) { await testSessionLifetimeHandlerFinishing.OnTestSessionFinishingAsync( sessionInfo.SessionId, diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs index 15adebb7ff..4a66392d2b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs @@ -10,6 +10,7 @@ using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Logging; using Microsoft.Testing.Platform.Messages; +using Microsoft.Testing.Platform.OutputDevice; using Microsoft.Testing.Platform.Requests; using Microsoft.Testing.Platform.Services; using Microsoft.Testing.Platform.Telemetry; @@ -83,7 +84,7 @@ protected override async Task InternalRunAsync() ITestSessionContext testSessionInfo = ServiceProvider.GetTestSessionContext(); await ExecuteRequestAsync( - ServiceProvider.GetPlatformOutputDevice(), + (ProxyOutputDevice)ServiceProvider.GetOutputDevice(), testSessionInfo, ServiceProvider, ServiceProvider.GetBaseMessageBus(), diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs index 68d8a1b8eb..78f85cbb46 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs @@ -3,16 +3,20 @@ using System.Collections.Concurrent; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.Net.Sockets; using Microsoft.Testing.Internal.Framework; using Microsoft.Testing.Platform.Capabilities.TestFramework; using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Extensions.OutputDevice; using Microsoft.Testing.Platform.Extensions.TestFramework; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Logging; using Microsoft.Testing.Platform.Messages; +using Microsoft.Testing.Platform.OutputDevice; using Microsoft.Testing.Platform.Requests; +using Microsoft.Testing.Platform.Resources; using Microsoft.Testing.Platform.ServerMode; using Microsoft.Testing.Platform.Services; using Microsoft.Testing.Platform.Telemetry; @@ -20,7 +24,7 @@ namespace Microsoft.Testing.Platform.Hosts; -internal sealed partial class ServerTestHost : CommonTestHost, IServerTestHost, IDisposable +internal sealed partial class ServerTestHost : CommonTestHost, IServerTestHost, IDisposable, IOutputDeviceDataProducer { public const string ProtocolVersion = "1.0.0"; private readonly Func> _buildTestFrameworkAsync; @@ -93,13 +97,36 @@ public ServerTestHost( protected override bool RunTestApplicationLifeCycleCallbacks => true; + public string Uid => nameof(ServerTestHost); + + public string Version => AppVersion.DefaultSemVer; + + public string DisplayName => PlatformResources.ServerTestHostDisplayName; + + public string Description => PlatformResources.ServerTestHostDescription; + private void OnCurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) - => _logger.LogWarning($"[ServerTestHost.OnCurrentDomainUnhandledException] {e.ExceptionObject}{_environment.NewLine}IsTerminating: {e.IsTerminating}"); + { + _logger.LogWarning($"[ServerTestHost.OnCurrentDomainUnhandledException] {e.ExceptionObject}{_environment.NewLine}IsTerminating: {e.IsTerminating}"); + + // Looks like nothing in this message to really be localized? + // All are class names, method names, property names, and placeholders. So none is localizable? + ServiceProvider.GetOutputDevice().DisplayAsync( + this, + new WarningMessageOutputDeviceData( + $"[ServerTestHost.OnCurrentDomainUnhandledException] {e.ExceptionObject}{_environment.NewLine}IsTerminating: {e.IsTerminating}")) + .GetAwaiter().GetResult(); + } private void OnTaskSchedulerUnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e) { e.SetObserved(); _logger.LogWarning($"[ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {e.Exception}"); + + // Looks like nothing in this message to really be localized? + // All are class names, method names, property names, and placeholders. So none is localizable? + ServiceProvider.GetOutputDevice().DisplayAsync(this, new WarningMessageOutputDeviceData(PlatformResources.UnobservedTaskExceptionWarningMessage)) + .GetAwaiter().GetResult(); } [MemberNotNull(nameof(_messageHandler))] @@ -118,13 +145,6 @@ protected override async Task InternalRunAsync() await _logger.LogDebugAsync("Starting server mode"); _messageHandler = await _messageHandlerFactory.CreateMessageHandlerAsync(_testApplicationCancellationTokenSource.CancellationToken); - // Initialize the ServerLoggerForwarderProvider, it can be null if diagnostic is disabled. - ServerLoggerForwarderProvider? serviceLoggerForwarder = ServiceProvider.GetService(); - if (serviceLoggerForwarder is not null) - { - await serviceLoggerForwarder.InitializeAsync(this); - } - await HandleMessagesAsync(); (_messageHandler as IDisposable)?.Dispose(); @@ -268,7 +288,14 @@ private async Task HandleNotificationAsync(NotificationMessage message, Cancella Exception? cancellationException = rpcState.CancelRequest(); if (cancellationException is null) { + // This is intentionally not using PlatformResources.ExceptionDuringCancellationWarningMessage + // It's meant for troubleshooting and shouldn't be localized. + // The localized message that is user-facing will be displayed in the DisplayAsync call next line. await _logger.LogWarningAsync($"Exception during the cancellation of request id '{args.CancelRequestId}'"); + + await ServiceProvider.GetOutputDevice().DisplayAsync( + this, + new WarningMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, PlatformResources.ExceptionDuringCancellationWarningMessage, args.CancelRequestId))); } } @@ -450,13 +477,16 @@ private async Task ExecuteRequestAsync(RequestArgsBase args, s DateTimeOffset adapterLoadStart = _clock.UtcNow; + ProxyOutputDevice outputDevice = ServiceProvider.GetRequiredService(); + await outputDevice.InitializeAsync(this); + // Build the per request adapter - ITestFramework perRequestTestFramework = await _buildTestFrameworkAsync(new( + ITestFramework perRequestTestFramework = await _buildTestFrameworkAsync(new TestFrameworkBuilderData( perRequestServiceProvider, requestFactory, invoker, filterFactory, - new ServerModePerCallOutputDevice(), + outputDevice.OriginalOutputDevice, [testNodeUpdateProcessor], _testFrameworkManager, _testSessionManager, @@ -475,7 +505,7 @@ private async Task ExecuteRequestAsync(RequestArgsBase args, s // Execute the request await ExecuteRequestAsync( - perRequestServiceProvider.GetPlatformOutputDevice(), + outputDevice, perRequestServiceProvider.GetTestSessionContext(), perRequestServiceProvider, perRequestServiceProvider.GetBaseMessageBus(), @@ -632,6 +662,11 @@ public void Dispose() { // Note: The lifetime of the _reader/_writer should be currently handled by the RunAsync() // We could consider creating a stateful engine that has the lifetime == server connection UP. + if (!ServiceProvider.GetUnhandledExceptionsPolicy().FastFailOnFailure) + { + AppDomain.CurrentDomain.UnhandledException -= OnCurrentDomainUnhandledException; + TaskScheduler.UnobservedTaskException -= OnTaskSchedulerUnobservedTaskException; + } } internal async Task SendTestUpdateCompleteAsync(Guid runId) @@ -700,6 +735,8 @@ await SendMessageAsync( } } + public Task IsEnabledAsync() => throw new NotImplementedException(); + private sealed class RpcInvocationState : IDisposable { private readonly Lock _cancellationTokenSourceLock = new(); diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs index ff99764694..bc0a2184df 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs @@ -196,10 +196,6 @@ public async Task BuildAsync( LoggerFactoryProxy loggerFactoryProxy = new(); serviceProvider.TryAddService(loggerFactoryProxy); - // Add output display proxy, needed by command line manager. - // We don't add to the service right now because we need special treatment between console/server mode. - IPlatformOutputDevice platformOutputDevice = ((PlatformOutputDeviceManager)OutputDisplay).Build(serviceProvider); - // Add Terminal options provider CommandLine.AddProvider(() => new TerminalTestReporterCommandLineOptionsProvider()); @@ -210,6 +206,11 @@ public async Task BuildAsync( // Set the concrete command line options to the proxy. commandLineOptionsProxy.SetCommandLineOptions(commandLineHandler); + bool hasServerFlag = commandLineHandler.TryGetOptionArgumentList(PlatformCommandLineProvider.ServerOptionKey, out string[]? protocolName); + bool isJsonRpcProtocol = protocolName is null || protocolName.Length == 0 || protocolName[0].Equals(PlatformCommandLineProvider.JsonRpcProtocolName, StringComparison.OrdinalIgnoreCase); + + ProxyOutputDevice proxyOutputDevice = await ((PlatformOutputDeviceManager)OutputDisplay).BuildAsync(serviceProvider, hasServerFlag && isJsonRpcProtocol); + // Add FileLoggerProvider if needed if (loggingState.FileLoggerProvider is not null) { @@ -219,16 +220,6 @@ public async Task BuildAsync( // Get the command line options ICommandLineOptions commandLineOptions = serviceProvider.GetCommandLineOptions(); - // Register the server mode log forwarder if needed. We follow the console --diagnostic behavior. - bool hasServerFlag = commandLineHandler.TryGetOptionArgumentList(PlatformCommandLineProvider.ServerOptionKey, out string[]? protocolName); - bool isJsonRpcProtocol = protocolName is null || protocolName.Length == 0 || protocolName[0].Equals(PlatformCommandLineProvider.JsonRpcProtocolName, StringComparison.OrdinalIgnoreCase); - if (hasServerFlag && isJsonRpcProtocol) - { - ServerLoggerForwarderProvider serverLoggerProxy = new(loggingState.LogLevel, serviceProvider); - serviceProvider.AddService(serverLoggerProxy); - Logging.AddProvider((logLevel, services) => serverLoggerProxy); - } - // Build the logger factory. ILoggerFactory loggerFactory = await ((LoggingManager)Logging).BuildAsync(serviceProvider, loggingState.LogLevel, systemMonitor); @@ -236,19 +227,14 @@ public async Task BuildAsync( loggerFactoryProxy.SetLoggerFactory(loggerFactory); // Initialize the output device if needed. - if (await platformOutputDevice.IsEnabledAsync()) + if (await proxyOutputDevice.OriginalOutputDevice.IsEnabledAsync()) { - await platformOutputDevice.TryInitializeAsync(); - } - else - { - // If for some reason the custom output is not enabled we opt-in the default terminal output device. - platformOutputDevice = PlatformOutputDeviceManager.GetDefaultTerminalOutputDevice(serviceProvider); - await platformOutputDevice.TryInitializeAsync(); + await proxyOutputDevice.OriginalOutputDevice.TryInitializeAsync(); } // Add the platform output device to the service provider for both modes. - serviceProvider.TryAddService(platformOutputDevice); + serviceProvider.TryAddService(proxyOutputDevice); + serviceProvider.TryAddService(proxyOutputDevice.OriginalOutputDevice); // Create the test framework capabilities ITestFrameworkCapabilities testFrameworkCapabilities = TestFramework.TestFrameworkCapabilitiesFactory(serviceProvider); @@ -269,9 +255,9 @@ public async Task BuildAsync( if (!loggingState.CommandLineParseResult.HasTool && !commandLineValidationResult.IsValid) { - await DisplayBannerIfEnabledAsync(loggingState, platformOutputDevice, testFrameworkCapabilities); - await platformOutputDevice.DisplayAsync(commandLineHandler, new ErrorMessageOutputDeviceData(commandLineValidationResult.ErrorMessage)); - await commandLineHandler.PrintHelpAsync(platformOutputDevice); + await DisplayBannerIfEnabledAsync(loggingState, proxyOutputDevice, testFrameworkCapabilities); + await proxyOutputDevice.DisplayAsync(commandLineHandler, new ErrorMessageOutputDeviceData(commandLineValidationResult.ErrorMessage)); + await commandLineHandler.PrintHelpAsync(proxyOutputDevice); return new InformativeCommandLineTestHost(ExitCodes.InvalidCommandLine, serviceProvider); } @@ -307,7 +293,7 @@ public async Task BuildAsync( // Display banner now because we need capture the output in case of MSBuild integration and we want to forward // to file disc also the banner, so at this point we need to have all services and configuration(result directory) built. - await DisplayBannerIfEnabledAsync(loggingState, platformOutputDevice, testFrameworkCapabilities); + await DisplayBannerIfEnabledAsync(loggingState, proxyOutputDevice, testFrameworkCapabilities); // Add global telemetry service. // Add at this point or the telemetry banner appearance order will be wrong, we want the testing app banner before the telemetry banner. @@ -326,7 +312,7 @@ public async Task BuildAsync( // Register the ITestApplicationResult TestApplicationResult testApplicationResult = new( - platformOutputDevice, + proxyOutputDevice, serviceProvider.GetTestApplicationCancellationTokenSource(), serviceProvider.GetCommandLineOptions(), serviceProvider.GetEnvironment()); @@ -339,14 +325,14 @@ public async Task BuildAsync( // ======= TOOLS MODE ======== // // Add the platform output device to the service provider. var toolsServiceProvider = (ServiceProvider)serviceProvider.Clone(); - toolsServiceProvider.TryAddService(platformOutputDevice); + toolsServiceProvider.TryAddService(proxyOutputDevice); IReadOnlyList toolsInformation = await ((ToolsManager)Tools).BuildAsync(toolsServiceProvider); if (loggingState.CommandLineParseResult.HasTool) { // Add the platform output device to the service provider. - serviceProvider.TryAddService(platformOutputDevice); + serviceProvider.TryAddService(proxyOutputDevice); - ToolsTestHost toolsTestHost = new(toolsInformation, serviceProvider, commandLineHandler, platformOutputDevice); + ToolsTestHost toolsTestHost = new(toolsInformation, serviceProvider, commandLineHandler, proxyOutputDevice); await LogTestHostCreatedAsync( serviceProvider, @@ -373,7 +359,7 @@ await LogTestHostCreatedAsync( } else { - await commandLineHandler.PrintHelpAsync(platformOutputDevice, toolsInformation); + await commandLineHandler.PrintHelpAsync(proxyOutputDevice, toolsInformation); } return new InformativeCommandLineTestHost(0, serviceProvider); @@ -382,7 +368,7 @@ await LogTestHostCreatedAsync( // If --info is invoked we return if (commandLineHandler.IsInfoInvoked()) { - await commandLineHandler.PrintInfoAsync(platformOutputDevice, toolsInformation); + await commandLineHandler.PrintInfoAsync(proxyOutputDevice, toolsInformation); return new InformativeCommandLineTestHost(0, serviceProvider); } @@ -417,7 +403,7 @@ await LogTestHostCreatedAsync( var testHostControllersServiceProvider = (ServiceProvider)serviceProvider.Clone(); // Add the platform output device to the service provider. - testHostControllersServiceProvider.TryAddService(platformOutputDevice); + testHostControllersServiceProvider.TryAddService(proxyOutputDevice); // Add the message bus proxy specific for the launchers. testHostControllersServiceProvider.TryAddService(new MessageBusProxy()); @@ -832,7 +818,7 @@ private async Task RegisterAsServiceOrConsumerOrBothAsync(object service, Servic await AddServiceIfNotSkippedAsync(service, serviceProvider); } - private async Task DisplayBannerIfEnabledAsync(ApplicationLoggingState loggingState, IPlatformOutputDevice platformOutputDevice, + private async Task DisplayBannerIfEnabledAsync(ApplicationLoggingState loggingState, ProxyOutputDevice outputDevice, ITestFrameworkCapabilities testFrameworkCapabilities) { bool isNoBannerSet = loggingState.CommandLineParseResult.IsOptionSet(PlatformCommandLineProvider.NoBannerOptionKey); @@ -844,7 +830,8 @@ private async Task DisplayBannerIfEnabledAsync(ApplicationLoggingState loggingSt string? bannerMessage = bannerMessageOwnerCapability is not null ? await bannerMessageOwnerCapability.GetBannerMessageAsync() : null; - await platformOutputDevice.DisplayBannerAsync(bannerMessage); + + await outputDevice.DisplayBannerAsync(bannerMessage); } } } diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs index baa794cb23..9ee0415152 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs @@ -77,7 +77,7 @@ protected override async Task InternalRunAsync() ITelemetryCollector telemetry = ServiceProvider.GetTelemetryCollector(); ITelemetryInformation telemetryInformation = ServiceProvider.GetTelemetryInformation(); string? extensionInformation = null; - IPlatformOutputDevice platformOutputDevice = ServiceProvider.GetPlatformOutputDevice(); + var outputDevice = (ProxyOutputDevice)ServiceProvider.GetOutputDevice(); IConfiguration configuration = ServiceProvider.GetConfiguration(); try { @@ -203,7 +203,7 @@ protected override async Task InternalRunAsync() displayErrorMessageBuilder.AppendLine(CultureInfo.InvariantCulture, $"Provider '{extension.DisplayName}' (UID: {extension.Uid}) failed with error: {errorMessage}"); } - await platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(displayErrorMessageBuilder.ToString())); + await outputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(displayErrorMessageBuilder.ToString())); await _logger.LogErrorAsync(logErrorMessageBuilder.ToString()); return ExitCodes.InvalidPlatformSetup; } @@ -306,7 +306,7 @@ protected override async Task InternalRunAsync() await messageBusProxy.DisableAsync(); } - await platformOutputDevice.DisplayAfterSessionEndRunAsync(); + await outputDevice.DisplayAfterSessionEndRunAsync(); // We collect info about the extensions before the dispose to avoid possible issue with cleanup. if (telemetryInformation.IsEnabled) @@ -322,7 +322,7 @@ protected override async Task InternalRunAsync() if (!_testHostGracefullyClosed && !abortRun.IsCancellationRequested) { - await platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, PlatformResources.TestProcessDidNotExitGracefullyErrorMessage, exitCode))); + await outputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, PlatformResources.TestProcessDidNotExitGracefullyErrorMessage, exitCode))); } await _logger.LogInformationAsync($"TestHostControllersTestHost ended with exit code '{exitCode}' (real test host exit code '{testHostProcess.ExitCode}')' in '{consoleRunStarted.Elapsed}'"); diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs index d39d047676..b0ed844cc8 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs @@ -20,12 +20,12 @@ internal sealed class ToolsTestHost( IReadOnlyList toolsInformation, ServiceProvider serviceProvider, CommandLineHandler commandLineHandler, - IPlatformOutputDevice platformOutputDevice) : ITestHost, IOutputDeviceDataProducer + IOutputDevice outputDevice) : ITestHost, IOutputDeviceDataProducer { private readonly IReadOnlyList _toolsInformation = toolsInformation; private readonly ServiceProvider _serviceProvider = serviceProvider; private readonly CommandLineHandler _commandLineHandler = commandLineHandler; - private readonly IPlatformOutputDevice _platformOutputDevice = platformOutputDevice; + private readonly IOutputDevice _outputDevice = outputDevice; /// public string Uid => nameof(ToolsTestHost); @@ -64,21 +64,21 @@ public async Task RunAsync() { if (UnknownOptions(out string? unknownOptionsError, tool)) { - await _platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(unknownOptionsError)); + await _outputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(unknownOptionsError)); console.WriteLine(); return ExitCodes.InvalidCommandLine; } if (ExtensionArgumentArityAreInvalid(out string? arityErrors, tool)) { - await _platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(arityErrors)); + await _outputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(arityErrors)); return ExitCodes.InvalidCommandLine; } ValidationResult optionsArgumentsValidationResult = await ValidateOptionsArgumentsAsync(tool); if (!optionsArgumentsValidationResult.IsValid) { - await _platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(optionsArgumentsValidationResult.ErrorMessage)); + await _outputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(optionsArgumentsValidationResult.ErrorMessage)); return ExitCodes.InvalidCommandLine; } @@ -86,8 +86,8 @@ public async Task RunAsync() } } - await _platformOutputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData($"Tool '{toolNameToRun}' not found in the list of registered tools.")); - await _commandLineHandler.PrintHelpAsync(_platformOutputDevice); + await _outputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData($"Tool '{toolNameToRun}' not found in the list of registered tools.")); + await _commandLineHandler.PrintHelpAsync(_outputDevice); return ExitCodes.InvalidCommandLine; } diff --git a/src/Platform/Microsoft.Testing.Platform/Logging/ServerLoggerForwarder.cs b/src/Platform/Microsoft.Testing.Platform/Logging/ServerLoggerForwarder.cs deleted file mode 100644 index a3a69548d2..0000000000 --- a/src/Platform/Microsoft.Testing.Platform/Logging/ServerLoggerForwarder.cs +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#if NETCOREAPP -using System.Diagnostics.CodeAnalysis; -using System.Threading.Channels; -#else -using System.Collections.Concurrent; -using System.Diagnostics.CodeAnalysis; -#endif -using System.Globalization; - -using Microsoft.Testing.Platform.Helpers; -using Microsoft.Testing.Platform.Hosts; -using Microsoft.Testing.Platform.Resources; - -namespace Microsoft.Testing.Platform.Logging; - -/// -/// This logger forwards the messages back to the server host so that they're -/// logged over RPC back to the client. -/// -internal sealed class ServerLoggerForwarder : ILogger, IDisposable -#if NETCOREAPP -#pragma warning disable SA1001 // Commas should be spaced correctly - , IAsyncDisposable -#pragma warning restore SA1001 // Commas should be spaced correctly -#endif -{ - private readonly LogLevel _logLevel; - private readonly IServerTestHost _serverTestHost; - private readonly Task _logLoop; -#if NETCOREAPP - private readonly Channel? _channel; -#else - private readonly BlockingCollection? _asyncLogs; -#endif - - private bool _isDisposed; - - // NOTE: We have to take the service provider because when the logger is created, the ServerTestHost is not yet registered. - public ServerLoggerForwarder(LogLevel logLevel, ITask task, IServerTestHost serverTestHost) - { - _logLevel = logLevel; - _serverTestHost = serverTestHost; -#if NETCOREAPP - _channel = Channel.CreateUnbounded(new UnboundedChannelOptions - { - // We process only 1 data at a time - SingleReader = true, - - // We don't know how many threads will call the Log method - SingleWriter = false, - - // We want to unlink the caller from the consumer - AllowSynchronousContinuations = false, - }); -#else - _asyncLogs = []; -#endif - _logLoop = task.Run(WriteLogMessageAsync, CancellationToken.None); - } - - private async Task WriteLogMessageAsync() - { -#if NETCOREAPP - // We do this check out of the try because we want to crash the process if the _channel is null. - ApplicationStateGuard.Ensure(_channel is not null); - - // We don't need cancellation token because the task will be stopped when the Channel is completed thanks to the call to Complete() inside the Dispose method. - while (await _channel.Reader.WaitToReadAsync()) - { - await PushServerLogMessageToTheMessageBusAsync(await _channel.Reader.ReadAsync()); - } -#else - ApplicationStateGuard.Ensure(_asyncLogs is not null); - - // We don't need cancellation token because the task will be stopped when the BlockingCollection is completed thanks to the call to CompleteAdding() - // inside the Dispose method. - foreach (ServerLogMessage message in _asyncLogs.GetConsumingEnumerable()) - { - await PushServerLogMessageToTheMessageBusAsync(message); - } -#endif - } - - public bool IsEnabled(LogLevel logLevel) => logLevel >= _logLevel; - - public void Log(LogLevel logLevel, TState state, Exception? exception, Func formatter) - { - if (!IsEnabled(logLevel)) - { - return; - } - - string message = formatter(state, exception); - ServerLogMessage logMessage = new(logLevel, message); - EnsureAsyncLogObjectsAreNotNull(); -#if NETCOREAPP - if (!_channel.Writer.TryWrite(logMessage)) - { - throw new InvalidOperationException("Failed to write the log to the channel"); - } -#else - _asyncLogs.Add(logMessage); -#endif - } - - public async Task LogAsync(LogLevel logLevel, TState state, Exception? exception, Func formatter) - { - if (!IsEnabled(logLevel)) - { - return; - } - - string message = formatter(state, exception); - ServerLogMessage logMessage = new(logLevel, message); - await PushServerLogMessageToTheMessageBusAsync(logMessage); - } - - private async Task PushServerLogMessageToTheMessageBusAsync(ServerLogMessage logMessage) - => await _serverTestHost.PushDataAsync(logMessage); - -#if NETCOREAPP - [MemberNotNull(nameof(_channel), nameof(_logLoop))] - private void EnsureAsyncLogObjectsAreNotNull() - { - ApplicationStateGuard.Ensure(_channel is not null); - ApplicationStateGuard.Ensure(_logLoop is not null); - } -#else - [MemberNotNull(nameof(_asyncLogs), nameof(_logLoop))] - private void EnsureAsyncLogObjectsAreNotNull() - { - ApplicationStateGuard.Ensure(_asyncLogs is not null); - ApplicationStateGuard.Ensure(_logLoop is not null); - } -#endif - - public void Dispose() - { - if (_isDisposed) - { - return; - } - - EnsureAsyncLogObjectsAreNotNull(); -#if NETCOREAPP - // Wait for all logs to be written - bool result = _channel.Writer.TryComplete(); - if (!_logLoop.Wait(TimeoutHelper.DefaultHangTimeSpanTimeout)) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, PlatformResources.TimeoutFlushingLogsErrorMessage, TimeoutHelper.DefaultHangTimeoutSeconds)); - } -#else - // Wait for all logs to be written - _asyncLogs.CompleteAdding(); - if (!_logLoop.Wait(TimeoutHelper.DefaultHangTimeSpanTimeout)) - { - throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, PlatformResources.TimeoutFlushingLogsErrorMessage, TimeoutHelper.DefaultHangTimeoutSeconds)); - } -#endif - _isDisposed = true; - } - -#if NETCOREAPP - public async ValueTask DisposeAsync() - { - if (_isDisposed) - { - return; - } - - EnsureAsyncLogObjectsAreNotNull(); - - // Wait for all logs to be written - _channel.Writer.TryComplete(); - await _logLoop.TimeoutAfterAsync(TimeoutHelper.DefaultHangTimeSpanTimeout); - _isDisposed = true; - } -#endif -} diff --git a/src/Platform/Microsoft.Testing.Platform/Logging/ServerLoggerForwarderProvider.cs b/src/Platform/Microsoft.Testing.Platform/Logging/ServerLoggerForwarderProvider.cs deleted file mode 100644 index 8b2ffaff02..0000000000 --- a/src/Platform/Microsoft.Testing.Platform/Logging/ServerLoggerForwarderProvider.cs +++ /dev/null @@ -1,35 +0,0 @@ -// 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.Testing.Platform.Hosts; -using Microsoft.Testing.Platform.Services; - -namespace Microsoft.Testing.Platform.Logging; - -internal sealed class ServerLoggerForwarderProvider(LogLevel logLevel, IServiceProvider serviceProvider) - : ILoggerProvider -{ - private readonly LogLevel _logLevel = logLevel; - private readonly ServerLogMessageInMemoryStore _serverLogMessageInMemoryStore = new(logLevel); - - private ServerTestHost? _serverTestHost; - - // If we don't have the server test host, we just log to the in-memory store. - public ILogger CreateLogger(string categoryName) - => _serverTestHost is null - ? _serverLogMessageInMemoryStore - : new ServerLoggerForwarder(_logLevel, serviceProvider.GetTask(), _serverTestHost); - - public async Task InitializeAsync(ServerTestHost serverTestHost) - { - _serverTestHost = serverTestHost; - _serverLogMessageInMemoryStore.Initialize(serverTestHost); - - foreach (ServerLogMessage serverLogMessage in _serverLogMessageInMemoryStore) - { - await _serverTestHost.PushDataAsync(serverLogMessage); - } - - _serverLogMessageInMemoryStore.Clean(); - } -} diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/IPlatformOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/IPlatformOutputDevice.cs index ac87b96c2a..25d1bf12ae 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/IPlatformOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/IPlatformOutputDevice.cs @@ -2,14 +2,17 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using Microsoft.Testing.Platform.Extensions; +using Microsoft.Testing.Platform.Extensions.OutputDevice; namespace Microsoft.Testing.Platform.OutputDevice; -internal interface IPlatformOutputDevice : IExtension, IOutputDevice +internal interface IPlatformOutputDevice : IExtension { Task DisplayBannerAsync(string? bannerMessage); Task DisplayBeforeSessionStartAsync(); Task DisplayAfterSessionEndRunAsync(); + + Task DisplayAsync(IOutputDeviceDataProducer producer, IOutputDeviceData data); } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs index 3c13dcc4a2..d3e09c4e8b 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs @@ -1,6 +1,7 @@ // 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.Testing.Platform.ServerMode; using Microsoft.Testing.Platform.Services; namespace Microsoft.Testing.Platform.OutputDevice; @@ -15,15 +16,21 @@ public void SetPlatformOutputDevice(Func BuildAsync(ServiceProvider serviceProvider, bool useServerModeOutputDevice) { - if (_platformOutputDeviceFactory is not null) + // TODO: SetPlatformOutputDevice isn't public yet. + // Before exposing it, do we want to pass the "useServerModeOutputDevice" info to it? + IPlatformOutputDevice nonServerOutputDevice = _platformOutputDeviceFactory is null + ? GetDefaultTerminalOutputDevice(serviceProvider) + : _platformOutputDeviceFactory(serviceProvider); + + // If the externally provided output device is not enabled, we opt-in the default terminal output device. + if (_platformOutputDeviceFactory is not null && !await nonServerOutputDevice.IsEnabledAsync()) { - IPlatformOutputDevice platformOutputDevice = _platformOutputDeviceFactory(serviceProvider); - return platformOutputDevice; + nonServerOutputDevice = GetDefaultTerminalOutputDevice(serviceProvider); } - return GetDefaultTerminalOutputDevice(serviceProvider); + return new ProxyOutputDevice(nonServerOutputDevice, useServerModeOutputDevice ? new ServerModePerCallOutputDevice(serviceProvider) : null); } public static TerminalOutputDevice GetDefaultTerminalOutputDevice(ServiceProvider serviceProvider) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/ProxyOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/ProxyOutputDevice.cs new file mode 100644 index 0000000000..6896debd84 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/ProxyOutputDevice.cs @@ -0,0 +1,65 @@ +// 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.Testing.Platform.Extensions.OutputDevice; +using Microsoft.Testing.Platform.Hosts; +using Microsoft.Testing.Platform.ServerMode; + +namespace Microsoft.Testing.Platform.OutputDevice; + +internal sealed class ProxyOutputDevice : IOutputDevice +{ + private readonly ServerModePerCallOutputDevice? _serverModeOutputDevice; + + public ProxyOutputDevice(IPlatformOutputDevice originalOutputDevice, ServerModePerCallOutputDevice? serverModeOutputDevice) + { + OriginalOutputDevice = originalOutputDevice; + _serverModeOutputDevice = serverModeOutputDevice; + } + + internal IPlatformOutputDevice OriginalOutputDevice { get; } + + public async Task DisplayAsync(IOutputDeviceDataProducer producer, IOutputDeviceData data) + { + await OriginalOutputDevice.DisplayAsync(producer, data); + if (_serverModeOutputDevice is not null) + { + await _serverModeOutputDevice.DisplayAsync(producer, data); + } + } + + internal async Task DisplayBannerAsync(string? bannerMessage) + { + await OriginalOutputDevice.DisplayBannerAsync(bannerMessage); + if (_serverModeOutputDevice is not null) + { + await _serverModeOutputDevice.DisplayBannerAsync(bannerMessage); + } + } + + internal async Task DisplayBeforeSessionStartAsync() + { + await OriginalOutputDevice.DisplayBeforeSessionStartAsync(); + if (_serverModeOutputDevice is not null) + { + await _serverModeOutputDevice.DisplayBeforeSessionStartAsync(); + } + } + + internal async Task DisplayAfterSessionEndRunAsync() + { + await OriginalOutputDevice.DisplayAfterSessionEndRunAsync(); + if (_serverModeOutputDevice is not null) + { + await _serverModeOutputDevice.DisplayAfterSessionEndRunAsync(); + } + } + + internal async Task InitializeAsync(ServerTestHost serverTestHost) + { + if (_serverModeOutputDevice is not null) + { + await _serverModeOutputDevice.InitializeAsync(serverTestHost); + } + } +} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx index 5bd7f79c1a..3ae6c7d53f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx +++ b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx @@ -671,4 +671,27 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is The configuration file '{0}' specified with '--config-file' could not be found. - + + Starting test session. + + + Starting test session. The log file path is '{0}'. + + + Finished test session. + + + Server mode test host + + + The 'ITestHost' implementation used when running server mode. + + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + + + Exception during the cancellation of request id '{0}' + {0} is the request id + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index fcbdab68b9..4526c31089 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -219,6 +219,11 @@ Zprostředkovatel {0} (UID: {1}) selhal s chybou: {2}. + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code Ukončovací kód @@ -271,6 +276,11 @@ selhalo s {0} upozorněním(i). + + Finished test session. + Finished test session. + + For test Pro testování @@ -633,6 +643,16 @@ Může mít jenom jeden argument jako řetězec ve formátu <value>[h|m|s] Objekt pro vytváření filtru provádění testů serveru + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' Nelze najít službu typu {0}. @@ -688,6 +708,16 @@ Může mít jenom jeden argument jako řetězec ve formátu <value>[h|m|s] Spouští se server. Naslouchání na portu {0} + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set Objekt pro vytváření ITestExecutionFilterFactory je už nastavený. @@ -897,6 +927,11 @@ Platné hodnoty jsou Normal a Detailed. Výchozí hodnota je Normal. Komunikační protokol {0} není podporován. + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} Toto umístění programu se považuje za nedostupné. File={0}, Line={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index 4cc60a09ab..ce0825be7a 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -219,6 +219,11 @@ Anbieter "{0}" (UID: {1}) ist mit folgendem Fehler fehlgeschlagen: {2} + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code Exitcode @@ -271,6 +276,11 @@ fehlerhaft mit {0} Warnung(en) + + Finished test session. + Finished test session. + + For test Für Test @@ -633,6 +643,16 @@ Nimmt ein Argument als Zeichenfolge im Format <value>[h|m|s], wobei "value Ausführungsfilterfactory des Servertests + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' Der Dienst vom Typ "{0}" wurde nicht gefunden. @@ -688,6 +708,16 @@ Nimmt ein Argument als Zeichenfolge im Format <value>[h|m|s], wobei "value Server wird gestartet. An Port "{0}" lauschen + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set Eine "ITestExecutionFilterFactory"-Factory ist bereits festgelegt @@ -897,6 +927,11 @@ Gültige Werte sind „Normal“, „Detailed“. Der Standardwert ist „Normal Das Kommunikationsprotokoll "{0}" wird nicht unterstützt + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} Dieser Programmspeicherort wird als nicht erreichbar betrachtet. File='{0}' Line={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index e77b5cb8a2..095d36bf98 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -219,6 +219,11 @@ Error del proveedor "{0}" (UID: {1}) con el error: {2} + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code Código de salida @@ -271,6 +276,11 @@ error con {0} advertencias + + Finished test session. + Finished test session. + + For test Para prueba @@ -633,6 +643,16 @@ Toma un argumento como cadena con el formato <value>[h|m|s] donde 'value' Fábrica de filtros de ejecución de pruebas de servidor + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' No se encuentra el servicio de tipo '{0}' @@ -688,6 +708,16 @@ Toma un argumento como cadena con el formato <value>[h|m|s] donde 'value' Iniciando el servidor. Escuchando en el puerto '{0}' + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set Ya se ha establecido una fábrica "ITestExecutionFilterFactory" @@ -897,6 +927,11 @@ Los valores válidos son 'Normal', 'Detallado'. El valor predeterminado es 'Norm No se admite el protocolo de comunicación '{0}' + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} Se considera que esta ubicación del programa es inaccesible. Archivo=''{0}'' Línea={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index cd2f8e18d6..2b23f3d009 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -219,6 +219,11 @@ Désolé, échec de l’« {0} » du fournisseur (UID : {1}) avec l’erreur : {2} + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code Code de sortie @@ -271,6 +276,11 @@ a échoué avec {0} avertissement(s) + + Finished test session. + Finished test session. + + For test Pour le test @@ -633,6 +643,16 @@ Prend un argument sous forme de chaîne au format <value>[h|m|s] où « v Fabrique de filtres d’exécution de tests du serveur + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' Service de type « {0} » introuvable @@ -688,6 +708,16 @@ Prend un argument sous forme de chaîne au format <value>[h|m|s] où « v Démarrage du serveur. Écoute sur le port « {0} » + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set Désolé, une fabrique « ITestExecutionFilterFactory » est déjà définie @@ -897,6 +927,11 @@ Les valeurs valides sont « Normal » et « Détaillé ». La valeur par dé Le protocole de communication « {0} » n’est pas pris en charge + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} Cet emplacement du programme est considéré comme inaccessible. File=« {0} », Ligne={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index 9f2e5fd171..f8450b7534 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -219,6 +219,11 @@ Provider '{0}' (UID: {1}) non riuscito con errore: {2} + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code Codice di uscita @@ -271,6 +276,11 @@ non riuscito con {0} avvisi + + Finished test session. + Finished test session. + + For test Per test @@ -633,6 +643,16 @@ Acquisisce un argomento come stringa nel formato <value>[h|m|s] dove 'valu Factory del filtro per l'esecuzione dei test del server + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' Impossibile trovare il servizio di tipo '{0}' @@ -688,6 +708,16 @@ Acquisisce un argomento come stringa nel formato <value>[h|m|s] dove 'valu Avvio del server. In ascolto sulla porta '{0}' + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set È già impostata una factory 'ITestExecutionFilterFactory' @@ -897,6 +927,11 @@ I valori validi sono 'Normal', 'Detailed'. L'impostazione predefinita è 'Normal Il protocollo di comunicazione '{0}' non è supportato + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} La posizione del programma è ritenuta non raggiungibile. File='{0}', Riga={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index d506fc0e50..6411ac9405 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -219,6 +219,11 @@ プロバイダー '{0}' (UID: {1}) が次のエラーで失敗しました: {2} + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code 終了コード @@ -271,6 +276,11 @@ {0} 件の警告付きで失敗しました + + Finished test session. + Finished test session. + + For test テスト用 @@ -634,6 +644,16 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is サーバー テスト実行フィルター ファクトリ + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' '{0}' 型のサービスが見つかりません @@ -689,6 +709,16 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is サーバーを起動しています。ポート '{0}' で聞いています + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set 'ITestExecutionFilterFactory' ファクトリは既に設定されています @@ -898,6 +928,11 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. 通信プロトコル '{0}' はサポートされていません + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} このプログラムの場所に到達できないと考えられます。ファイル='{0}'、行={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index 4d044167b3..73ab4a51df 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -219,6 +219,11 @@ 공급자 '{0}'(UID: {1})이 오류 {2}(으)로 실패했습니다. + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code 종료 코드 @@ -271,6 +276,11 @@ {0} 경고와 함께 실패 + + Finished test session. + Finished test session. + + For test 테스트용 @@ -633,6 +643,16 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is 서버 테스트 실행 필터 팩터리 + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' '{0}' 형식의 서비스를 찾을 수 없습니다. @@ -688,6 +708,16 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is 서버를 시작하는 중입니다. 포트 '{0}'에서 수신 대기 중 + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set 'ITestExecutionFilterFactory' 팩터리가 이미 설정되어 있음 @@ -897,6 +927,11 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. 통신 프로토콜 '{0}'은(는) 지원되지 않습니다. + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} 이 프로그램 위치에 연결할 수 없는 것으로 생각됩니다. File='{0}' Line={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index f9085027fc..127548414d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -219,6 +219,11 @@ Dostawca „{0}” (UID:{1}) nie powiódł się z powodu błędu: {2} + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code Kod zakończenia @@ -271,6 +276,11 @@ zakończono niepowodzeniem, z ostrzeżeniami w liczbie: {0} + + Finished test session. + Finished test session. + + For test Na potrzeby testu @@ -633,6 +643,16 @@ Pobiera jeden argument jako ciąg w formacie <value>[h|m|s], gdzie element Fabryka filtrów wykonywania testów serwera + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' Nie można odnaleźć usługi typu „{0}” @@ -688,6 +708,16 @@ Pobiera jeden argument jako ciąg w formacie <value>[h|m|s], gdzie element Uruchamianie serwera. Nasłuchiwanie na porcie „{0}” + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set Fabryka „ITestExecutionFilterFactory” jest już ustawiona @@ -897,6 +927,11 @@ Prawidłowe wartości to „Normalne”, „Szczegółowe”. Wartość domyśln Protokół komunikacyjny „{0}” nie jest obsługiwany + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} Ta lokalizacja programu jest uważana za nieosiągalną. Plik=„{0}”, Wiersz={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index 1f4c3e9aeb..d303930104 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -219,6 +219,11 @@ O provedor ''{0}'' (UID: {1}) falhou com o erro: {2} + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code Código de saída @@ -271,6 +276,11 @@ falhou com {0} aviso(s) + + Finished test session. + Finished test session. + + For test Para teste @@ -633,6 +643,16 @@ Recebe um argumento como cadeia de caracteres no formato <valor>[h|m|s] em Fábrica de filtros de execução de teste de servidor + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' Não é possível localizar o serviço do tipo "{0}" @@ -688,6 +708,16 @@ Recebe um argumento como cadeia de caracteres no formato <valor>[h|m|s] em Iniciando servidor. Escutando na porta “{0}” + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set Uma fábrica “ITestExecutionFilterFactory” já está definida @@ -897,6 +927,11 @@ Os valores válidos são “Normal”, “Detalhado”. O padrão é “Normal O protocolo de comunicação “{0}” não tem suporte + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} Este local do programa é considerado inacessível. Arquivo='{0}' Linha={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index 48d7556f60..42539f5b67 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -219,6 +219,11 @@ Сбой поставщика "{0}" (ИД пользователя: {1}) с ошибкой: {2} + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code Код завершения @@ -271,6 +276,11 @@ сбой с предупреждениями ({0}) + + Finished test session. + Finished test session. + + For test Для тестирования @@ -633,6 +643,16 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Фабрика фильтров выполнения тестов сервера + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' Не удалось найти службу типа "{0}" @@ -688,6 +708,16 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Выполняется запуск сервера. Прослушивание порта "{0}" + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set Фабрика ITestExecutionFilterFactory уже настроена @@ -897,6 +927,11 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. Протокол коммуникации "{0}" не поддерживается + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} Похоже, что это расположение программы является недоступным. Файл="{0}", строка={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 6c74b00cf7..91326a0e25 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -219,6 +219,11 @@ '{0}' sağlayıcısı '' (UID: {1}) şu hatayla başarısız oldu: {2} + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code Çıkış kodu @@ -271,6 +276,11 @@ {0} uyarıyla başarısız oldu + + Finished test session. + Finished test session. + + For test Test için @@ -633,6 +643,16 @@ Bir bağımsız değişkeni, 'value' değerinin kayan olduğu <value>[h|m| Sunucu test yürütme filtresi fabrikası + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' '{0}' türündeki hizmet bulunamıyor @@ -688,6 +708,16 @@ Bir bağımsız değişkeni, 'value' değerinin kayan olduğu <value>[h|m| Sunucu başlatılıyor. '{0}' bağlantı noktasında dinleme işlemi yapılıyor + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set Bir 'ITestExecutionFilterFactory' fabrikası zaten ayarlanmış @@ -897,6 +927,11 @@ Geçerli değerler: ‘Normal’, ‘Ayrıntılı’. Varsayılan değer: ‘Nor '{0}' iletişim protokolü desteklenmiyor + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} Bu program konumu erişilemez olarak görülüyor. Dosya='{0}', Satır={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 35c5ef5311..3ee2239188 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -219,6 +219,11 @@ 提供程序 '{0}' (UID: {1}) 失败,出现错误: {2} + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code 退出代码 @@ -271,6 +276,11 @@ 失败,出现 {0} 警告 + + Finished test session. + Finished test session. + + For test 用于测试 @@ -633,6 +643,16 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is 服务器测试执行筛选工厂 + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' 找不到“{0}”类型的服务 @@ -688,6 +708,16 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is 正在启动服务器。正在侦听端口“{0}” + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set 已设置“ITestExecutionFilterFactory”工厂 @@ -897,6 +927,11 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. 不支持通信协议“{0}” + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} 此程序位置被视为无法访问。文件='{0}',行={1} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index 105285b9c3..80a74a1d82 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -219,6 +219,11 @@ 提供者 '{0}' (UID: {1}) 失敗,發生錯誤: {2} + + Exception during the cancellation of request id '{0}' + Exception during the cancellation of request id '{0}' + {0} is the request id + Exit code 結束代碼 @@ -271,6 +276,11 @@ 失敗,有 {0} 個警告 + + Finished test session. + Finished test session. + + For test 用於測試 @@ -633,6 +643,16 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is 伺服器測試執行篩選條件中心 + + The 'ITestHost' implementation used when running server mode. + The 'ITestHost' implementation used when running server mode. + + + + Server mode test host + Server mode test host + + Cannot find service of type '{0}' 找不到類型 '{0}' 的服務 @@ -688,6 +708,16 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is 正在啟動伺服器。正在連接埠 '{0}' 上聆聽 + + Starting test session. + Starting test session. + + + + Starting test session. The log file path is '{0}'. + Starting test session. The log file path is '{0}'. + + An 'ITestExecutionFilterFactory' factory is already set 已設定 'ITestExecutionFilterFactory' 中心 @@ -897,6 +927,11 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. 通訊協定 '{0}' 不受支援 + + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + {0} is the exception that was unhandled/unobserved + This program location is thought to be unreachable. File='{0}' Line={1} 此程式位置被認為無法連線。File='{0}' Line={1} diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs index 46f26549e2..091f782ad3 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs @@ -1,14 +1,52 @@ // 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.Concurrent; +using System.Globalization; +using System.Text; + using Microsoft.Testing.Platform.Extensions.OutputDevice; using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.Hosts; +using Microsoft.Testing.Platform.Logging; using Microsoft.Testing.Platform.OutputDevice; +using Microsoft.Testing.Platform.Resources; +using Microsoft.Testing.Platform.Services; namespace Microsoft.Testing.Platform.ServerMode; -internal class ServerModePerCallOutputDevice : IPlatformOutputDevice +internal sealed class ServerModePerCallOutputDevice : IPlatformOutputDevice { + private readonly IServiceProvider _serviceProvider; + private readonly ConcurrentBag _messages = new(); + + private IServerTestHost? _serverTestHost; + + private static readonly string[] NewLineStrings = { "\r\n", "\n" }; + + public ServerModePerCallOutputDevice(IServiceProvider serviceProvider) + => _serviceProvider = serviceProvider; + + internal async Task InitializeAsync(IServerTestHost serverTestHost) + { + // Server mode output device is basically used to send messages to Test Explorer. + // For that, it needs the ServerTestHost. + // However, the ServerTestHost is available later than the time we create the output device. + // So, the server mode output device is initially created early without the ServerTestHost, and + // it keeps any messages in a list. + // Later when ServerTestHost is created and is available, we initialize the server mode output device. + // The initialization will setup the right state for pushing to Test Explorer, and will push any existing + // messages to Test Explorer as well. + _serverTestHost = serverTestHost; + + foreach (ServerLogMessage message in _messages) + { + await LogAsync(message); + } + + _messages.Clear(); + } + public string Uid => nameof(ServerModePerCallOutputDevice); public string Version => AppVersion.DefaultSemVer; @@ -17,13 +55,98 @@ internal class ServerModePerCallOutputDevice : IPlatformOutputDevice public string Description => nameof(ServerModePerCallOutputDevice); - public Task DisplayAfterSessionEndRunAsync() => Task.CompletedTask; + public async Task DisplayAfterSessionEndRunAsync() + => await LogAsync(LogLevel.Trace, PlatformResources.FinishedTestSession, padding: null); + + public async Task DisplayAsync(IOutputDeviceDataProducer producer, IOutputDeviceData data) + { + switch (data) + { + case FormattedTextOutputDeviceData formattedTextOutputDeviceData: + await LogAsync(LogLevel.Information, formattedTextOutputDeviceData.Text, formattedTextOutputDeviceData.Padding); + break; + + case TextOutputDeviceData textOutputDeviceData: + await LogAsync(LogLevel.Information, textOutputDeviceData.Text, padding: null); + break; + + case WarningMessageOutputDeviceData warningData: + await LogAsync(LogLevel.Warning, warningData.Message, padding: null); + break; + + case ErrorMessageOutputDeviceData errorData: + await LogAsync(LogLevel.Error, errorData.Message, padding: null); + break; + + case ExceptionOutputDeviceData exceptionOutputDeviceData: + await LogAsync(LogLevel.Error, exceptionOutputDeviceData.Exception.ToString(), padding: null); + break; + } + } + + public async Task DisplayBannerAsync(string? bannerMessage) + { + if (bannerMessage is not null) + { + await LogAsync(LogLevel.Debug, bannerMessage, padding: null); + } + } + + public async Task DisplayBeforeSessionStartAsync() + { + if (_serviceProvider.GetService() is { FileLogger.FileName: { } logFileName }) + { + await LogAsync(LogLevel.Trace, string.Format(CultureInfo.InvariantCulture, PlatformResources.StartingTestSessionWithLogFilePath, logFileName), padding: null); + } + else + { + await LogAsync(LogLevel.Trace, PlatformResources.StartingTestSession, padding: null); + } + } + + public Task IsEnabledAsync() => Task.FromResult(true); + + private async Task LogAsync(LogLevel logLevel, string message, int? padding) + => await LogAsync(GetServerLogMessage(logLevel, message, padding)); + + private async Task LogAsync(ServerLogMessage message) + { + if (_serverTestHost is null) + { + _messages.Add(message); + } + else + { + await _serverTestHost.PushDataAsync(message); + } + } + + private static ServerLogMessage GetServerLogMessage(LogLevel logLevel, string message, int? padding) + => new(logLevel, GetIndentedMessage(message, padding)); + + private static string GetIndentedMessage(string message, int? padding) + { + int paddingValue = padding.GetValueOrDefault(); + if (paddingValue == 0) + { + return message; + } - public Task DisplayAsync(IOutputDeviceDataProducer producer, IOutputDeviceData data) => Task.CompletedTask; + string indent = new(' ', paddingValue); - public Task DisplayBannerAsync(string? bannerMessage) => Task.CompletedTask; + if (!message.Contains('\n')) + { + return indent + message; + } - public Task DisplayBeforeSessionStartAsync() => Task.CompletedTask; + string[] lines = message.Split(NewLineStrings, StringSplitOptions.None); + StringBuilder builder = new(); + foreach (string line in lines) + { + builder.Append(indent); + builder.AppendLine(line); + } - public Task IsEnabledAsync() => Task.FromResult(false); + return builder.ToString(); + } } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/LogsCollector.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/LogsCollector.cs index 037e12b643..b4846a5370 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/LogsCollector.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/LogsCollector.cs @@ -7,4 +7,5 @@ namespace Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; -public class LogsCollector : ConcurrentBag; +// Not using ConcurrentBag because it's unordered. +public class LogsCollector : BlockingCollection; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs index 9ca1e2813a..989d5feae1 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs @@ -40,7 +40,7 @@ public async Task DiscoverAndRun(string tfm) await Task.WhenAll(discoveryListener.WaitCompletion(), runListener.WaitCompletion()); Assert.AreEqual(1, discoveryCollector.TestNodeUpdates.Count(x => x.Node.NodeType == "action"), $"Wrong number of discovery"); Assert.AreEqual(2, runCollector.TestNodeUpdates.Count, $"Wrong number of updates"); - Assert.IsFalse(logs.IsEmpty, $"Logs are empty"); + Assert.IsFalse(logs.Count == 0, $"Logs are empty"); Assert.IsFalse(telemetry.IsEmpty, $"telemetry is empty"); await jsonClient.Exit(); Assert.AreEqual(0, await jsonClient.WaitServerProcessExit()); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj index 992db4d4d1..45b3af34c2 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj @@ -1,4 +1,4 @@ - + $(NetCurrent) @@ -11,7 +11,10 @@ + + + diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs new file mode 100644 index 0000000000..fc136a2958 --- /dev/null +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs @@ -0,0 +1,178 @@ +// 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.Text.RegularExpressions; + +using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; + +using MSTest.Acceptance.IntegrationTests.Messages.V100; + +namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; + +[TestGroup] +public sealed partial class ServerLoggingTests : ServerModeTestsBase +{ + private readonly TestAssetFixture _testAssetFixture; + + public ServerLoggingTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) + : base(testExecutionContext) => _testAssetFixture = testAssetFixture; + + public async Task RunningInServerJsonRpcModeShouldHaveOutputDeviceLogsPushedToTestExplorer() + { + string tfm = TargetFrameworks.NetCurrent.Arguments; + string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "ServerLoggingTests", tfm); + using TestingPlatformClient jsonClient = await StartAsServerAndConnectToTheClientAsync(testHost); + LogsCollector logs = new(); + jsonClient.RegisterLogListener(logs); + + InitializeResponse initializeResponseArgs = await jsonClient.Initialize(); + + TestNodeUpdateCollector discoveryCollector = new(); + ResponseListener discoveryListener = await jsonClient.DiscoverTests(Guid.NewGuid(), discoveryCollector.CollectNodeUpdates); + + TestNodeUpdateCollector runCollector = new(); + ResponseListener runListener = await jsonClient.RunTests(Guid.NewGuid(), runCollector.CollectNodeUpdates); + + await Task.WhenAll(discoveryListener.WaitCompletion(), runListener.WaitCompletion()); + Assert.IsFalse(logs.Count == 0, $"Logs are empty"); + string logsString = string.Join(Environment.NewLine, logs.Select(l => l.ToString())); + string logPath = LogFilePathRegex().Match(logsString).Groups[1].Value; + string port = PortRegex().Match(logsString).Groups[1].Value; + + Assert.AreEqual( + $$""" + Log { LogLevel = Information, Message = Connecting to client host '127.0.0.1' port '{{port}}' } + Log { LogLevel = Trace, Message = Starting test session. Log file path is '{{logPath}}'. } + Log { LogLevel = Error, Message = System.Exception: This is an exception output } + Log { LogLevel = Error, Message = This is a red output with padding set to 3 } + Log { LogLevel = Warning, Message = This is a yellow output with padding set to 2 } + Log { LogLevel = Information, Message = This is a blue output with padding set to 1 } + Log { LogLevel = Information, Message = This is normal text output. } + Log { LogLevel = Trace, Message = Finished test session } + Log { LogLevel = Trace, Message = Starting test session. Log file path is '{{logPath}}'. } + Log { LogLevel = Error, Message = System.Exception: This is an exception output } + Log { LogLevel = Error, Message = This is a red output with padding set to 3 } + Log { LogLevel = Warning, Message = This is a yellow output with padding set to 2 } + Log { LogLevel = Information, Message = This is a blue output with padding set to 1 } + Log { LogLevel = Information, Message = This is normal text output. } + Log { LogLevel = Trace, Message = Finished test session } + """, logsString); + } + + [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] + public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + { + private const string AssetName = "TestAssetFixture"; + + public string TargetAssetPath => GetAssetPath(AssetName); + + public override IEnumerable<(string ID, string Name, string Code)> GetAssetsToGenerate() + { + yield return (AssetName, AssetName, + Sources + .PatchTargetFrameworks(TargetFrameworks.All) + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); + } + + private const string Sources = """ +#file ServerLoggingTests.csproj + + + + $TargetFrameworks$ + Exe + true + enable + preview + + + + + + + +#file Program.cs + +using System; +using System.Threading.Tasks; +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Extensions.OutputDevice; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.OutputDevice; +using Microsoft.Testing.Platform.Services; + +public class Startup +{ + public static async Task Main(string[] args) + { + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, serviceProvider) => new DummyTestAdapter(serviceProvider)); + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); + } +} + +public class DummyTestAdapter : ITestFramework, IDataProducer, IOutputDeviceDataProducer +{ + private readonly IOutputDevice _outputDevice; + + public DummyTestAdapter(IServiceProvider serviceProvider) + { + _outputDevice = serviceProvider.GetOutputDevice(); + } + + public string Uid => nameof(DummyTestAdapter); + + public string Version => "2.0.0"; + + public string DisplayName => nameof(DummyTestAdapter); + + public string Description => nameof(DummyTestAdapter); + + public Task IsEnabledAsync() => Task.FromResult(true); + + public Type[] DataTypesProduced => new[] { typeof(TestNodeUpdateMessage) }; + + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + + public async Task ExecuteRequestAsync(ExecuteRequestContext context) + { + await _outputDevice.DisplayAsync(this, new ExceptionOutputDeviceData(new Exception("This is an exception output"))); + await _outputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData("This is a red output with padding set to 3") + { + ForegroundColor = new SystemConsoleColor() { ConsoleColor = ConsoleColor.Red }, + Padding = 3, + }); + + await _outputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData("This is a yellow output with padding set to 2") + { + ForegroundColor = new SystemConsoleColor() { ConsoleColor = ConsoleColor.Yellow }, + Padding = 2, + }); + + await _outputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData("This is a blue output with padding set to 1") + { + ForegroundColor = new SystemConsoleColor() { ConsoleColor = ConsoleColor.Blue }, + Padding = 1, + }); + + await _outputDevice.DisplayAsync(this, new TextOutputDeviceData("This is normal text output.")); + context.Complete(); + } +} +"""; + } + + [GeneratedRegex("Connecting to client host '127.0.0.1' port '(\\d+)'")] + private static partial Regex PortRegex(); + + [GeneratedRegex("The log file path is '(.+?)'")] + private static partial Regex LogFilePathRegex(); +} diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/ServerLoggerForwarderTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/ServerLoggerForwarderTests.cs deleted file mode 100644 index 10be06a371..0000000000 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/ServerLoggerForwarderTests.cs +++ /dev/null @@ -1,57 +0,0 @@ -// 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.Globalization; - -using Microsoft.Testing.Platform.Extensions.Messages; -using Microsoft.Testing.Platform.Helpers; -using Microsoft.Testing.Platform.Hosts; -using Microsoft.Testing.Platform.Logging; -using Microsoft.Testing.Platform.Services; - -using Moq; - -namespace Microsoft.Testing.Platform.UnitTests; - -[TestGroup] -public class ServerLoggerForwarderTests : TestBase -{ - private const string Message = "Dummy"; - - private static readonly Func Formatter = - (state, exception) => - string.Format(CultureInfo.InvariantCulture, "{0}{1}", state, exception is not null ? $" -- {exception}" : string.Empty); - - private readonly Mock _mockServerTestHost = new(); - private readonly ServiceProvider _serviceProvider = new(); - - public ServerLoggerForwarderTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - _mockServerTestHost.Setup(x => x.PushDataAsync(It.IsAny())).Returns(Task.CompletedTask); - _serviceProvider.AddService(new SystemTask()); - _serviceProvider.AddService(_mockServerTestHost.Object); - } - - [ArgumentsProvider(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers))] - public void ServerLoggerForwarder_Log(LogLevel defaultLevel, LogLevel currentLevel) - { - using (ServerLoggerForwarder serverLoggerForwarder = new(defaultLevel, new SystemTask(), _mockServerTestHost.Object)) - { - serverLoggerForwarder.Log(currentLevel, Message, null, Formatter); - } - - _mockServerTestHost.Verify(x => x.PushDataAsync(It.IsAny()), LogTestHelpers.GetExpectedLogCallTimes(defaultLevel, currentLevel)); - } - - [ArgumentsProvider(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers))] - public async Task ServerLoggerForwarder_LogAsync(LogLevel defaultLevel, LogLevel currentLevel) - { - using (ServerLoggerForwarder serverLoggerForwarder = new(defaultLevel, new SystemTask(), _mockServerTestHost.Object)) - { - await serverLoggerForwarder.LogAsync(currentLevel, Message, null, Formatter); - } - - _mockServerTestHost.Verify(x => x.PushDataAsync(It.IsAny()), LogTestHelpers.GetExpectedLogCallTimes(defaultLevel, currentLevel)); - } -} From 4f809f5cea16664c7e1226bc59d5cc05a543b5a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 4 Dec 2024 14:01:36 +0100 Subject: [PATCH 056/273] Bump version in samples (#4232) --- samples/public/Directory.Build.props | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/samples/public/Directory.Build.props b/samples/public/Directory.Build.props index a5c07027eb..3dff110b22 100644 --- a/samples/public/Directory.Build.props +++ b/samples/public/Directory.Build.props @@ -1,13 +1,13 @@ - 8.1.0 - 17.12.6 - 3.6.2 + 8.2.2 + 17.13.1 + 3.6.4 1.0.0-alpha.24530.4 - 1.45.1 - 1.4.2 - 17.11.1 + 1.49.0 + 1.4.3 + 17.12.0 From 11a9ef7c9e1f17f445e3b7af330c9a5a20871f6a Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 4 Dec 2024 14:32:06 +0100 Subject: [PATCH 057/273] Sort UnsupportedRunConfigurationSettings (#4234) --- .../ObjectModel/RunSettingsAdapter.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs index 5eff0ec573..9e63be64bc 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs @@ -25,15 +25,15 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; internal sealed class RunSettingsAdapter : IRunSettings { private static readonly string[] UnsupportedRunConfigurationSettings = [ + "DotnetHostPath", "MaxCpuCount", "TargetFrameworkVersion", "TargetPlatform", - "TreatTestAdapterErrorsAsWarnings", "TestAdaptersPaths", "TestCaseFilter", "TestSessionTimeout", - "DotnetHostPath", "TreatNoTestsAsError", + "TreatTestAdapterErrorsAsWarnings", ]; public RunSettingsAdapter( From 52bcabf439b2a01c351efee014054ba09d68544b Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 4 Dec 2024 14:48:46 +0100 Subject: [PATCH 058/273] [main] Update dependencies from devdiv/DevDiv/vs-code-coverage (#4236) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index f289bc1aeb..ce94efb7de 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,9 +13,9 @@ https://github.com/dotnet/arcade e8de3415124309210e4cbd0105e4a9da8dc01696 - + https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage - a657d717d57fcaf8f3ab3330b168f420e92b7a42 + d9ab1aae37bfdcc5ba1f0b2ecf45be1058673059 https://github.com/microsoft/testanywhere diff --git a/eng/Versions.props b/eng/Versions.props index 8abc136c95..c9cdbbb16a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,7 +8,7 @@ 10.0.0-beta.24578.2 - 17.13.1-preview.24603.1 + 17.13.2-preview.24603.5 1.5.0-preview.24603.5 1.0.0-alpha.24473.2 From 42f423b84ab1c792adff1442747caef0bfd07221 Mon Sep 17 00:00:00 2001 From: Marco Rossignoli Date: Thu, 5 Dec 2024 14:55:13 +0100 Subject: [PATCH 059/273] Fix server mode in playground (#4243) Co-authored-by: Marco Rossignoli --- samples/Playground/Program.cs | 5 +- .../TestingPlatformClientFactory.cs | 80 ------------------- 2 files changed, 3 insertions(+), 82 deletions(-) diff --git a/samples/Playground/Program.cs b/samples/Playground/Program.cs index c285308345..b333df12e7 100644 --- a/samples/Playground/Program.cs +++ b/samples/Playground/Program.cs @@ -28,6 +28,7 @@ public static async Task Main(string[] args) { // To attach to the children Microsoft.Testing.TestInfrastructure.DebuggerUtility.AttachCurrentProcessToParentVSProcess(); + ITestApplicationBuilder testApplicationBuilder = await TestApplication.CreateBuilderAsync(args); // Test MSTest @@ -37,7 +38,7 @@ public static async Task Main(string[] args) // testApplicationBuilder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, _) => new DummyAdapter()); // Custom test host controller extension - testApplicationBuilder.TestHostControllers.AddProcessLifetimeHandler(s => new OutOfProc(s.GetMessageBus())); + // testApplicationBuilder.TestHostControllers.AddProcessLifetimeHandler(s => new OutOfProc(s.GetMessageBus())); // Enable Trx // testApplicationBuilder.AddTrxReportProvider(); @@ -50,7 +51,7 @@ public static async Task Main(string[] args) else { Environment.SetEnvironmentVariable("TESTSERVERMODE", "0"); - using TestingPlatformClient client = await TestingPlatformClientFactory.StartAsServerAndConnectAsync(Environment.ProcessPath!, enableDiagnostic: true); + using TestingPlatformClient client = await TestingPlatformClientFactory.StartAsServerAndConnectToTheClientAsync(Environment.ProcessPath!); await client.InitializeAsync(); List testNodeUpdates = new(); diff --git a/samples/Playground/ServerMode/TestingPlatformClientFactory.cs b/samples/Playground/ServerMode/TestingPlatformClientFactory.cs index a5f432d990..fe054644f3 100644 --- a/samples/Playground/ServerMode/TestingPlatformClientFactory.cs +++ b/samples/Playground/ServerMode/TestingPlatformClientFactory.cs @@ -74,86 +74,6 @@ public static async Task StartAsServerAndConnectToTheClie return new TestingPlatformClient(new(tcpClient.GetStream()), tcpClient, processHandler); } - public static async Task StartAsServerAndConnectAsync(string testApp, bool enableDiagnostic = false) - { - var environmentVariables = new Dictionary(DefaultEnvironmentVariables); - foreach (DictionaryEntry entry in Environment.GetEnvironmentVariables()) - { - // Skip all unwanted environment variables. - string? key = entry.Key.ToString(); - if (WellKnownEnvironmentVariables.ToSkipEnvironmentVariables.Contains(key, StringComparer.OrdinalIgnoreCase)) - { - continue; - } - - environmentVariables[key!] = entry.Value!.ToString()!; - } - - // We expect to not fail for unhandled exception in server mode for IDE needs. - environmentVariables.Add("TESTINGPLATFORM_EXIT_PROCESS_ON_UNHANDLED_EXCEPTION", "0"); - - // To attach to the server on startup - // environmentVariables.Add(EnvironmentVariableConstants.TESTINGPLATFORM_LAUNCH_ATTACH_DEBUGGER, "1"); - TaskCompletionSource portFound = new(); - ProcessConfiguration processConfig = new(testApp) - { - OnStandardOutput = - (_, output) => - { - Match m = ParsePort().Match(output); - if (m.Success && int.TryParse(m.Groups[1].Value, out int port)) - { - portFound.SetResult(port); - } - - // Do not remove pls - // NotepadWindow.WriteLine($"[OnStandardOutput] {output}"); - }, - - // Do not remove pls - // OnErrorOutput = (_, output) => NotepadWindow.WriteLine($"[OnErrorOutput] {output}"), - OnErrorOutput = (_, output) => - { - if (!portFound.Task.IsCompleted) - { - try - { - portFound.SetException(new InvalidOperationException(output)); - } - catch (InvalidOperationException) - { - // possible race - } - } - }, - OnExit = (processHandle, exitCode) => - { - if (exitCode != 0) - { - if (portFound.Task.Exception is null && !portFound.Task.IsCompleted) - { - portFound.SetException(new InvalidOperationException($"Port not found during parsing and process exited with code '{exitCode}'")); - } - } - }, - - // OnExit = (_, exitCode) => NotepadWindow.WriteLine($"[OnExit] Process exit code '{exitCode}'"), - Arguments = "--server --diagnostic --diagnostic-verbosity trace", - // Arguments = "--server", - EnvironmentVariables = environmentVariables, - }; - - IProcessHandle processHandler = ProcessFactory.Start(processConfig, cleanDefaultEnvironmentVariableIfCustomAreProvided: false); - await portFound.Task; - - var tcpClient = new TcpClient(); - using CancellationTokenSource cancellationTokenSource = new(TimeSpan.FromSeconds(90)); -#pragma warning disable VSTHRD103 // Call async methods when in an async method - await tcpClient.ConnectAsync(new IPEndPoint(IPAddress.Loopback, portFound.Task.Result), cancellationTokenSource.Token); -#pragma warning restore VSTHRD103 // Call async methods when in an async method - return new TestingPlatformClient(new(tcpClient.GetStream()), tcpClient, processHandler, enableDiagnostic); - } - [GeneratedRegex(@"Starting server. Listening on port '(\d+)'")] private static partial Regex ParsePort(); } From 8e26da6634e74e3a25395822eb6225c450b0d790 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 13:59:47 +0000 Subject: [PATCH 060/273] [main] Update dependencies from dotnet/arcade (#4242) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 12 ++++++------ eng/Versions.props | 2 +- global.json | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ce94efb7de..9e478314de 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,17 +1,17 @@ - + https://github.com/dotnet/arcade - e8de3415124309210e4cbd0105e4a9da8dc01696 + 45d845e04c05fbe5da9838c454bbc3af1df6be81 - + https://github.com/dotnet/arcade - e8de3415124309210e4cbd0105e4a9da8dc01696 + 45d845e04c05fbe5da9838c454bbc3af1df6be81 - + https://github.com/dotnet/arcade - e8de3415124309210e4cbd0105e4a9da8dc01696 + 45d845e04c05fbe5da9838c454bbc3af1df6be81 https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage diff --git a/eng/Versions.props b/eng/Versions.props index c9cdbbb16a..27d46c27dc 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,7 +7,7 @@ preview - 10.0.0-beta.24578.2 + 10.0.0-beta.24604.4 17.13.2-preview.24603.5 1.5.0-preview.24603.5 diff --git a/global.json b/global.json index 05db535cd5..d853cca63e 100644 --- a/global.json +++ b/global.json @@ -26,7 +26,7 @@ "rollForward": "latestFeature" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.24578.2", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.24604.4", "MSBuild.Sdk.Extras": "3.0.44" } } From 7a760d8b593a183aef7aa040780ba8682a65d784 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 5 Dec 2024 07:09:44 -0800 Subject: [PATCH 061/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2595873 (#4246) --- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf index 09100d9ed2..563149bafd 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + "{0}" verwenden diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf index 2858582c3b..35e521fa47 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + Usar "{0}" diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf index 7ac61d85fa..99c1533bcf 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + '{0}' を使用します diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf index ea68841a9c..a4812d36aa 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + '{0}' 사용 diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf index bb4f55e225..dfe805fc24 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + Użyj „{0}” diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf index 0ebb07b529..afb8abcafd 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + Usar '{0}' diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf index b1c1938023..d81aae1484 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + Использовать "{0}" diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf index 07a03d4d10..e9a368cbae 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + '{0}' kullan From 5c721f568573da726fd0996b6f5db87d389ecfee Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 5 Dec 2024 07:10:05 -0800 Subject: [PATCH 062/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2595864 (#4245) From 2b15de2dee622188d57b38600ef951eaa6f8b164 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 5 Dec 2024 16:10:41 +0100 Subject: [PATCH 063/273] chore: seal internal classes when possible (#4235) --- .editorconfig | 1 + .../Discovery/AssemblyEnumerator.cs | 1 + .../Discovery/AssemblyEnumeratorWrapper.cs | 2 +- .../Discovery/TestMethodValidator.cs | 2 + .../Discovery/TypeEnumerator.cs | 2 + .../Discovery/TypeValidator.cs | 2 + .../Discovery/UnitTestDiscoverer.cs | 2 + .../Execution/RunCleanupResult.cs | 2 +- .../Execution/TestAssemblySettingsProvider.cs | 2 +- .../Execution/TestCaseDiscoverySink.cs | 2 +- .../Execution/TestMethodRunner.cs | 2 +- .../MSTest.TestAdapter/Execution/TypeCache.cs | 2 +- .../Execution/UnitTestRunner.cs | 2 +- .../Helpers/EnvironmentWrapper.cs | 2 +- .../Helpers/ReflectHelper.cs | 2 + .../Helpers/RunSettingsUtilities.cs | 2 +- .../ObjectModel/AdapterSettingsException.cs | 2 +- .../ObjectModel/StackTraceInformation.cs | 2 +- .../ObjectModel/TestAssemblySettings.cs | 2 +- .../ObjectModel/TestFailedException.cs | 2 +- .../ObjectModel/TestMethodOptions.cs | 2 +- .../ObjectModel/TypeInspectionException.cs | 2 +- .../ObjectModel/UnitTestElement.cs | 2 +- .../PlatformServiceProvider.cs | 2 +- .../SourceGeneratedDynamicDataOperations.cs | 2 +- .../MSTest.TestAdapter/TestMethodFilter.cs | 2 +- .../Constants.cs | 2 +- .../Data/TestDataConnectionFactory.cs | 4 +- .../Deployment/AssemblyLoadWorker.cs | 2 +- .../Deployment/DeploymentItem.cs | 2 +- .../Services/ReflectionOperations2.cs | 2 +- .../Services/ThreadSafeStringWriter.cs | 2 +- .../Utilities/AppDomainUtilities.cs | 2 +- .../Utilities/AppDomainWrapper.cs | 8 ++- .../Utilities/AssemblyUtility.cs | 3 +- .../Utilities/DeploymentItemUtility.cs | 2 +- .../Utilities/DeploymentUtility.cs | 6 +- .../Utilities/FileUtility.cs | 2 + .../Utilities/RandomIntPermutation.cs | 2 +- .../Utilities/ReflectionUtility.cs | 2 + .../Utilities/SequentialIntPermutation.cs | 2 +- .../Utilities/XmlUtilities.cs | 2 + .../BoundedCacheWithFactory.cs | 2 +- .../FailedTestInfoRequestSerializer.cs | 4 +- .../ModuleInfoRequestSerializer.cs | 4 +- .../RunSummaryRequestSerializer.cs | 4 +- .../AppInsightTelemetryClient.cs | 2 +- .../AppInsightTelemetryClientFactory.cs | 2 +- .../CIEnvironmentDetectorForTelemetry.cs | 2 +- .../Serializers/ReportFileNameSerializer.cs | 2 +- .../TestAdapterInformationsSerializer.cs | 4 +- .../TrxCompareTool.CommandLine.cs | 2 +- .../TrxCompareTool.cs | 2 +- .../TrxProcessLifetimeHandler.cs | 4 +- .../TrxTestApplicationLifecycleCallbacks.cs | 2 +- .../ObjectModel/FilterExpressionWrapper.cs | 2 +- .../Tasks/DotnetMuxerLocator.cs | 2 +- .../Tasks/InvokeTestingPlatformTask.cs | 2 +- .../Tasks/StackTraceHelper.cs | 2 +- ...EnvironmentVariablesConfigurationSource.cs | 2 +- .../Helpers/AsyncMonitorFactory.cs | 2 +- .../Helpers/System/SystemClock.cs | 2 +- .../Helpers/System/SystemRuntimeFeature.cs | 2 +- .../Hosts/TestFrameworkBuilderData.cs | 2 +- .../Hosts/TestHostBuilder.cs | 62 +++++++------------ .../Hosts/TestHostControlledHost.cs | 2 +- .../Hosts/TestHostOchestratorHost.cs | 2 +- .../IPC/Models/TestHostProcessExitRequest.cs | 2 +- .../IPC/Models/TestHostProcessPIDRequest.cs | 2 +- .../Logging/FileLoggerInformation.cs | 2 +- .../Logging/LoggerFactoryProxy.cs | 2 +- .../Messages/AsynchronousMessageBus.cs | 2 +- .../Messages/ChannelConsumerDataProcessor.cs | 2 +- ...onsumingEnumerableConsumerDataProcessor.cs | 2 +- .../Messages/PropertyBag.Property.cs | 2 +- .../OutputDevice/OutputDeviceManager.cs | 6 +- .../OutputDevice/Terminal/ErrorMessage.cs | 2 +- .../Terminal/ExceptionFlattener.cs | 4 +- .../OutputDevice/Terminal/TestRunArtifact.cs | 2 +- .../OutputDevice/Terminal/WarningMessage.cs | 2 +- .../OutputDevice/TerminalOutputDevice.cs | 8 +-- .../Requests/TestHostTestFrameworkInvoker.cs | 2 + .../DotnetTest/IPC/DotnetTestDataConsumer.cs | 6 +- .../ServerMode/JsonRpc/ErrorCodes.cs | 2 +- .../Json/JsonCollectionDeserializer.cs | 2 +- .../JsonRpc/Json/JsoniteProperties.cs | 2 +- .../JsonRpc/MessageHandlerFactory.cs | 2 +- .../ServerMode/JsonRpc/PassiveNode.cs | 2 +- .../JsonRpc/PerRequestTestSessionContext.cs | 2 +- .../ServerMode/JsonRpc/RpcMessages.cs | 52 ++++++++-------- .../JsonRpc/TestNodeStateChangeAggregator.cs | 2 +- .../CTRLPlusCCancellationTokenSource.cs | 2 +- .../ITestApplicationProcessExitCode.cs | 2 +- .../TestFramework/TestFrameworkManager.cs | 2 +- .../TestSessionLifetimeHandlersContainer.cs | 2 +- .../PassiveNodeDataConsumer.cs | 2 +- .../TestHostProcessInformation.cs | 2 +- .../TestHostOrchestratorManager.cs | 2 +- .../RuntimeTypeHelper.cs | 2 +- .../Assertions/CollectionAssert.cs | 2 +- .../MSTest.Performance.Runner/Steps/Files.cs | 2 +- 101 files changed, 180 insertions(+), 169 deletions(-) diff --git a/.editorconfig b/.editorconfig index be3939f63d..59a6b86f57 100644 --- a/.editorconfig +++ b/.editorconfig @@ -214,6 +214,7 @@ dotnet_diagnostic.CA1827.severity = warning # CA1827: Do not use Cou dotnet_diagnostic.CA1836.severity = warning # CA1836: Prefer IsEmpty over Count dotnet_diagnostic.CA1840.severity = warning # CA1840: Use 'Environment.CurrentManagedThreadId' dotnet_diagnostic.CA1852.severity = warning # CA1852: Seal internal types +dotnet_code_quality.CA1852.ignore_internalsvisibleto = true dotnet_diagnostic.CA1854.severity = warning # CA1854: Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method # Disabled as it's making the code complex to deal with when multi targeting dotnet_diagnostic.CA1863.severity = none # CA1863: Use 'CompositeFormat' diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs index 711bda3b0e..0b097fbe8a 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs @@ -20,6 +20,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; /// /// Enumerates through all types in the assembly in search of valid test methods. /// +[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "Overrides required for testability")] internal class AssemblyEnumerator : MarshalByRefObject { /// diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs index 357a0eb456..9c327d2a91 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs @@ -13,7 +13,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; /// /// Enumerates through an assembly to get a set of test methods. /// -internal class AssemblyEnumeratorWrapper +internal sealed class AssemblyEnumeratorWrapper { /// /// Assembly name for UTF. diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs index 861d108ab4..811868b2fc 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs @@ -1,6 +1,7 @@ // 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.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection; @@ -13,6 +14,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; /// /// Determines if a method is a valid test method. /// +[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "Overrides required for testability")] internal class TestMethodValidator { private readonly ReflectHelper _reflectHelper; diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs index 2cfc50d46b..847cf7e1fc 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs @@ -2,6 +2,7 @@ // 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; @@ -17,6 +18,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; /// /// Enumerates through the type looking for Valid Test Methods to execute. /// +[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "Overrides required for testability")] internal class TypeEnumerator { private readonly Type _type; diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs index f9f45eea1b..386891f596 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs @@ -1,6 +1,7 @@ // 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.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection; @@ -12,6 +13,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; /// /// Determines whether a type is a valid test class for this adapter. /// +[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "Overrides required for testability")] internal class TypeValidator { // Setting this to a string representation instead of a typeof(TestContext).FullName diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs b/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs index e9ff1ccdc1..bc669c1e79 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs @@ -1,6 +1,7 @@ // 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.Diagnostics.CodeAnalysis; using System.Globalization; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; @@ -12,6 +13,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; +[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "Overrides required for testability")] internal class UnitTestDiscoverer { private readonly AssemblyEnumeratorWrapper _assemblyEnumeratorWrapper; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/RunCleanupResult.cs b/src/Adapter/MSTest.TestAdapter/Execution/RunCleanupResult.cs index edf7534eff..11e1dedcea 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/RunCleanupResult.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/RunCleanupResult.cs @@ -7,7 +7,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// Result of the run cleanup operation. /// [Serializable] -internal class RunCleanupResult +internal sealed class RunCleanupResult { /// /// Gets or sets the standard out of the cleanup methods. diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblySettingsProvider.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblySettingsProvider.cs index 043ba32aa7..5c155daf58 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblySettingsProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblySettingsProvider.cs @@ -10,7 +10,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; -internal class TestAssemblySettingsProvider : MarshalByRefObject +internal sealed class TestAssemblySettingsProvider : MarshalByRefObject { /// /// Returns object to be used for controlling lifetime, null means infinite lifetime. diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestCaseDiscoverySink.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestCaseDiscoverySink.cs index 1ba6f9adbe..2c81c236a6 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestCaseDiscoverySink.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestCaseDiscoverySink.cs @@ -11,7 +11,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// The test case discovery sink. /// -internal class TestCaseDiscoverySink : ITestCaseDiscoverySink +internal sealed class TestCaseDiscoverySink : ITestCaseDiscoverySink { /// /// Initializes a new instance of the class. diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs index 69c590cdd9..017f45b100 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs @@ -22,7 +22,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// This class is responsible to running tests and converting framework TestResults to adapter TestResults. /// -internal class TestMethodRunner +internal sealed class TestMethodRunner { /// /// Test context which needs to be passed to the various methods of the test. diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index eb6124cf9d..5b07edca36 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -21,7 +21,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// Defines type cache which reflects upon a type and cache its test artifacts. /// -internal class TypeCache : MarshalByRefObject +internal sealed class TypeCache : MarshalByRefObject { /// /// Test context property name. diff --git a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs index fb0f910321..fae1a9d7bc 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs @@ -21,7 +21,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// The runner that runs a single unit test. Also manages the assembly and class cleanup methods at the end of the run. /// -internal class UnitTestRunner : MarshalByRefObject +internal sealed class UnitTestRunner : MarshalByRefObject { private readonly ConcurrentDictionary _fixtureTests = new(); private readonly TypeCache _typeCache; diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/EnvironmentWrapper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/EnvironmentWrapper.cs index 949291af0c..792366d479 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/EnvironmentWrapper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/EnvironmentWrapper.cs @@ -3,7 +3,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; -internal class EnvironmentWrapper : IEnvironment +internal sealed class EnvironmentWrapper : IEnvironment { public string MachineName => Environment.MachineName; } diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index 7bbf28454d..bf6ecc3d15 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Concurrent; +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection; using System.Security; @@ -13,6 +14,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; +[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "Overrides required for mocking")] internal class ReflectHelper : MarshalByRefObject { #pragma warning disable RS0030 // Do not use banned APIs diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/RunSettingsUtilities.cs b/src/Adapter/MSTest.TestAdapter/Helpers/RunSettingsUtilities.cs index 5f7e649824..62b5a7e147 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/RunSettingsUtilities.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/RunSettingsUtilities.cs @@ -11,7 +11,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; -internal class RunSettingsUtilities +internal static class RunSettingsUtilities { /// /// Gets the settings to be used while creating XmlReader for runsettings. diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/AdapterSettingsException.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/AdapterSettingsException.cs index 774406f04d..1942c45c2a 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/AdapterSettingsException.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/AdapterSettingsException.cs @@ -3,7 +3,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; -internal class AdapterSettingsException : Exception +internal sealed class AdapterSettingsException : Exception { internal AdapterSettingsException(string? message) : base(message) diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/StackTraceInformation.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/StackTraceInformation.cs index 4d68fef812..43923ec246 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/StackTraceInformation.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/StackTraceInformation.cs @@ -6,7 +6,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; [Serializable] -internal class StackTraceInformation +internal sealed class StackTraceInformation { public StackTraceInformation(string stackTrace) : this(stackTrace, null, 0, 0) diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestAssemblySettings.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestAssemblySettings.cs index f27c2e85af..5e9a68270d 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestAssemblySettings.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestAssemblySettings.cs @@ -6,7 +6,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; [Serializable] -internal class TestAssemblySettings +internal sealed class TestAssemblySettings { public TestAssemblySettings() => Workers = -1; diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestFailedException.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestFailedException.cs index 2e7373532c..1b11693dcc 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestFailedException.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestFailedException.cs @@ -9,7 +9,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; /// Internal class to indicate Test Execution failure. /// [Serializable] -internal class TestFailedException : Exception +internal sealed class TestFailedException : Exception { public TestFailedException(UnitTestOutcome outcome, string errorMessage) : this(outcome, errorMessage, null, null) diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs index c2ccd4e3c4..1c87933a6a 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs @@ -10,4 +10,4 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; /// /// A facade service for options passed to a test method. /// -internal record TestMethodOptions(TimeoutInfo TimeoutInfo, ExpectedExceptionBaseAttribute? ExpectedException, ITestContext? TestContext, bool CaptureDebugTraces, TestMethodAttribute? Executor); +internal sealed record TestMethodOptions(TimeoutInfo TimeoutInfo, ExpectedExceptionBaseAttribute? ExpectedException, ITestContext? TestContext, bool CaptureDebugTraces, TestMethodAttribute? Executor); diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/TypeInspectionException.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/TypeInspectionException.cs index aa269a088b..0e13ffe8e9 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/TypeInspectionException.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/TypeInspectionException.cs @@ -7,7 +7,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; /// Internal class to indicate type inspection failure. /// [Serializable] -internal class TypeInspectionException : Exception +internal sealed class TypeInspectionException : Exception { public TypeInspectionException() : base() diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs index 646d2b010a..30cb0945e8 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs @@ -16,7 +16,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; /// [Serializable] [DebuggerDisplay("{GetDisplayName()} ({TestMethod.ManagedTypeName})")] -internal class UnitTestElement +internal sealed class UnitTestElement { /// /// Initializes a new instance of the class. diff --git a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs index 8a91c6f5a6..32f77ac5b2 100644 --- a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs @@ -15,7 +15,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// /// The main service provider class that exposes all the platform services available. /// -internal class PlatformServiceProvider : IPlatformServiceProvider +internal sealed class PlatformServiceProvider : IPlatformServiceProvider { /// /// Initializes a new instance of the class - a singleton. diff --git a/src/Adapter/MSTest.TestAdapter/SourceGeneratedDynamicDataOperations.cs b/src/Adapter/MSTest.TestAdapter/SourceGeneratedDynamicDataOperations.cs index 96f1d4470e..79ec0ea968 100644 --- a/src/Adapter/MSTest.TestAdapter/SourceGeneratedDynamicDataOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/SourceGeneratedDynamicDataOperations.cs @@ -3,6 +3,6 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; -internal class SourceGeneratedDynamicDataOperations : DynamicDataOperations +internal sealed class SourceGeneratedDynamicDataOperations : DynamicDataOperations { } diff --git a/src/Adapter/MSTest.TestAdapter/TestMethodFilter.cs b/src/Adapter/MSTest.TestAdapter/TestMethodFilter.cs index 1076988370..862a71e0f1 100644 --- a/src/Adapter/MSTest.TestAdapter/TestMethodFilter.cs +++ b/src/Adapter/MSTest.TestAdapter/TestMethodFilter.cs @@ -10,7 +10,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; -internal class TestMethodFilter +internal sealed class TestMethodFilter { /// /// Supported properties for filtering. diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Constants.cs b/src/Adapter/MSTestAdapter.PlatformServices/Constants.cs index e9207ebaab..9651fb5b97 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Constants.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Constants.cs @@ -5,7 +5,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; -internal class Constants +internal static class Constants { #if NETFRAMEWORK /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnectionFactory.cs b/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnectionFactory.cs index aa332bbb2f..35929bf664 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnectionFactory.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnectionFactory.cs @@ -64,12 +64,12 @@ public virtual TestDataConnection Create(string invariantProviderName, string co #region TestDataConnectionFactories - private class XmlTestDataConnectionFactory : TestDataConnectionFactory + private sealed class XmlTestDataConnectionFactory : TestDataConnectionFactory { public override TestDataConnection Create(string invariantProviderName, string connectionString, List dataFolders) => new XmlDataConnection(connectionString, dataFolders); } - private class CsvTestDataConnectionFactory : TestDataConnectionFactory + private sealed class CsvTestDataConnectionFactory : TestDataConnectionFactory { public override TestDataConnection Create(string invariantProviderName, string connectionString, List dataFolders) => new CsvDataConnection(connectionString, dataFolders); } diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs index 8190c1fff2..7caef27a5a 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs @@ -21,7 +21,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Dep /// Utility function for Assembly related info /// The caller is supposed to create AppDomain and create instance of given class in there. /// -internal class AssemblyLoadWorker : MarshalByRefObject +internal sealed class AssemblyLoadWorker : MarshalByRefObject { private readonly IAssemblyUtility _assemblyUtility; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/DeploymentItem.cs b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/DeploymentItem.cs index 260c42fb78..f9a74383aa 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/DeploymentItem.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/DeploymentItem.cs @@ -39,7 +39,7 @@ internal enum DeploymentItemOriginType /// The deployment item for a test class or a test method. /// [Serializable] -internal class DeploymentItem +internal sealed class DeploymentItem { /// /// Initializes a new instance of the class. diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs index 8f74a3e352..9fd567d020 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs @@ -7,7 +7,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; -internal class ReflectionOperations2 : ReflectionOperations, IReflectionOperations2 +internal sealed class ReflectionOperations2 : ReflectionOperations, IReflectionOperations2 { public ReflectionOperations2() { diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs index 32d35b7e18..9d3efef984 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs @@ -177,7 +177,7 @@ private ThreadSafeStringBuilder GetOrAddStringBuilder() /// /// This StringBuilder puts locks around all the methods to avoid conflicts when writing or reading from multiple threads. /// - private class ThreadSafeStringBuilder + private sealed class ThreadSafeStringBuilder { private readonly StringBuilder _stringBuilder = new(); private readonly Lock _instanceLockObject = new(); diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs index 0d74da2d04..a465deaebc 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs @@ -257,7 +257,7 @@ internal static Version GetTargetFrameworkVersionFromVersionString(string versio appDomainCultureHelper?.SetUICulture(uiCulture); } - private class AppDomainCultureHelper : MarshalByRefObject + private sealed class AppDomainCultureHelper : MarshalByRefObject { #pragma warning disable CA1822 // Mark members as static - Should not be static for our need public void SetUICulture(CultureInfo uiCulture) => CultureInfo.DefaultThreadCurrentUICulture = uiCulture; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainWrapper.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainWrapper.cs index ce5057c5b6..1fd4e53f75 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainWrapper.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainWrapper.cs @@ -10,11 +10,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// Abstraction over the AppDomain APIs. /// -internal class AppDomainWrapper : IAppDomain +internal sealed class AppDomainWrapper : IAppDomain { - public AppDomain CreateDomain(string friendlyName, Evidence securityInfo, AppDomainSetup info) => AppDomain.CreateDomain(friendlyName, securityInfo, info); + public AppDomain CreateDomain(string friendlyName, Evidence securityInfo, AppDomainSetup info) + => AppDomain.CreateDomain(friendlyName, securityInfo, info); - public void Unload(AppDomain appDomain) => AppDomain.Unload(appDomain); + public void Unload(AppDomain appDomain) + => AppDomain.Unload(appDomain); } #endif diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AssemblyUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AssemblyUtility.cs index 8c6511384d..1c36284b18 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AssemblyUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AssemblyUtility.cs @@ -3,9 +3,9 @@ #if !WINDOWS_UWP +using System.Diagnostics.CodeAnalysis; #if NETFRAMEWORK using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection; @@ -19,6 +19,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Uti /// /// Utility for assembly specific functionality. /// +[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "Overrides required for testability")] internal class AssemblyUtility #if NETFRAMEWORK : IAssemblyUtility diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs index a787c71b3e..867f593dae 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs @@ -17,7 +17,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Uti /// /// The deployment utility. /// -internal class DeploymentItemUtility +internal sealed class DeploymentItemUtility { // REVIEW: it would be better if this was a ReflectionHelper, because helper is able to cache. But we don't have reflection helper here, because this is platform services dll. private readonly ReflectionUtility _reflectionUtility; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs index 73fdc4278e..51c73227b0 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs @@ -20,7 +20,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; -internal class DeploymentUtility : DeploymentUtilityBase +internal sealed class DeploymentUtility : DeploymentUtilityBase { public DeploymentUtility() : base() @@ -104,7 +104,7 @@ protected override void AddDependenciesOfDeploymentItem(string deploymentItemFil #if NETFRAMEWORK [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] - protected void ProcessNewStorage(string testSource, IList deploymentItems, IList warnings) + public void ProcessNewStorage(string testSource, IList deploymentItems, IList warnings) { // Add deployment items and process .config files only for storages we have not processed before. if (!DeploymentItemUtility.IsValidDeploymentItem(testSource, string.Empty, out string? errorMessage)) @@ -136,7 +136,7 @@ protected void ProcessNewStorage(string testSource, IList deploy } } - protected IEnumerable GetSatellites(IEnumerable deploymentItems, string testSource, IList warnings) + public IEnumerable GetSatellites(IEnumerable deploymentItems, string testSource, IList warnings) { List satellites = []; foreach (DeploymentItem item in deploymentItems) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs index 905e3e09ef..cc5b3efeb1 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs @@ -3,6 +3,7 @@ #if !WINDOWS_UWP +using System.Diagnostics.CodeAnalysis; using System.Globalization; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; @@ -11,6 +12,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; +[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "Overrides required for mocking")] internal class FileUtility { private readonly AssemblyUtility _assemblyUtility; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/RandomIntPermutation.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/RandomIntPermutation.cs index 668da63a8a..aaf3965dbf 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/RandomIntPermutation.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/RandomIntPermutation.cs @@ -11,7 +11,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// Permutation of integers from 0 to (numberOfObjects - 1), in random order and in the end all values are returned. /// Used to get random permutation for data row access in data driven test. /// -internal class RandomIntPermutation : IEnumerable +internal sealed class RandomIntPermutation : IEnumerable { private readonly int[] _objects; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ReflectionUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ReflectionUtility.cs index 5ebf1ee8d2..8ff05ead97 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ReflectionUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ReflectionUtility.cs @@ -6,6 +6,7 @@ #if NETFRAMEWORK using System.Collections; #endif +using System.Diagnostics.CodeAnalysis; using System.Reflection; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; @@ -13,6 +14,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Uti /// /// Utility for reflection API's. /// +[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "Overrides required for testability")] internal class ReflectionUtility { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/SequentialIntPermutation.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/SequentialIntPermutation.cs index c77c8fe83d..f4faf60807 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/SequentialIntPermutation.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/SequentialIntPermutation.cs @@ -11,7 +11,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// Permutation of integers from 0 to (numberOfObjects - 1) returned by increment of 1. /// Used to get sequential permutation for data row access in data driven test. /// -internal class SequentialIntPermutation : IEnumerable +internal sealed class SequentialIntPermutation : IEnumerable { private readonly int _numberOfObjects; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/XmlUtilities.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/XmlUtilities.cs index afbef47053..3518df09ed 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/XmlUtilities.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/XmlUtilities.cs @@ -3,6 +3,7 @@ #if NETFRAMEWORK +using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection; using System.Text; @@ -12,6 +13,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; +[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "Overrides required for mocking")] internal class XmlUtilities { private const string XmlNamespace = "urn:schemas-microsoft-com:asm.v1"; diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/BoundedCacheWithFactory.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/BoundedCacheWithFactory.cs index d3fbaf64d1..87250620aa 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/BoundedCacheWithFactory.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/BoundedCacheWithFactory.cs @@ -7,7 +7,7 @@ namespace Analyzer.Utilities; /// Acts as a good alternative to /// when the cached value has a cyclic reference to the key preventing early garbage collection of entries. /// -internal class BoundedCacheWithFactory +internal sealed class BoundedCacheWithFactory where TKey : class { // Bounded weak reference cache. diff --git a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/FailedTestInfoRequestSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/FailedTestInfoRequestSerializer.cs index 2a4e07195f..e3425beaaf 100644 --- a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/FailedTestInfoRequestSerializer.cs +++ b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/FailedTestInfoRequestSerializer.cs @@ -6,7 +6,7 @@ namespace Microsoft.Testing.Extensions.MSBuild.Serializers; -internal record FailedTestInfoRequest( +internal sealed record FailedTestInfoRequest( string DisplayName, bool IsCanceled, string? Duration, @@ -17,7 +17,7 @@ internal record FailedTestInfoRequest( string? CodeFilePath, int LineNumber) : IRequest; -internal class FailedTestInfoRequestSerializer : BaseSerializer, INamedPipeSerializer +internal sealed class FailedTestInfoRequestSerializer : BaseSerializer, INamedPipeSerializer { public int Id => 2; diff --git a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/ModuleInfoRequestSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/ModuleInfoRequestSerializer.cs index b5a9fe108d..062fd2d642 100644 --- a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/ModuleInfoRequestSerializer.cs +++ b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/ModuleInfoRequestSerializer.cs @@ -6,9 +6,9 @@ namespace Microsoft.Testing.Extensions.MSBuild.Serializers; -internal record ModuleInfoRequest(string FrameworkDescription, string ProcessArchitecture, string TestResultFolder) : IRequest; +internal sealed record ModuleInfoRequest(string FrameworkDescription, string ProcessArchitecture, string TestResultFolder) : IRequest; -internal class ModuleInfoRequestSerializer : BaseSerializer, INamedPipeSerializer +internal sealed class ModuleInfoRequestSerializer : BaseSerializer, INamedPipeSerializer { public int Id => 1; diff --git a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/RunSummaryRequestSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/RunSummaryRequestSerializer.cs index e28a1c33e7..4a612df01d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/RunSummaryRequestSerializer.cs +++ b/src/Platform/Microsoft.Testing.Extensions.MSBuild/Serializers/RunSummaryRequestSerializer.cs @@ -6,14 +6,14 @@ namespace Microsoft.Testing.Extensions.MSBuild.Serializers; -internal record RunSummaryInfoRequest( +internal sealed record RunSummaryInfoRequest( int Total, int TotalFailed, int TotalPassed, int TotalSkipped, string? Duration) : IRequest; -internal class RunSummaryInfoRequestSerializer : BaseSerializer, INamedPipeSerializer +internal sealed class RunSummaryInfoRequestSerializer : BaseSerializer, INamedPipeSerializer { public int Id => 3; diff --git a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightTelemetryClient.cs b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightTelemetryClient.cs index 9fa6fa9296..fe27fd2eb2 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightTelemetryClient.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightTelemetryClient.cs @@ -6,7 +6,7 @@ namespace Microsoft.Testing.Extensions.Telemetry; -internal class AppInsightTelemetryClient : ITelemetryClient +internal sealed class AppInsightTelemetryClient : ITelemetryClient { // Note: The InstrumentationKey should match the one of dotnet cli. private const string InstrumentationKey = "74cc1c9e-3e6e-4d05-b3fc-dde9101d0254"; diff --git a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightTelemetryClientFactory.cs b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightTelemetryClientFactory.cs index 8e3665349c..642da76ed9 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightTelemetryClientFactory.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightTelemetryClientFactory.cs @@ -3,7 +3,7 @@ namespace Microsoft.Testing.Extensions.Telemetry; -internal class AppInsightTelemetryClientFactory : ITelemetryClientFactory +internal sealed class AppInsightTelemetryClientFactory : ITelemetryClientFactory { public ITelemetryClient Create(string? currentSessionId, string osVersion) => new AppInsightTelemetryClient(currentSessionId, osVersion); diff --git a/src/Platform/Microsoft.Testing.Extensions.Telemetry/CIEnvironmentDetectorForTelemetry.cs b/src/Platform/Microsoft.Testing.Extensions.Telemetry/CIEnvironmentDetectorForTelemetry.cs index 09e5b7cc4d..b90059537b 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Telemetry/CIEnvironmentDetectorForTelemetry.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Telemetry/CIEnvironmentDetectorForTelemetry.cs @@ -7,7 +7,7 @@ namespace Microsoft.Testing.Extensions.Telemetry; // Detection of CI: https://learn.microsoft.com/dotnet/core/tools/telemetry#continuous-integration-detection // From: https://github.com/dotnet/sdk/blob/main/src/Cli/dotnet/Telemetry/CIEnvironmentDetectorForTelemetry.cs -internal class CIEnvironmentDetectorForTelemetry +internal sealed class CIEnvironmentDetectorForTelemetry { // Systems that provide boolean values only, so we can simply parse and check for true private static readonly string[] BooleanVariables = diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/ReportFileNameSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/ReportFileNameSerializer.cs index a2102ed28d..45832d23db 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/ReportFileNameSerializer.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/ReportFileNameSerializer.cs @@ -11,7 +11,7 @@ internal sealed class ReportFileNameRequest(string fileName) : IRequest public string FileName { get; } = fileName; } -internal class ReportFileNameRequestSerializer : BaseSerializer, INamedPipeSerializer +internal sealed class ReportFileNameRequestSerializer : BaseSerializer, INamedPipeSerializer { public int Id => 1; diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/TestAdapterInformationsSerializer.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/TestAdapterInformationsSerializer.cs index 7c3c41e2f0..b40b5f3ae8 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/TestAdapterInformationsSerializer.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Serializers/TestAdapterInformationsSerializer.cs @@ -6,7 +6,7 @@ namespace Microsoft.Testing.Extensions.TrxReport.Abstractions.Serializers; -internal class TestAdapterInformationRequest : IRequest +internal sealed class TestAdapterInformationRequest : IRequest { public TestAdapterInformationRequest(string testAdapterId, string testAdapterVersion) { @@ -19,7 +19,7 @@ public TestAdapterInformationRequest(string testAdapterId, string testAdapterVer public string TestAdapterVersion { get; } } -internal class TestAdapterInformationRequestSerializer : BaseSerializer, INamedPipeSerializer +internal sealed class TestAdapterInformationRequestSerializer : BaseSerializer, INamedPipeSerializer { public int Id => 2; diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.CommandLine.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.CommandLine.cs index 5738762730..71f2f4b9c5 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.CommandLine.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.CommandLine.cs @@ -12,7 +12,7 @@ namespace Microsoft.Testing.Extensions.TrxReport.Abstractions; -internal class TrxCompareToolCommandLine : IToolCommandLineOptionsProvider +internal sealed class TrxCompareToolCommandLine : IToolCommandLineOptionsProvider { public const string BaselineTrxOptionName = "baseline-trx"; public const string TrxToCompareOptionName = "trx-to-compare"; diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.cs index f270034078..3078a918f2 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.cs @@ -14,7 +14,7 @@ namespace Microsoft.Testing.Extensions.TrxReport.Abstractions; -internal class TrxCompareTool : ITool, IOutputDeviceDataProducer +internal sealed class TrxCompareTool : ITool, IOutputDeviceDataProducer { public const string ToolName = "ms-trxcompare"; private readonly ICommandLineOptions _commandLineOptions; diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxProcessLifetimeHandler.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxProcessLifetimeHandler.cs index 0a5e0991a8..3ecf341949 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxProcessLifetimeHandler.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxProcessLifetimeHandler.cs @@ -240,7 +240,7 @@ public void Dispose() } #endif - private class ExtensionInfo : IExtension + private sealed class ExtensionInfo : IExtension { public ExtensionInfo(string id, string semVer, string displayName, string description) { @@ -261,7 +261,7 @@ public ExtensionInfo(string id, string semVer, string displayName, string descri public Task IsEnabledAsync() => throw new NotImplementedException(); } - private class TestAdapterInfo : ITestFramework + private sealed class TestAdapterInfo : ITestFramework { public TestAdapterInfo(string id, string semVer) { diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxTestApplicationLifecycleCallbacks.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxTestApplicationLifecycleCallbacks.cs index 5ce9dc10be..9102eeaa8e 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxTestApplicationLifecycleCallbacks.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxTestApplicationLifecycleCallbacks.cs @@ -14,7 +14,7 @@ namespace Microsoft.Testing.Extensions.TrxReport.Abstractions; -internal class TrxTestApplicationLifecycleCallbacks : ITestApplicationLifecycleCallbacks, IDisposable +internal sealed class TrxTestApplicationLifecycleCallbacks : ITestApplicationLifecycleCallbacks, IDisposable { private readonly bool _isEnabled; private readonly IEnvironment _environment; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpressionWrapper.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpressionWrapper.cs index 8e2b757025..14cde5cba7 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpressionWrapper.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpressionWrapper.cs @@ -12,7 +12,7 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; [ExcludeFromCodeCoverage] // Helper copied from VSTest source code -internal class FilterExpressionWrapper +internal sealed class FilterExpressionWrapper { /// /// FilterExpression corresponding to filter criteria. diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs index c482f52b26..53ca25c7d6 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs @@ -10,7 +10,7 @@ namespace Microsoft.Testing.Platform.MSBuild.Tasks; -internal class DotnetMuxerLocator +internal sealed class DotnetMuxerLocator { private readonly string _muxerName; private readonly Process _currentProcess; diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs index e365c36b75..fbebc18061 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs @@ -420,7 +420,7 @@ private Task HandleRequestAsync(IRequest request) throw new NotImplementedException($"Request '{request.GetType()}' not supported."); } - private class MSBuildLogger : Logging.ILogger + private sealed class MSBuildLogger : Logging.ILogger { public bool IsEnabled(LogLevel logLevel) => false; diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/StackTraceHelper.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/StackTraceHelper.cs index 04f6ac93b2..e4f936f99a 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/StackTraceHelper.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/StackTraceHelper.cs @@ -8,7 +8,7 @@ namespace Microsoft.Testing.Platform.MSBuild; -internal class StackTraceHelper +internal static class StackTraceHelper { private static Regex? s_regex; diff --git a/src/Platform/Microsoft.Testing.Platform/Configurations/EnvironmentVariablesConfigurationSource.cs b/src/Platform/Microsoft.Testing.Platform/Configurations/EnvironmentVariablesConfigurationSource.cs index 2b064dd169..8279902eac 100644 --- a/src/Platform/Microsoft.Testing.Platform/Configurations/EnvironmentVariablesConfigurationSource.cs +++ b/src/Platform/Microsoft.Testing.Platform/Configurations/EnvironmentVariablesConfigurationSource.cs @@ -6,7 +6,7 @@ namespace Microsoft.Testing.Platform.Configurations; -internal class EnvironmentVariablesConfigurationSource(IEnvironment environmentVariables) : IConfigurationSource +internal sealed class EnvironmentVariablesConfigurationSource(IEnvironment environmentVariables) : IConfigurationSource { private readonly IEnvironment _environmentVariables = environmentVariables; diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/AsyncMonitorFactory.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/AsyncMonitorFactory.cs index c0e6470be8..cec9823762 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/AsyncMonitorFactory.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/AsyncMonitorFactory.cs @@ -3,7 +3,7 @@ namespace Microsoft.Testing.Platform.Helpers; -internal class SystemMonitorAsyncFactory : IAsyncMonitorFactory +internal sealed class SystemMonitorAsyncFactory : IAsyncMonitorFactory { public IAsyncMonitor Create() => new SystemAsyncMonitor(); } diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemClock.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemClock.cs index a985b5dcb2..b16ac89135 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemClock.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemClock.cs @@ -3,7 +3,7 @@ namespace Microsoft.Testing.Platform.Helpers; -internal class SystemClock : IClock +internal sealed class SystemClock : IClock { public DateTimeOffset UtcNow => DateTimeOffset.UtcNow; } diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemRuntimeFeature.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemRuntimeFeature.cs index 436c3580cc..2fcb57b2e8 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemRuntimeFeature.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemRuntimeFeature.cs @@ -7,7 +7,7 @@ namespace Microsoft.Testing.Platform.Helpers; -internal class SystemRuntimeFeature : IRuntimeFeature +internal sealed class SystemRuntimeFeature : IRuntimeFeature { #if NETCOREAPP public bool IsDynamicCodeSupported => RuntimeFeature.IsDynamicCodeSupported; diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestFrameworkBuilderData.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestFrameworkBuilderData.cs index 838dc78ef3..c948281d6d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestFrameworkBuilderData.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestFrameworkBuilderData.cs @@ -11,7 +11,7 @@ namespace Microsoft.Testing.Platform.Hosts; -internal class TestFrameworkBuilderData(ServiceProvider serviceProvider, ITestExecutionRequestFactory testExecutionRequestFactory, +internal sealed class TestFrameworkBuilderData(ServiceProvider serviceProvider, ITestExecutionRequestFactory testExecutionRequestFactory, ITestFrameworkInvoker testExecutionRequestInvoker, ITestExecutionFilterFactory testExecutionFilterFactory, IPlatformOutputDevice platformOutputDisplayService, IEnumerable serverPerCallConsumers, TestFrameworkManager testFrameworkManager, TestHostManager testSessionManager, MessageBusProxy messageBusProxy, diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs index bc0a2184df..2bee5296da 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs @@ -33,7 +33,7 @@ namespace Microsoft.Testing.Platform.Hosts; -internal class TestHostBuilder(IFileSystem fileSystem, IRuntimeFeature runtimeFeature, IEnvironment environment, IProcessHandler processHandler, ITestApplicationModuleInfo testApplicationModuleInfo) : ITestHostBuilder +internal sealed class TestHostBuilder(IFileSystem fileSystem, IRuntimeFeature runtimeFeature, IEnvironment environment, IProcessHandler processHandler, ITestApplicationModuleInfo testApplicationModuleInfo) : ITestHostBuilder { private readonly IFileSystem _fileSystem = fileSystem; private readonly ITestApplicationModuleInfo _testApplicationModuleInfo = testApplicationModuleInfo; @@ -498,12 +498,11 @@ await LogTestHostCreatedAsync( } // Build the test host - ConsoleTestHost consoleHost = CreateConsoleTestHost( + ConsoleTestHost consoleHost = TestHostBuilder.CreateConsoleTestHost( serviceProvider, BuildTestFrameworkAsync, (TestFrameworkManager)TestFramework, - (TestHostManager)TestHost, - _testApplicationModuleInfo); + (TestHostManager)TestHost); // If needed we wrap the host inside the TestHostControlledHost to automatically handle the shutdown of the connected pipe. ITestHost actualTestHost = testControllerConnection is not null @@ -567,7 +566,7 @@ await client.RequestReplyAsync( return client; } - protected virtual void AddApplicationMetadata(IServiceProvider serviceProvider, Dictionary builderMetadata) + private void AddApplicationMetadata(IServiceProvider serviceProvider, Dictionary builderMetadata) { ITelemetryInformation telemetryInformation = serviceProvider.GetTelemetryInformation(); if (!telemetryInformation.IsEnabled) @@ -644,10 +643,10 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD // creations and we could lose interesting diagnostic information. List dataConsumersBuilder = []; - await RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.PlatformOutputDisplayService, serviceProvider, dataConsumersBuilder); - await RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionRequestFactory, serviceProvider, dataConsumersBuilder); - await RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionRequestInvoker, serviceProvider, dataConsumersBuilder); - await RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionFilterFactory, serviceProvider, dataConsumersBuilder); + await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.PlatformOutputDisplayService, serviceProvider, dataConsumersBuilder); + await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionRequestFactory, serviceProvider, dataConsumersBuilder); + await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionRequestInvoker, serviceProvider, dataConsumersBuilder); + await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionFilterFactory, serviceProvider, dataConsumersBuilder); // Create the test framework adapter ITestFrameworkCapabilities testFrameworkCapabilities = serviceProvider.GetTestFrameworkCapabilities(); @@ -657,16 +656,13 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD serviceProvider.AllowTestAdapterFrameworkRegistration = true; try { - await RegisterAsServiceOrConsumerOrBothAsync(new TestFrameworkProxy(testFramework), serviceProvider, dataConsumersBuilder); + await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(new TestFrameworkProxy(testFramework), serviceProvider, dataConsumersBuilder); } finally { serviceProvider.AllowTestAdapterFrameworkRegistration = false; } - // Virtual callback that allows to the VSTest mode to register custom services needed by the bridge. - AfterTestAdapterCreation(serviceProvider); - // Prepare the session lifetime handlers for the notifications List testSessionLifetimeHandlers = []; @@ -686,11 +682,11 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD { if (testhostExtension.Extension is IDataConsumer) { - await RegisterAsServiceOrConsumerOrBothAsync(testhostExtension.Extension, serviceProvider, dataConsumersBuilder); + await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testhostExtension.Extension, serviceProvider, dataConsumersBuilder); } else { - await AddServiceIfNotSkippedAsync(testhostExtension.Extension, serviceProvider); + await TestHostBuilder.AddServiceIfNotSkippedAsync(testhostExtension.Extension, serviceProvider); } } } @@ -704,7 +700,7 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD testSessionLifetimeHandlers.Add(handler); } - await RegisterAsServiceOrConsumerOrBothAsync(consumerService, serviceProvider, dataConsumersBuilder); + await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(consumerService, serviceProvider, dataConsumersBuilder); } // Register the test session lifetime handlers container @@ -720,7 +716,7 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD // Allow the ITestApplicationProcessExitCode to subscribe as IDataConsumer ITestApplicationProcessExitCode testApplicationResult = serviceProvider.GetRequiredService(); - await RegisterAsServiceOrConsumerOrBothAsync(testApplicationResult, serviceProvider, dataConsumersBuilder); + await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testApplicationResult, serviceProvider, dataConsumersBuilder); // We register the data consumer handler if we're connected to the dotnet test pipe if (pushOnlyProtocolDataConsumer is not null) @@ -765,39 +761,29 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD return testFramework; } - protected virtual ConsoleTestHost CreateConsoleTestHost( + private static ConsoleTestHost CreateConsoleTestHost( ServiceProvider serviceProvider, Func> buildTestFrameworkAsync, TestFrameworkManager testFrameworkManager, - TestHostManager testHostManager, - ITestApplicationModuleInfo testApplicationModuleInfo) + TestHostManager testHostManager) => new(serviceProvider, buildTestFrameworkAsync, testFrameworkManager, testHostManager); - protected virtual bool SkipAddingService(object service) => false; - - protected virtual void AfterTestAdapterCreation(ServiceProvider serviceProvider) + private static async Task AddServiceIfNotSkippedAsync(object service, ServiceProvider serviceProvider) { - } - - private async Task AddServiceIfNotSkippedAsync(object service, ServiceProvider serviceProvider) - { - if (!SkipAddingService(service)) + if (service is IExtension extension) { - if (service is IExtension extension) - { - if (await extension.IsEnabledAsync()) - { - serviceProvider.TryAddService(service); - } - } - else + if (await extension.IsEnabledAsync()) { serviceProvider.TryAddService(service); } } + else + { + serviceProvider.TryAddService(service); + } } - private async Task RegisterAsServiceOrConsumerOrBothAsync(object service, ServiceProvider serviceProvider, + private static async Task RegisterAsServiceOrConsumerOrBothAsync(object service, ServiceProvider serviceProvider, List dataConsumersBuilder) { if (service is IDataConsumer dataConsumer) @@ -815,7 +801,7 @@ private async Task RegisterAsServiceOrConsumerOrBothAsync(object service, Servic return; } - await AddServiceIfNotSkippedAsync(service, serviceProvider); + await TestHostBuilder.AddServiceIfNotSkippedAsync(service, serviceProvider); } private async Task DisplayBannerIfEnabledAsync(ApplicationLoggingState loggingState, ProxyOutputDevice outputDevice, diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControlledHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControlledHost.cs index 79ee5575c2..47aa9ec5ce 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControlledHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControlledHost.cs @@ -7,7 +7,7 @@ namespace Microsoft.Testing.Platform.Hosts; -internal class TestHostControlledHost(NamedPipeClient testHostControllerPipeClient, ITestHost innerTestHost, CancellationToken cancellationToken) : ITestHost, IDisposable +internal sealed class TestHostControlledHost(NamedPipeClient testHostControllerPipeClient, ITestHost innerTestHost, CancellationToken cancellationToken) : ITestHost, IDisposable #if NETCOREAPP #pragma warning disable SA1001 // Commas should be spaced correctly , IAsyncDisposable diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostOchestratorHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostOchestratorHost.cs index 3f51ed08cc..6eca7b889f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostOchestratorHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostOchestratorHost.cs @@ -8,7 +8,7 @@ namespace Microsoft.Testing.Platform.Hosts; -internal class TestHostOrchestratorHost(TestHostOrchestratorConfiguration testHostOrchestratorConfiguration, ServiceProvider serviceProvider) : ITestHost +internal sealed class TestHostOrchestratorHost(TestHostOrchestratorConfiguration testHostOrchestratorConfiguration, ServiceProvider serviceProvider) : ITestHost { private readonly TestHostOrchestratorConfiguration _testHostOrchestratorConfiguration = testHostOrchestratorConfiguration; private readonly ServiceProvider _serviceProvider = serviceProvider; diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/Models/TestHostProcessExitRequest.cs b/src/Platform/Microsoft.Testing.Platform/IPC/Models/TestHostProcessExitRequest.cs index c3b34f5444..8e6d85f2a2 100644 --- a/src/Platform/Microsoft.Testing.Platform/IPC/Models/TestHostProcessExitRequest.cs +++ b/src/Platform/Microsoft.Testing.Platform/IPC/Models/TestHostProcessExitRequest.cs @@ -3,7 +3,7 @@ namespace Microsoft.Testing.Platform.IPC.Models; -internal class TestHostProcessExitRequest(int returnCode) : IRequest +internal sealed class TestHostProcessExitRequest(int returnCode) : IRequest { public int ExitCode { get; } = returnCode; } diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/Models/TestHostProcessPIDRequest.cs b/src/Platform/Microsoft.Testing.Platform/IPC/Models/TestHostProcessPIDRequest.cs index de12594ebb..f0b2f9220a 100644 --- a/src/Platform/Microsoft.Testing.Platform/IPC/Models/TestHostProcessPIDRequest.cs +++ b/src/Platform/Microsoft.Testing.Platform/IPC/Models/TestHostProcessPIDRequest.cs @@ -3,7 +3,7 @@ namespace Microsoft.Testing.Platform.IPC.Models; -internal class TestHostProcessPIDRequest(int pid) : IRequest +internal sealed class TestHostProcessPIDRequest(int pid) : IRequest { public int PID { get; } = pid; } diff --git a/src/Platform/Microsoft.Testing.Platform/Logging/FileLoggerInformation.cs b/src/Platform/Microsoft.Testing.Platform/Logging/FileLoggerInformation.cs index 573172ca4b..2237492e9b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Logging/FileLoggerInformation.cs +++ b/src/Platform/Microsoft.Testing.Platform/Logging/FileLoggerInformation.cs @@ -3,7 +3,7 @@ namespace Microsoft.Testing.Platform.Logging; -internal record FileLoggerInformation(bool SyncronousWrite, FileInfo LogFile, LogLevel LogLevel) : IFileLoggerInformation +internal sealed record FileLoggerInformation(bool SyncronousWrite, FileInfo LogFile, LogLevel LogLevel) : IFileLoggerInformation { public bool SyncronousWrite { get; init; } = SyncronousWrite; diff --git a/src/Platform/Microsoft.Testing.Platform/Logging/LoggerFactoryProxy.cs b/src/Platform/Microsoft.Testing.Platform/Logging/LoggerFactoryProxy.cs index be1c9ac261..a8ac01eee4 100644 --- a/src/Platform/Microsoft.Testing.Platform/Logging/LoggerFactoryProxy.cs +++ b/src/Platform/Microsoft.Testing.Platform/Logging/LoggerFactoryProxy.cs @@ -3,7 +3,7 @@ namespace Microsoft.Testing.Platform.Logging; -internal class LoggerFactoryProxy : ILoggerFactory +internal sealed class LoggerFactoryProxy : ILoggerFactory { private ILoggerFactory? _loggerFactory; diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs b/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs index baede6aec5..f9e4b0cdf6 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs @@ -13,7 +13,7 @@ namespace Microsoft.Testing.Platform.Messages; -internal class AsynchronousMessageBus : BaseMessageBus, IMessageBus, IDisposable +internal sealed class AsynchronousMessageBus : BaseMessageBus, IMessageBus, IDisposable { // This is an arbitrary number of attempts to drain the message bus. // The number of attempts is configurable via the environment variable TESTINGPLATFORM_MESSAGEBUS_DRAINDATA_ATTEMPTS. diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs b/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs index 6ef8484b97..4948060748 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs @@ -12,7 +12,7 @@ namespace Microsoft.Testing.Platform.Messages; [DebuggerDisplay("DataConsumer = {DataConsumer.Uid}")] -internal class AsyncConsumerDataProcessor : IDisposable +internal sealed class AsyncConsumerDataProcessor : IDisposable { private readonly ITask _task; private readonly CancellationToken _cancellationToken; diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/ConsumingEnumerableConsumerDataProcessor.cs b/src/Platform/Microsoft.Testing.Platform/Messages/ConsumingEnumerableConsumerDataProcessor.cs index 4779fa1ee1..7b13cf0970 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/ConsumingEnumerableConsumerDataProcessor.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/ConsumingEnumerableConsumerDataProcessor.cs @@ -10,7 +10,7 @@ namespace Microsoft.Testing.Platform.Messages; -internal class AsyncConsumerDataProcessor : IDisposable +internal sealed class AsyncConsumerDataProcessor : IDisposable { // The default underlying collection is a ConcurrentQueue object, which provides first in, first out (FIFO) behavior. private readonly BlockingCollection<(IDataProducer DataProducer, IData Data)> _payloads = []; diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.Property.cs b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.Property.cs index a72c9adb96..7904841d55 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.Property.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.Property.cs @@ -9,7 +9,7 @@ namespace Microsoft.Testing.Platform.Extensions.Messages; public sealed partial class PropertyBag { [DebuggerTypeProxy(typeof(PropertyDebugView))] - internal /* for testing */ class Property(IProperty current, Property? next = null) : IEnumerable + internal /* for testing */ sealed class Property(IProperty current, Property? next = null) : IEnumerable { public int Count { diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs index d3e09c4e8b..e8e7ac88b0 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs @@ -30,7 +30,11 @@ internal async Task BuildAsync(ServiceProvider serviceProvide nonServerOutputDevice = GetDefaultTerminalOutputDevice(serviceProvider); } - return new ProxyOutputDevice(nonServerOutputDevice, useServerModeOutputDevice ? new ServerModePerCallOutputDevice(serviceProvider) : null); + return new ProxyOutputDevice( + nonServerOutputDevice, + useServerModeOutputDevice + ? new ServerModePerCallOutputDevice(serviceProvider) + : null); } public static TerminalOutputDevice GetDefaultTerminalOutputDevice(ServiceProvider serviceProvider) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ErrorMessage.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ErrorMessage.cs index 541ca6ecdd..f4e41aa43e 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ErrorMessage.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ErrorMessage.cs @@ -6,4 +6,4 @@ namespace Microsoft.Testing.Platform.OutputDevice.Terminal; /// /// An error message that was sent to output during the build. /// -internal record ErrorMessage(string Text) : IProgressMessage; +internal sealed record ErrorMessage(string Text) : IProgressMessage; diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs index cd057bc2e9..e0a57cbe9d 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs @@ -3,7 +3,7 @@ namespace Microsoft.Testing.Platform.OutputDevice.Terminal; -internal class ExceptionFlattener +internal sealed class ExceptionFlattener { internal static FlatException[] Flatten(string? errorMessage, Exception? exception) { @@ -51,4 +51,4 @@ internal static FlatException[] Flatten(string? errorMessage, Exception? excepti } } -internal record FlatException(string? ErrorMessage, string? ErrorType, string? StackTrace); +internal sealed record FlatException(string? ErrorMessage, string? ErrorType, string? StackTrace); diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestRunArtifact.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestRunArtifact.cs index 64c01d44af..e8eba56edc 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestRunArtifact.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestRunArtifact.cs @@ -6,4 +6,4 @@ namespace Microsoft.Testing.Platform.OutputDevice.Terminal; /// /// An artifact / attachment that was reported during run. /// -internal record TestRunArtifact(bool OutOfProcess, string? Assembly, string? TargetFramework, string? Architecture, string? ExecutionId, string? TestName, string Path); +internal sealed record TestRunArtifact(bool OutOfProcess, string? Assembly, string? TargetFramework, string? Architecture, string? ExecutionId, string? TestName, string Path); diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/WarningMessage.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/WarningMessage.cs index 2cd967504a..c938898aa7 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/WarningMessage.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/WarningMessage.cs @@ -6,4 +6,4 @@ namespace Microsoft.Testing.Platform.OutputDevice.Terminal; /// /// A warning message that was sent during run. /// -internal record WarningMessage(string Text) : IProgressMessage; +internal sealed record WarningMessage(string Text) : IProgressMessage; diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs index 05b5a39fc3..b5eaff5ff8 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs @@ -25,7 +25,7 @@ namespace Microsoft.Testing.Platform.OutputDevice; /// /// Implementation of output device that writes to terminal with progress and optionally with ANSI. /// -internal partial class TerminalOutputDevice : IHotReloadPlatformOutputDevice, +internal sealed partial class TerminalOutputDevice : IHotReloadPlatformOutputDevice, IDataConsumer, IOutputDeviceDataProducer, ITestSessionLifetimeHandler, @@ -183,7 +183,7 @@ private string GetShortArchitecture(string runtimeIdentifier) ]; /// - public virtual string Uid { get; } = nameof(TerminalOutputDevice); + public string Uid { get; } = nameof(TerminalOutputDevice); /// public string Version { get; } = AppVersion.DefaultSemVer; @@ -195,7 +195,7 @@ private string GetShortArchitecture(string runtimeIdentifier) public string Description { get; } = "Test Platform default console service"; /// - public virtual Task IsEnabledAsync() => Task.FromResult(true); + public Task IsEnabledAsync() => Task.FromResult(true); private async Task LogDebugAsync(string message) { @@ -205,7 +205,7 @@ private async Task LogDebugAsync(string message) } } - public virtual async Task DisplayBannerAsync(string? bannerMessage) + public async Task DisplayBannerAsync(string? bannerMessage) { RoslynDebug.Assert(_terminalTestReporter is not null); diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs b/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs index b52d8e99e5..edade0379b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs @@ -2,6 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using Microsoft.Testing.Platform.Capabilities; using Microsoft.Testing.Platform.Capabilities.TestFramework; @@ -18,6 +19,7 @@ namespace Microsoft.Testing.Platform.Requests; +[SuppressMessage("Performance", "CA1852: Seal internal types", Justification = "HotReload needs to inherit and override ExecuteRequestAsync")] internal class TestHostTestFrameworkInvoker(IServiceProvider serviceProvider) : ITestFrameworkInvoker, IOutputDeviceDataProducer, IDataProducer { protected IServiceProvider ServiceProvider { get; } = serviceProvider; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/DotnetTestDataConsumer.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/DotnetTestDataConsumer.cs index 63af8f949c..ab8b8865ba 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/DotnetTestDataConsumer.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/DotnetTestDataConsumer.cs @@ -10,7 +10,7 @@ namespace Microsoft.Testing.Platform.IPC; -internal class DotnetTestDataConsumer : IPushOnlyProtocolConsumer +internal sealed class DotnetTestDataConsumer : IPushOnlyProtocolConsumer { private readonly DotnetTestConnection? _dotnetTestConnection; private readonly IEnvironment _environment; @@ -172,8 +172,6 @@ private static TestNodeDetails GetTestNodeDetails(TestNodeUpdateMessage testNode long? duration = null; string? reason = string.Empty; ExceptionMessage[]? exceptions = null; - string? errorStackTrace = string.Empty; - TestNodeStateProperty nodeState = testNodeUpdateMessage.TestNode.Properties.Single(); string? standardOutput = testNodeUpdateMessage.TestNode.Properties.SingleOrDefault()?.StandardOutput; string? standardError = testNodeUpdateMessage.TestNode.Properties.SingleOrDefault()?.StandardError; @@ -245,7 +243,7 @@ private static TestNodeDetails GetTestNodeDetails(TestNodeUpdateMessage testNode } } - public record TestNodeDetails(byte? State, long? Duration, string? Reason, ExceptionMessage[]? Exceptions, string? StandardOutput, string? StandardError); + public sealed record TestNodeDetails(byte? State, long? Duration, string? Reason, ExceptionMessage[]? Exceptions, string? StandardOutput, string? StandardError); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ErrorCodes.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ErrorCodes.cs index ec80398a22..fba10b37fe 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ErrorCodes.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ErrorCodes.cs @@ -6,7 +6,7 @@ namespace Microsoft.Testing.Platform.ServerMode; [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Common pattern to use public static readonly fields")] -internal class ErrorCodes +internal sealed class ErrorCodes { #region JSON-RPC error codes // JSON-RPC specific error codes. diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/JsonCollectionDeserializer.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/JsonCollectionDeserializer.cs index f559ce340c..b22ae843f5 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/JsonCollectionDeserializer.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/JsonCollectionDeserializer.cs @@ -10,7 +10,7 @@ internal abstract class JsonCollectionDeserializer : JsonDeserializ internal abstract TCollection CreateObject(Json json, JsonElement element); } -internal class JsonCollectionDeserializer(Func createCollection, Action addItem) : JsonCollectionDeserializer +internal sealed class JsonCollectionDeserializer(Func createCollection, Action addItem) : JsonCollectionDeserializer where TCollection : ICollection { private readonly Func _createCollection = createCollection; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/JsoniteProperties.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/JsoniteProperties.cs index adf00d8a21..ec292d8a38 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/JsoniteProperties.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/JsoniteProperties.cs @@ -4,4 +4,4 @@ namespace Microsoft.Testing.Platform.ServerMode.Json; // This object is needed to reuse jsonite's serialization shared code. -internal class JsoniteProperties : Dictionary; +internal sealed class JsoniteProperties : Dictionary; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs index 7bd1ec32d5..e5d33e11d0 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs @@ -14,7 +14,7 @@ namespace Microsoft.Testing.Platform.ServerMode; internal sealed partial class ServerModeManager { - internal class MessageHandlerFactory : IMessageHandlerFactory, IOutputDeviceDataProducer + internal sealed class MessageHandlerFactory : IMessageHandlerFactory, IOutputDeviceDataProducer { private readonly string? _host; private readonly int _port; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PassiveNode.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PassiveNode.cs index 52c8b93d64..5cffc0761a 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PassiveNode.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PassiveNode.cs @@ -10,7 +10,7 @@ namespace Microsoft.Testing.Platform.ServerMode; -internal class PassiveNode : IDisposable +internal sealed class PassiveNode : IDisposable { private readonly IMessageHandlerFactory _messageHandlerFactory; private readonly ITestApplicationCancellationTokenSource _testApplicationCancellationTokenSource; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PerRequestTestSessionContext.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PerRequestTestSessionContext.cs index 729fa3bd84..374411b7ec 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PerRequestTestSessionContext.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PerRequestTestSessionContext.cs @@ -6,7 +6,7 @@ namespace Microsoft.Testing.Platform.ServerMode; -internal class PerRequestTestSessionContext(CancellationToken rpcCancellationToken, CancellationToken testApplicationcancellationToken) : ITestSessionContext, IDisposable +internal sealed class PerRequestTestSessionContext(CancellationToken rpcCancellationToken, CancellationToken testApplicationcancellationToken) : ITestSessionContext, IDisposable { private readonly CancellationTokenSource _cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(rpcCancellationToken, testApplicationcancellationToken); diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/RpcMessages.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/RpcMessages.cs index be95ad9a19..941f900ed7 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/RpcMessages.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/RpcMessages.cs @@ -12,19 +12,19 @@ internal abstract record RpcMessage(); /// A request is a message for which the server should return a corresponding /// or . /// -internal record RequestMessage(int Id, string Method, object? Params) : RpcMessage; +internal sealed record RequestMessage(int Id, string Method, object? Params) : RpcMessage; /// /// A notification message is a message that notifies the server of an event. /// There's no corresponding response that the server should send back and as such /// no Id is specified when sending a notification. /// -internal record NotificationMessage(string Method, object? Params) : RpcMessage; +internal sealed record NotificationMessage(string Method, object? Params) : RpcMessage; /// /// An error message is sent if some exception was thrown when processing the request. /// -internal record ErrorMessage(int Id, int ErrorCode, string Message, object? Data) : RpcMessage; +internal sealed record ErrorMessage(int Id, int ErrorCode, string Message, object? Data) : RpcMessage; /// /// An response message is sent if a request is handled successfully. @@ -33,59 +33,59 @@ internal record ErrorMessage(int Id, int ErrorCode, string Message, object? Data /// If the RPC handler returns a the /// will be returned as null. /// -internal record ResponseMessage(int Id, object? Result) : RpcMessage; +internal sealed record ResponseMessage(int Id, object? Result) : RpcMessage; -internal record InitializeRequestArgs(int ProcessId, ClientInfo ClientInfo, ClientCapabilities Capabilities); +internal sealed record InitializeRequestArgs(int ProcessId, ClientInfo ClientInfo, ClientCapabilities Capabilities); -internal record InitializeResponseArgs(int? ProcessId, ServerInfo ServerInfo, ServerCapabilities Capabilities); +internal sealed record InitializeResponseArgs(int? ProcessId, ServerInfo ServerInfo, ServerCapabilities Capabilities); internal record RequestArgsBase(Guid RunId, ICollection? TestNodes, string? GraphFilter); -internal record DiscoverRequestArgs(Guid RunId, ICollection? TestNodes, string? GraphFilter) : +internal sealed record DiscoverRequestArgs(Guid RunId, ICollection? TestNodes, string? GraphFilter) : RequestArgsBase(RunId, TestNodes, GraphFilter); internal record ResponseArgsBase; -internal record DiscoverResponseArgs : ResponseArgsBase; +internal sealed record DiscoverResponseArgs : ResponseArgsBase; -internal record RunRequestArgs(Guid RunId, ICollection? TestNodes, string? GraphFilter) : +internal sealed record RunRequestArgs(Guid RunId, ICollection? TestNodes, string? GraphFilter) : RequestArgsBase(RunId, TestNodes, GraphFilter); -internal record RunResponseArgs(Artifact[] Artifacts) : ResponseArgsBase; +internal sealed record RunResponseArgs(Artifact[] Artifacts) : ResponseArgsBase; -internal record Artifact(string Uri, string Producer, string Type, string DisplayName, string? Description = null); +internal sealed record Artifact(string Uri, string Producer, string Type, string DisplayName, string? Description = null); -internal record CancelRequestArgs(int CancelRequestId); +internal sealed record CancelRequestArgs(int CancelRequestId); -internal record ExitRequestArgs; +internal sealed record ExitRequestArgs; -internal record ClientInfo(string Name, string Version); +internal sealed record ClientInfo(string Name, string Version); -internal record ClientCapabilities(bool DebuggerProvider); +internal sealed record ClientCapabilities(bool DebuggerProvider); -internal record ClientTestingCapabilities(bool DebuggerProvider); +internal sealed record ClientTestingCapabilities(bool DebuggerProvider); -internal record ServerInfo(string Name, string Version); +internal sealed record ServerInfo(string Name, string Version); -internal record ServerCapabilities(ServerTestingCapabilities TestingCapabilities); +internal sealed record ServerCapabilities(ServerTestingCapabilities TestingCapabilities); -internal record ServerTestingCapabilities( +internal sealed record ServerTestingCapabilities( bool SupportsDiscovery, bool MultiRequestSupport, bool VSTestProviderSupport, bool SupportsAttachments, bool MultiConnectionProvider); -internal record TestNodeStateChangedEventArgs(Guid RunId, TestNodeUpdateMessage[]? Changes); +internal sealed record TestNodeStateChangedEventArgs(Guid RunId, TestNodeUpdateMessage[]? Changes); -internal record LogEventArgs(ServerLogMessage LogMessage); +internal sealed record LogEventArgs(ServerLogMessage LogMessage); -internal record TelemetryEventArgs(string EventName, IDictionary Metrics); +internal sealed record TelemetryEventArgs(string EventName, IDictionary Metrics); -internal record ProcessInfoArgs(string Program, string? Args, string? WorkingDirectory, IDictionary? EnvironmentVariables); +internal sealed record ProcessInfoArgs(string Program, string? Args, string? WorkingDirectory, IDictionary? EnvironmentVariables); -internal record AttachDebuggerInfoArgs(int ProcessId); +internal sealed record AttachDebuggerInfoArgs(int ProcessId); -internal record class TestsAttachments(RunTestAttachment[] Attachments); +internal sealed record class TestsAttachments(RunTestAttachment[] Attachments); -internal record class RunTestAttachment(string? Uri, string? Producer, string? Type, string? DisplayName, string? Description); +internal sealed record class RunTestAttachment(string? Uri, string? Producer, string? Type, string? DisplayName, string? Description); diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/TestNodeStateChangeAggregator.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/TestNodeStateChangeAggregator.cs index 91278adca4..0c26a1c096 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/TestNodeStateChangeAggregator.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/TestNodeStateChangeAggregator.cs @@ -15,7 +15,7 @@ internal sealed partial class ServerTestHost /// This is done to minimize the number of RPC messages sent. /// /// The caller needs to ensure thread-safety. - internal class TestNodeStateChangeAggregator(Guid runId) + internal sealed class TestNodeStateChangeAggregator(Guid runId) { // Note: Currently there's no cascading node changes we need to deal with. private readonly List _stateChanges = []; diff --git a/src/Platform/Microsoft.Testing.Platform/Services/CTRLPlusCCancellationTokenSource.cs b/src/Platform/Microsoft.Testing.Platform/Services/CTRLPlusCCancellationTokenSource.cs index 62ce3e3186..9028714672 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/CTRLPlusCCancellationTokenSource.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/CTRLPlusCCancellationTokenSource.cs @@ -6,7 +6,7 @@ namespace Microsoft.Testing.Platform.Services; -internal class CTRLPlusCCancellationTokenSource : ITestApplicationCancellationTokenSource, IDisposable +internal sealed class CTRLPlusCCancellationTokenSource : ITestApplicationCancellationTokenSource, IDisposable { private readonly CancellationTokenSource _cancellationTokenSource = new(); private readonly ILogger? _logger; diff --git a/src/Platform/Microsoft.Testing.Platform/Services/ITestApplicationProcessExitCode.cs b/src/Platform/Microsoft.Testing.Platform/Services/ITestApplicationProcessExitCode.cs index 1f8a11274b..880295b739 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/ITestApplicationProcessExitCode.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/ITestApplicationProcessExitCode.cs @@ -19,7 +19,7 @@ internal interface ITestApplicationProcessExitCode : IDataConsumer Statistics GetStatistics(); } -internal class Statistics +internal sealed class Statistics { public int TotalRanTests { get; set; } diff --git a/src/Platform/Microsoft.Testing.Platform/TestFramework/TestFrameworkManager.cs b/src/Platform/Microsoft.Testing.Platform/TestFramework/TestFrameworkManager.cs index 6027b14792..d122e4737e 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestFramework/TestFrameworkManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestFramework/TestFrameworkManager.cs @@ -6,7 +6,7 @@ namespace Microsoft.Testing.Internal.Framework; -internal class TestFrameworkManager( +internal sealed class TestFrameworkManager( Func testFrameworkFactory, Func testFrameworkCapabilitiesFactory) : ITestFrameworkManager diff --git a/src/Platform/Microsoft.Testing.Platform/TestHost/TestSessionLifetimeHandlersContainer.cs b/src/Platform/Microsoft.Testing.Platform/TestHost/TestSessionLifetimeHandlersContainer.cs index 667bc8d76d..1526535287 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestHost/TestSessionLifetimeHandlersContainer.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestHost/TestSessionLifetimeHandlersContainer.cs @@ -3,7 +3,7 @@ namespace Microsoft.Testing.Platform.Extensions.TestHost; -internal class TestSessionLifetimeHandlersContainer +internal sealed class TestSessionLifetimeHandlersContainer { public TestSessionLifetimeHandlersContainer(IEnumerable testSessionLifetimeHandlers) => TestSessionLifetimeHandlers = testSessionLifetimeHandlers; diff --git a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/PassiveNodeDataConsumer.cs b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/PassiveNodeDataConsumer.cs index 5f95d7325b..6bad942616 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/PassiveNodeDataConsumer.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/PassiveNodeDataConsumer.cs @@ -8,7 +8,7 @@ namespace Microsoft.Testing.Platform.TestHostControllers; -internal class PassiveNodeDataConsumer : IDataConsumer, IDisposable +internal sealed class PassiveNodeDataConsumer : IDataConsumer, IDisposable { private const string FileType = "file"; private readonly PassiveNode? _passiveNode; diff --git a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostProcessInformation.cs b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostProcessInformation.cs index 7006bd8c44..c67c3cfa0b 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostProcessInformation.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostProcessInformation.cs @@ -6,7 +6,7 @@ namespace Microsoft.Testing.Platform.TestHostControllers; -internal class TestHostProcessInformation : ITestHostProcessInformation +internal sealed class TestHostProcessInformation : ITestHostProcessInformation { private readonly int? _exitCode; private readonly bool? _hasExitedGracefully; diff --git a/src/Platform/Microsoft.Testing.Platform/TestHostOrcherstrator/TestHostOrchestratorManager.cs b/src/Platform/Microsoft.Testing.Platform/TestHostOrcherstrator/TestHostOrchestratorManager.cs index 72d36b4723..675e94dc09 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestHostOrcherstrator/TestHostOrchestratorManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestHostOrcherstrator/TestHostOrchestratorManager.cs @@ -8,7 +8,7 @@ namespace Microsoft.Testing.Platform.Extensions.TestHostOrchestrator; -internal class TestHostOrchestratorManager : ITestHostOrchestratorManager +internal sealed class TestHostOrchestratorManager : ITestHostOrchestratorManager { private List>? _factories; diff --git a/src/TestFramework/TestFramework.Extensions/RuntimeTypeHelper.cs b/src/TestFramework/TestFramework.Extensions/RuntimeTypeHelper.cs index 89a1ed7c31..984319f536 100644 --- a/src/TestFramework/TestFramework.Extensions/RuntimeTypeHelper.cs +++ b/src/TestFramework/TestFramework.Extensions/RuntimeTypeHelper.cs @@ -10,7 +10,7 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// /// Provides method signature discovery for generic methods. /// -internal class RuntimeTypeHelper +internal sealed class RuntimeTypeHelper { /// /// Compares the method signatures of these two methods. diff --git a/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs b/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs index b43825c247..98d779210f 100644 --- a/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs +++ b/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs @@ -1684,7 +1684,7 @@ private static string ConstructFinalMessage( /// /// compares the objects using object.Equals. /// - private class ObjectComparer : IComparer + private sealed class ObjectComparer : IComparer { int IComparer.Compare(object? x, object? y) => Equals(x, y) ? 0 : -1; } diff --git a/test/Performance/MSTest.Performance.Runner/Steps/Files.cs b/test/Performance/MSTest.Performance.Runner/Steps/Files.cs index ef9db35e37..f8e722e908 100644 --- a/test/Performance/MSTest.Performance.Runner/Steps/Files.cs +++ b/test/Performance/MSTest.Performance.Runner/Steps/Files.cs @@ -3,4 +3,4 @@ namespace MSTest.Performance.Runner.Steps; -internal record Files(string[] FilesCollection) : IPayload; +internal sealed record Files(string[] FilesCollection) : IPayload; From 4da8915b31e18c6afcf20503ee143becfa2dcbea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 5 Dec 2024 16:12:34 +0100 Subject: [PATCH 064/273] Fix playground project --- samples/Playground/Program.cs | 1 - samples/Playground/ServerMode/TestingPlatformClientFactory.cs | 4 ---- 2 files changed, 5 deletions(-) diff --git a/samples/Playground/Program.cs b/samples/Playground/Program.cs index b333df12e7..c49a0d0999 100644 --- a/samples/Playground/Program.cs +++ b/samples/Playground/Program.cs @@ -9,7 +9,6 @@ using Microsoft.Testing.Platform.Extensions.TestHostControllers; using Microsoft.Testing.Platform.Messages; using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; -using Microsoft.Testing.Platform.Services; using Microsoft.Testing.Platform.TestHost; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/samples/Playground/ServerMode/TestingPlatformClientFactory.cs b/samples/Playground/ServerMode/TestingPlatformClientFactory.cs index fe054644f3..f4da060cd4 100644 --- a/samples/Playground/ServerMode/TestingPlatformClientFactory.cs +++ b/samples/Playground/ServerMode/TestingPlatformClientFactory.cs @@ -7,7 +7,6 @@ using System.Net; using System.Net.Sockets; using System.Text; -using System.Text.RegularExpressions; using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; @@ -73,9 +72,6 @@ public static async Task StartAsServerAndConnectToTheClie return new TestingPlatformClient(new(tcpClient.GetStream()), tcpClient, processHandler); } - - [GeneratedRegex(@"Starting server. Listening on port '(\d+)'")] - private static partial Regex ParsePort(); } public sealed class ProcessConfiguration From a7410522fdb0224409070d42a856434a1ad992dd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 5 Dec 2024 15:59:24 +0000 Subject: [PATCH 065/273] [main] Update dependencies from devdiv/DevDiv/vs-code-coverage, microsoft/testanywhere (#4244) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 9e478314de..ea277e2c53 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,13 +13,13 @@ https://github.com/dotnet/arcade 45d845e04c05fbe5da9838c454bbc3af1df6be81 - + https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage - d9ab1aae37bfdcc5ba1f0b2ecf45be1058673059 + eb105201ff904a7d5c6fac39de838a4bb6966a93 - + https://github.com/microsoft/testanywhere - 16e36e5fb2a4c3cae9dd5e0b041f72dce371d300 + 33cb71263430f0dbe8f9ffd4edd76d837cb05259 https://github.com/microsoft/testanywhere diff --git a/eng/Versions.props b/eng/Versions.props index 27d46c27dc..7522c58f20 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,9 +8,9 @@ 10.0.0-beta.24604.4 - 17.13.2-preview.24603.5 + 17.13.2-preview.24605.2 - 1.5.0-preview.24603.5 + 1.5.0-preview.24604.2 1.0.0-alpha.24473.2 From ee0cc58268e7bd19aeeb9ddb8c872da7f3c2ba3b Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 5 Dec 2024 20:38:06 +0100 Subject: [PATCH 066/273] Cleanup FailedStates in TrxReportEngine (#4247) --- .../TrxReportEngine.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportEngine.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportEngine.cs index 10d7a0399a..79a64331c9 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportEngine.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportEngine.cs @@ -16,6 +16,7 @@ using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.Extensions.TestFramework; using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.Messages; using Microsoft.Testing.Platform.Services; namespace Microsoft.Testing.Extensions.TrxReport.Abstractions; @@ -28,14 +29,6 @@ internal sealed partial class TrxReportEngine private static readonly Regex InvalidXmlCharReplace = BuildInvalidXmlCharReplace(); private static readonly MatchEvaluator InvalidXmlEvaluator = ReplaceInvalidCharacterWithUniCodeEscapeSequence; - private static readonly Type[] FailedStates = - [ - typeof(FailedTestNodeStateProperty), - typeof(CancelledTestNodeStateProperty), - typeof(ErrorTestNodeStateProperty), - typeof(TimeoutTestNodeStateProperty) - ]; - private static readonly HashSet InvalidFileNameChars = [ '\"', @@ -469,7 +462,7 @@ private void AddResults(string testAppModule, XElement testRun, out XElement tes string outcome = "Passed"; TestNodeStateProperty? testState = testNode.Properties.SingleOrDefault(); if (testState is { } state - && FailedStates.Contains(testState.GetType())) + && TestNodePropertiesCategories.WellKnownTestNodeTestRunOutcomeFailedProperties.Contains(testState.GetType())) { outcome = resultSummaryOutcome = "Failed"; } From ef27d27af94c0ffbf69f77d04a28ec907ad83499 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 6 Dec 2024 10:53:31 +0100 Subject: [PATCH 067/273] [main] Bump MicrosoftCodeAnalysisAnalyzersVersion from 3.11.0-beta1.24574.2 to 3.11.0-beta1.24605.2 (#4252) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index d87626fa7e..2be713e468 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,7 +6,7 @@ 8.2.2 17.11.4 - 3.11.0-beta1.24574.2 + 3.11.0-beta1.24605.2 3.11.0 4.10.0 $(MicrosoftCodeAnalysisAnalyzersVersion) From dead25f370b20728623e0802ed62f3a161ab5be4 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Fri, 6 Dec 2024 02:13:40 -0800 Subject: [PATCH 068/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2596498 --- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf index 52437221ca..d58b3e72b6 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + Použít {0} diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf index 2efae20a2f..0dde1ce7ba 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + Utiliser « {0} » diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf index d8b88fbb48..acacf8c10d 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + Usa '{0}' From 1e0332be7f2849306c239b57345e9a034720dbac Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Fri, 6 Dec 2024 02:15:03 -0800 Subject: [PATCH 069/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2596498 --- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf index 3c8412618a..fe8e6c7875 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + 使用“{0}” diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf index 64444c7af9..c30f129ce5 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf @@ -84,7 +84,7 @@ Use '{0}' - Use '{0}' + 使用 '{0}' From 65c3a72736c138ce7c5d6e1f88ec74fa8b0ec138 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Fri, 6 Dec 2024 02:16:27 -0800 Subject: [PATCH 070/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2596498 --- .../Resources/xlf/PlatformResources.cs.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.de.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.es.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.fr.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.it.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.ja.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.ko.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.pl.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.pt-BR.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.ru.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.tr.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.zh-Hans.xlf | 14 +++++++------- .../Resources/xlf/PlatformResources.zh-Hant.xlf | 14 +++++++------- 13 files changed, 91 insertions(+), 91 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index 4526c31089..3bdbc0f3a3 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + Výjimka při rušení ID žádosti '{0}' {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + Testovací relace byla dokončena. @@ -645,12 +645,12 @@ Může mít jenom jeden argument jako řetězec ve formátu <value>[h|m|s] The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + Implementace ITestHost použitá při spuštění režimu serveru Server mode test host - Server mode test host + Testovací hostitel režimu serveru @@ -710,12 +710,12 @@ Může mít jenom jeden argument jako řetězec ve formátu <value>[h|m|s] Starting test session. - Starting test session. + Spouští se testovací relace. Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + Spouští se testovací relace. Cesta k souboru protokolu je '{0}'. @@ -929,7 +929,7 @@ Platné hodnoty jsou Normal a Detailed. Výchozí hodnota je Normal. [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Neošetřená výjimka: {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index ce0825be7a..5d14ba2145 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + Ausnahme beim Abbrechen der Anforderungs-ID '{0}' {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + Die Testsitzung wurde beendet. @@ -645,12 +645,12 @@ Nimmt ein Argument als Zeichenfolge im Format <value>[h|m|s], wobei "value The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + Die implementierung "ITestHost", die beim Ausführen des Servermodus verwendet wird. Server mode test host - Server mode test host + Testhost für Servermodus @@ -710,12 +710,12 @@ Nimmt ein Argument als Zeichenfolge im Format <value>[h|m|s], wobei "value Starting test session. - Starting test session. + Die Testsitzung wird gestartet. Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + Die Testsitzung wird gestartet. Der Protokolldateipfad ist '{0}'. @@ -929,7 +929,7 @@ Gültige Werte sind „Normal“, „Detailed“. Der Standardwert ist „Normal [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Ausnahmefehler: {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index 095d36bf98..c0b9273013 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + Excepción durante la cancelación del id. de solicitud '{0}' {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + Finalizó la sesión de prueba. @@ -645,12 +645,12 @@ Toma un argumento como cadena con el formato <value>[h|m|s] donde 'value' The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + Implementación de 'ITestHost' usada al ejecutar el modo de servidor. Server mode test host - Server mode test host + Host de prueba en modo servidor @@ -710,12 +710,12 @@ Toma un argumento como cadena con el formato <value>[h|m|s] donde 'value' Starting test session. - Starting test session. + Iniciando sesión de prueba. Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + Iniciando sesión de prueba. La ruta de acceso del archivo de registro es '{0}'. @@ -929,7 +929,7 @@ Los valores válidos son 'Normal', 'Detallado'. El valor predeterminado es 'Norm [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] excepción no controlada: {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index 2b23f3d009..0b8c6bc0b7 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + Exception lors de l’annulation de l’ID de demande '{0}' {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + Session de test terminée. @@ -645,12 +645,12 @@ Prend un argument sous forme de chaîne au format <value>[h|m|s] où « v The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + Implémentation 'ITestHost' utilisée lors de l’exécution du mode serveur. Server mode test host - Server mode test host + Hôte de test du mode serveur @@ -710,12 +710,12 @@ Prend un argument sous forme de chaîne au format <value>[h|m|s] où « v Starting test session. - Starting test session. + Démarrage de la session de test. Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + Démarrage de la session de test. Le chemin d’accès au fichier journal est '{0}'. @@ -929,7 +929,7 @@ Les valeurs valides sont « Normal » et « Détaillé ». La valeur par dé [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] exception non prise en charge : {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index f8450b7534..d3e5c55526 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + Eccezione durante l'annullamento dell'ID richiesta '{0}' {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + Sessione di test completata. @@ -645,12 +645,12 @@ Acquisisce un argomento come stringa nel formato <value>[h|m|s] dove 'valu The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + Implementazione di 'ITestHost' usata durante l'esecuzione della modalità server. Server mode test host - Server mode test host + Host di test in modalità server @@ -710,12 +710,12 @@ Acquisisce un argomento come stringa nel formato <value>[h|m|s] dove 'valu Starting test session. - Starting test session. + Avvio della sessione di test. Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + Avvio della sessione di test. Il percorso del file di log è '{0}'. @@ -929,7 +929,7 @@ I valori validi sono 'Normal', 'Detailed'. L'impostazione predefinita è 'Normal [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] eccezione non gestita: {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index 6411ac9405..04505b2af6 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + 要求 ID '{0}' の取り消し中に例外が発生しました {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + テスト セッションを終了しました。 @@ -646,12 +646,12 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + サーバー モードの実行時に使用される 'ITestHost' 実装。 Server mode test host - Server mode test host + サーバー モード テスト ホスト @@ -711,12 +711,12 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Starting test session. - Starting test session. + テスト セッションを開始しています。 Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + テスト セッションを開始しています。ログ ファイルのパスが '{0}' です。 @@ -930,7 +930,7 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + ハンドルされない例外 [ServerTestHost.OnTaskSchedulerUnobservedTaskException]: {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index 73ab4a51df..8a32fd0626 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + 요청 ID를 취소하는 동안 예외가 '{0}' {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + 테스트 세션을 마쳤습니다. @@ -645,12 +645,12 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + 서버 모드를 실행할 때 사용되는 'ITestHost' 구현입니다. Server mode test host - Server mode test host + 서버 모드 테스트 호스트 @@ -710,12 +710,12 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Starting test session. - Starting test session. + 테스트 세션을 시작하는 중입니다. Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + 테스트 세션을 시작하는 중입니다. 로그 파일 경로가 '{0}'. @@ -929,7 +929,7 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + 처리되지 않은 예외 [ServerTestHost.OnTaskSchedulerUnobservedTaskException]: {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index 127548414d..6b5d42a576 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + Wyjątek podczas anulowania '{0}' identyfikatora żądania {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + Zakończono sesję testą. @@ -645,12 +645,12 @@ Pobiera jeden argument jako ciąg w formacie <value>[h|m|s], gdzie element The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + Implementacja "ITestHost" używana podczas uruchamiania trybu serwera. Server mode test host - Server mode test host + Host testów trybu serwera @@ -710,12 +710,12 @@ Pobiera jeden argument jako ciąg w formacie <value>[h|m|s], gdzie element Starting test session. - Starting test session. + Rozpoczynanie sesji testowej. Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + Rozpoczynanie sesji testowej. Ścieżka pliku dziennika jest '{0}'. @@ -929,7 +929,7 @@ Prawidłowe wartości to „Normalne”, „Szczegółowe”. Wartość domyśln [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Nieobsługiwany wyjątek: {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index d303930104..396831b6e5 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + Exceção durante o cancelamento da ID da solicitação '{0}' {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + Sessão de teste concluída. @@ -645,12 +645,12 @@ Recebe um argumento como cadeia de caracteres no formato <valor>[h|m|s] em The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + A implementação 'ITestHost' usada ao executar o modo de servidor. Server mode test host - Server mode test host + Host de teste do modo de servidor @@ -710,12 +710,12 @@ Recebe um argumento como cadeia de caracteres no formato <valor>[h|m|s] em Starting test session. - Starting test session. + Iniciando sessão de teste. Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + Iniciando sessão de teste. O caminho do arquivo de log '{0}'. @@ -929,7 +929,7 @@ Os valores válidos são “Normal”, “Detalhado”. O padrão é “Normal [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] exceção sem tratamento: {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index 42539f5b67..6f5ec3345d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + Исключение при отмене запроса '{0}' {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + Тестовый сеанс завершен. @@ -645,12 +645,12 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + Реализация "ITestHost", используемая при работе в режиме сервера. Server mode test host - Server mode test host + Тестовый хост в режиме сервера @@ -710,12 +710,12 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Starting test session. - Starting test session. + Запуск тестового сеанса. Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + Запуск тестового сеанса. Путь к файлу журнала '{0}'. @@ -929,7 +929,7 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] необработанное исключение: {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 91326a0e25..25f69e948c 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + İstek kimliği iptali sırasında özel durum '{0}' {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + Test oturumu bitti. @@ -645,12 +645,12 @@ Bir bağımsız değişkeni, 'value' değerinin kayan olduğu <value>[h|m| The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + Sunucu modu çalıştırılırken kullanılan 'ITestHost' uygulaması. Server mode test host - Server mode test host + Sunucu modu test ana bilgisayarı @@ -710,12 +710,12 @@ Bir bağımsız değişkeni, 'value' değerinin kayan olduğu <value>[h|m| Starting test session. - Starting test session. + Test oturumu başlatılıyor. Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + Test oturumu başlatılıyor. Günlük dosyası yolu '{0}'. @@ -929,7 +929,7 @@ Geçerli değerler: ‘Normal’, ‘Ayrıntılı’. Varsayılan değer: ‘Nor [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] özel durum: {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 3ee2239188..833edb5f9c 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + 取消请求 ID 期间出现异常 '{0}' {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + 已完成测试会话。 @@ -645,12 +645,12 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + 运行服务器模式时使用的 “ITestHost” 实现。 Server mode test host - Server mode test host + 服务器模式测试主机 @@ -710,12 +710,12 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Starting test session. - Starting test session. + 正在启动测试会话。 Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + 正在启动测试会话。日志文件路径 '{0}'。 @@ -929,7 +929,7 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] 未经处理的异常: {0} {0} is the exception that was unhandled/unobserved diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index 80a74a1d82..218d20906d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -221,7 +221,7 @@ Exception during the cancellation of request id '{0}' - Exception during the cancellation of request id '{0}' + 取消要求標識碼 '{0}' 期間發生例外狀況 {0} is the request id @@ -278,7 +278,7 @@ Finished test session. - Finished test session. + 已完成測試會話。 @@ -645,12 +645,12 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is The 'ITestHost' implementation used when running server mode. - The 'ITestHost' implementation used when running server mode. + 執行伺服器模式時使用的 『ITestHost』 實作。 Server mode test host - Server mode test host + 伺服器模式測試主機 @@ -710,12 +710,12 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Starting test session. - Starting test session. + 正在啟動測試會話。 Starting test session. The log file path is '{0}'. - Starting test session. The log file path is '{0}'. + 正在啟動測試會話。記錄檔路徑 '{0}'。 @@ -929,7 +929,7 @@ Valid values are 'Normal', 'Detailed'. Default is 'Normal'. [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} - [ServerTestHost.OnTaskSchedulerUnobservedTaskException] Unhandled exception: {0} + [ServerTestHost.OnTaskSchedulerUnobservedTaskException] 未處理的例外狀況: {0} {0} is the exception that was unhandled/unobserved From beb890d4fe699cf718748884c1e642e28239c1fc Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 6 Dec 2024 20:59:08 +0100 Subject: [PATCH 071/273] Use `ValidationResult.ValidTask` instead of `Task.FromResult(ValidationResult.Valid())` (#4262) --- .../CrashDumpEnvironmentVariableProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs index ee85390bf8..ae351902ac 100644 --- a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs @@ -198,7 +198,7 @@ public Task ValidateTestHostEnvironmentVariablesAsync(IReadOnl } } - return Task.FromResult(errors.Length > 0 ? ValidationResult.Invalid(errors.ToString()) : ValidationResult.Valid()); + return errors.Length > 0 ? Task.FromResult(ValidationResult.Invalid(errors.ToString())) : ValidationResult.ValidTask; static void AddError(StringBuilder errors, string variableName, string? expectedValue, string? actualValue) { From d269367836fd50071f08134a56c70721d8584d22 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sat, 7 Dec 2024 14:40:34 +0100 Subject: [PATCH 072/273] Avoid Linq allocations from usage of Union (#4265) --- .../CommandLineOptionsValidator.cs | 24 +++++++++++++------ 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsValidator.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsValidator.cs index 56fa01c467..3449c90813 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsValidator.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsValidator.cs @@ -225,12 +225,24 @@ private static async Task ValidateOptionsArgumentsAsync( } private static async Task ValidateConfigurationAsync( - IEnumerable extensionsProviders, - IEnumerable systemProviders, + Dictionary>.KeyCollection extensionsProviders, + Dictionary>.KeyCollection systemProviders, ICommandLineOptions commandLineOptions) { - StringBuilder? stringBuilder = null; - foreach (ICommandLineOptionsProvider commandLineOptionsProvider in systemProviders.Union(extensionsProviders)) + StringBuilder? stringBuilder = await ValidateConfigurationAsync(systemProviders, commandLineOptions, null); + stringBuilder = await ValidateConfigurationAsync(extensionsProviders, commandLineOptions, stringBuilder); + + return stringBuilder?.Length > 0 + ? ValidationResult.Invalid(stringBuilder.ToTrimmedString()) + : ValidationResult.Valid(); + } + + private static async Task ValidateConfigurationAsync( + Dictionary>.KeyCollection providers, + ICommandLineOptions commandLineOptions, + StringBuilder? stringBuilder) + { + foreach (ICommandLineOptionsProvider commandLineOptionsProvider in providers) { ValidationResult result = await commandLineOptionsProvider.ValidateCommandLineOptionsAsync(commandLineOptions); if (!result.IsValid) @@ -241,9 +253,7 @@ private static async Task ValidateConfigurationAsync( } } - return stringBuilder?.Length > 0 - ? ValidationResult.Invalid(stringBuilder.ToTrimmedString()) - : ValidationResult.Valid(); + return stringBuilder; } private static string ToTrimmedString(this StringBuilder stringBuilder) From 8dc8b14491cd7946c70357e3463d3a8a46f548e0 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sat, 7 Dec 2024 14:40:58 +0100 Subject: [PATCH 073/273] Avoid repetitive string.Format call for every character of command-line options (#4264) --- .../CommandLine/CommandLineOption.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs index 398da42025..aa3cf47b5e 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs @@ -29,9 +29,10 @@ internal CommandLineOption(string name, string description, ArgumentArity arity, Guard.NotNullOrWhiteSpace(description); ArgumentGuard.Ensure(arity.Max >= arity.Min, nameof(arity), PlatformResources.CommandLineInvalidArityErrorMessage); + string errorMessage = string.Format(CultureInfo.InvariantCulture, PlatformResources.CommandLineInvalidOptionName, name); for (int i = 0; i < name.Length; i++) { - ArgumentGuard.Ensure(char.IsLetterOrDigit(name[i]) || name[i] == '-' || name[i] == '?', nameof(name), string.Format(CultureInfo.InvariantCulture, PlatformResources.CommandLineInvalidOptionName, name)); + ArgumentGuard.Ensure(char.IsLetterOrDigit(name[i]) || name[i] == '-' || name[i] == '?', nameof(name), errorMessage); } Name = name; From e101a9d48773cc935c7b536d25d378d9a3211fee Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sat, 7 Dec 2024 14:44:03 +0100 Subject: [PATCH 074/273] More efficient reflection (#4263) --- .../Discovery/AssemblyEnumerator.cs | 2 +- .../Discovery/TypeValidator.cs | 2 +- .../MSTest.TestAdapter/Execution/TypeCache.cs | 4 +-- .../SourceGeneratedReflectionOperations.cs | 8 +++--- .../Interfaces/IReflectionOperations2.cs | 8 +++--- .../Services/ReflectionOperations2.cs | 25 +++++++++++-------- .../Discovery/AssemblyEnumeratorTests.cs | 22 ++++++++-------- 7 files changed, 37 insertions(+), 34 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs index 0b097fbe8a..883b634e78 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs @@ -83,7 +83,7 @@ internal ICollection EnumerateAssembly(string assemblyFileName, Assembly assembly = PlatformServiceProvider.Instance.FileOperations.LoadAssembly(assemblyFileName, isReflectionOnly: false); - IReadOnlyList types = GetTypes(assembly, assemblyFileName, warningMessages); + Type[] types = GetTypes(assembly, assemblyFileName, warningMessages); bool discoverInternals = ReflectHelper.GetDiscoverInternalsAttribute(assembly) != null; TestIdGenerationStrategy testIdGenerationStrategy = ReflectHelper.GetTestIdGenerationStrategy(assembly); diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs index 386891f596..916c7da27a 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs @@ -106,7 +106,7 @@ internal static bool HasCorrectTestContextSignature(Type type) { DebugEx.Assert(type != null, "HasCorrectTestContextSignature type is null"); - IEnumerable propertyInfoEnumerable = PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredProperties(type); + PropertyInfo[] propertyInfoEnumerable = PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredProperties(type); var propertyInfo = new List(); foreach (PropertyInfo pinfo in propertyInfoEnumerable) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index 5b07edca36..6ab6227133 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -259,7 +259,7 @@ private static bool TryGetUnescapedManagedTypeName(TestMethod testMethod, [NotNu /// The . private TestClassInfo CreateClassInfo(Type classType, TestMethod testMethod) { - IEnumerable constructors = PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredConstructors(classType); + ConstructorInfo[] constructors = PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredConstructors(classType); (ConstructorInfo CtorInfo, bool IsParameterless)? selectedConstructor = null; foreach (ConstructorInfo ctor in constructors) @@ -399,7 +399,7 @@ private TestAssemblyInfo GetAssemblyInfo(Type type) assemblyInfo = new TestAssemblyInfo(assembly); - IReadOnlyList types = AssemblyEnumerator.GetTypes(assembly, assembly.FullName!, null); + Type[] types = AssemblyEnumerator.GetTypes(assembly, assembly.FullName!, null); foreach (Type t in types) { diff --git a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs index c69b9bbdc4..19877998ab 100644 --- a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs @@ -50,16 +50,16 @@ public object[] GetCustomAttributes(Assembly assembly, Type /* the attribute typ return attributes.ToArray(); } - public IEnumerable GetDeclaredConstructors(Type classType) + public ConstructorInfo[] GetDeclaredConstructors(Type classType) => ReflectionDataProvider.TypeConstructors[classType]; public MethodInfo? GetDeclaredMethod(Type dynamicDataDeclaringType, string dynamicDataSourceName) => GetDeclaredMethods(dynamicDataDeclaringType).FirstOrDefault(m => m.Name == dynamicDataSourceName); - public IEnumerable GetDeclaredMethods(Type classType) + public MethodInfo[] GetDeclaredMethods(Type classType) => ReflectionDataProvider.TypeMethods[classType]; - public IEnumerable GetDeclaredProperties(Type type) + public PropertyInfo[] GetDeclaredProperties(Type type) => ReflectionDataProvider.TypeProperties[type]; public PropertyInfo? GetDeclaredProperty(Type type, string propertyName) @@ -68,7 +68,7 @@ public IEnumerable GetDeclaredProperties(Type type) public Type[] GetDefinedTypes(Assembly assembly) => ReflectionDataProvider.Types; - public IEnumerable GetRuntimeMethods(Type type) + public MethodInfo[] GetRuntimeMethods(Type type) => ReflectionDataProvider.TypeMethods[type]; public MethodInfo? GetRuntimeMethod(Type declaringType, string methodName, Type[] parameters) => throw new NotImplementedException(); diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs index 4e651384d6..7de179b9f6 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs @@ -7,19 +7,19 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int internal interface IReflectionOperations2 : IReflectionOperations { - IEnumerable GetDeclaredConstructors(Type classType); + ConstructorInfo[] GetDeclaredConstructors(Type classType); MethodInfo? GetDeclaredMethod(Type dynamicDataDeclaringType, string dynamicDataSourceName); - IEnumerable GetDeclaredMethods(Type classType); + MethodInfo[] GetDeclaredMethods(Type classType); - IEnumerable GetDeclaredProperties(Type type); + PropertyInfo[] GetDeclaredProperties(Type type); PropertyInfo? GetDeclaredProperty(Type type, string propertyName); Type[] GetDefinedTypes(Assembly assembly); - IEnumerable GetRuntimeMethods(Type type); + MethodInfo[] GetRuntimeMethods(Type type); MethodInfo? GetRuntimeMethod(Type declaringType, string methodName, Type[] parameters); diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs index 9fd567d020..653a5d7499 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs @@ -9,6 +9,9 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; internal sealed class ReflectionOperations2 : ReflectionOperations, IReflectionOperations2 { + private const BindingFlags DeclaredOnlyLookup = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly; + private const BindingFlags Everything = BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance; + public ReflectionOperations2() { #if NET8_0_OR_GREATER @@ -23,26 +26,26 @@ public ReflectionOperations2() #pragma warning disable IL2026 // Members attributed with RequiresUnreferencedCode may break when trimming #pragma warning disable IL2067 // 'target parameter' argument does not satisfy 'DynamicallyAccessedMembersAttribute' in call to 'target method'. #pragma warning disable IL2057 // Unrecognized value passed to the typeName parameter of 'System.Type.GetType(String)' - public IEnumerable GetDeclaredConstructors(Type classType) - => classType.GetTypeInfo().DeclaredConstructors; + public ConstructorInfo[] GetDeclaredConstructors(Type classType) + => classType.GetConstructors(DeclaredOnlyLookup); public MethodInfo? GetDeclaredMethod(Type type, string methodName) - => type.GetTypeInfo().GetDeclaredMethod(methodName); + => type.GetMethod(methodName, DeclaredOnlyLookup); - public IEnumerable GetDeclaredMethods(Type classType) - => classType.GetTypeInfo().DeclaredMethods; + public MethodInfo[] GetDeclaredMethods(Type classType) + => classType.GetMethods(DeclaredOnlyLookup); - public IEnumerable GetDeclaredProperties(Type type) - => type.GetTypeInfo().DeclaredProperties; + public PropertyInfo[] GetDeclaredProperties(Type type) + => type.GetProperties(DeclaredOnlyLookup); public PropertyInfo? GetDeclaredProperty(Type type, string propertyName) - => type.GetTypeInfo().GetDeclaredProperty(propertyName); + => type.GetProperty(propertyName, DeclaredOnlyLookup); public Type[] GetDefinedTypes(Assembly assembly) - => assembly.DefinedTypes.ToArray(); + => assembly.GetTypes(); - public IEnumerable GetRuntimeMethods(Type type) - => type.GetRuntimeMethods(); + public MethodInfo[] GetRuntimeMethods(Type type) + => type.GetMethods(Everything); public MethodInfo? GetRuntimeMethod(Type declaringType, string methodName, Type[] parameters) => declaringType.GetRuntimeMethod(methodName, parameters); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs index c34c2d834f..77d616faae 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs @@ -101,7 +101,7 @@ public void GetTypesShouldReturnSetOfDefinedTypes() TypeInfo[] expectedTypes = [typeof(DummyTestClass).GetTypeInfo(), typeof(DummyTestClass).GetTypeInfo()]; // Setup mocks - mockAssembly.Setup(a => a.DefinedTypes).Returns(expectedTypes); + mockAssembly.Setup(a => a.GetTypes()).Returns(expectedTypes); IReadOnlyList types = AssemblyEnumerator.GetTypes(mockAssembly.Object, string.Empty, _warnings); Verify(expectedTypes.SequenceEqual(types)); @@ -123,7 +123,7 @@ public void GetTypesShouldReturnReflectionTypeLoadExceptionTypesOnException() var reflectedTypes = new Type[] { typeof(DummyTestClass) }; // Setup mocks - mockAssembly.Setup(a => a.DefinedTypes).Throws(new ReflectionTypeLoadException(reflectedTypes, null)); + mockAssembly.Setup(a => a.GetTypes()).Throws(new ReflectionTypeLoadException(reflectedTypes, null)); IReadOnlyList types = AssemblyEnumerator.GetTypes(mockAssembly.Object, string.Empty, _warnings); @@ -137,8 +137,8 @@ public void GetTypesShouldLogWarningsWhenReflectionFailsWithLoaderExceptions() var exceptions = new Exception[] { new("DummyLoaderException") }; // Setup mocks - mockAssembly.Setup(a => a.DefinedTypes).Throws(new ReflectionTypeLoadException(null, exceptions)); - mockAssembly.Setup(a => a.DefinedTypes).Throws(new ReflectionTypeLoadException(null, exceptions)); + mockAssembly.Setup(a => a.GetTypes()).Throws(new ReflectionTypeLoadException(null, exceptions)); + mockAssembly.Setup(a => a.GetTypes()).Throws(new ReflectionTypeLoadException(null, exceptions)); IReadOnlyList types = AssemblyEnumerator.GetTypes(mockAssembly.Object, "DummyAssembly", _warnings); @@ -237,7 +237,7 @@ public void EnumerateAssemblyShouldReturnEmptyListWhenNoTestElementsInAType() // Setup mocks mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(DummyTestClass)]); - mockAssembly.Setup(a => a.DefinedTypes) + mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(DummyTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); @@ -256,7 +256,7 @@ public void EnumerateAssemblyShouldReturnTestElementsForAType() // Setup mocks mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(DummyTestClass)]); - mockAssembly.Setup(a => a.DefinedTypes) + mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(DummyTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); @@ -278,7 +278,7 @@ public void EnumerateAssemblyShouldReturnMoreThanOneTestElementForAType() // Setup mocks mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(DummyTestClass)]); - mockAssembly.Setup(a => a.DefinedTypes) + mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(DummyTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); @@ -300,7 +300,7 @@ public void EnumerateAssemblyShouldReturnMoreThanOneTestElementForMoreThanOneTyp // Setup mocks mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(DummyTestClass), typeof(DummyTestClass)]); - mockAssembly.Setup(a => a.DefinedTypes) + mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(DummyTestClass).GetTypeInfo(), typeof(DummyTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); @@ -323,7 +323,7 @@ public void EnumerateAssemblyShouldNotLogWarningsIfNonePresent() // Setup mocks mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(InternalTestClass)]); - mockAssembly.Setup(a => a.DefinedTypes) + mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(InternalTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); @@ -345,7 +345,7 @@ public void EnumerateAssemblyShouldLogWarningsIfPresent() // Setup mocks mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(InternalTestClass)]); - mockAssembly.Setup(a => a.DefinedTypes) + mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(InternalTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); @@ -365,7 +365,7 @@ public void EnumerateAssemblyShouldHandleExceptionsWhileEnumeratingAType() // Setup mocks mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(InternalTestClass)]); - mockAssembly.Setup(a => a.DefinedTypes) + mockAssembly.Setup(a => a.GetTypes()) .Returns([typeof(InternalTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); From 4224ceac7579e939334b563185d94ab966a7dee1 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 8 Dec 2024 08:49:50 +0100 Subject: [PATCH 075/273] [Performance] Avoid System.Action allocations for test context cancellation (#4272) --- .../Execution/TestExecutionManager.cs | 2 +- .../Execution/TestRunCancellationToken.cs | 10 ++++++---- .../MSTest.TestAdapter/PlatformServiceProvider.cs | 4 +++- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs index f3a8913b9d..9df21eb37a 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs @@ -305,7 +305,7 @@ private void ExecuteTestsInSource(IEnumerable tests, IRunContext? runC [MSTestSettings.CurrentSettings, unitTestElements, (int)sourceSettings.ClassCleanupLifecycle])!; // Ensures that the cancellation token gets through AppDomain boundary. - _testRunCancellationToken?.Register(testRunner.Cancel); + _testRunCancellationToken?.Register(static state => ((UnitTestRunner)state!).Cancel(), testRunner); if (MSTestSettings.CurrentSettings.ParallelizationWorkers.HasValue) { diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs index 2bf81e04f7..fb380b6bb2 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs @@ -19,7 +19,7 @@ public class TestRunCancellationToken /// Callbacks to be invoked when canceled. /// Needs to be a concurrent collection, see https://github.com/microsoft/testfx/issues/3953. /// - private readonly ConcurrentBag _registeredCallbacks = new(); + private readonly ConcurrentBag<(Action, object?)> _registeredCallbacks = new(); public TestRunCancellationToken() : this(CancellationToken.None) @@ -43,9 +43,9 @@ private set if (!previousValue && value) { - foreach (Action callBack in _registeredCallbacks) + foreach ((Action callBack, object? state) in _registeredCallbacks) { - callBack.Invoke(); + callBack.Invoke(state); } } } @@ -60,7 +60,9 @@ private set /// Registers a callback method to be invoked when canceled. /// /// Callback delegate for handling cancellation. - public void Register(Action callback) => _registeredCallbacks.Add(callback); + public void Register(Action callback) => _registeredCallbacks.Add((_ => callback(), null)); + + internal void Register(Action callback, object? state) => _registeredCallbacks.Add((callback, state)); /// /// Unregister the callback method. diff --git a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs index 32f77ac5b2..94bcdc3e8d 100644 --- a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs @@ -17,6 +17,8 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// internal sealed class PlatformServiceProvider : IPlatformServiceProvider { + private static readonly Action CancelDelegate = static state => ((TestContextImplementation)state!).Context.CancellationTokenSource.Cancel(); + /// /// Initializes a new instance of the class - a singleton. /// @@ -223,7 +225,7 @@ public ITestSourceHost CreateTestSourceHost( public ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties) { var testContextImplementation = new TestContextImplementation(testMethod, writer, properties); - TestRunCancellationToken?.Register(testContextImplementation.Context.CancellationTokenSource.Cancel); + TestRunCancellationToken?.Register(CancelDelegate, testContextImplementation); return testContextImplementation; } } From 02579cc031e8481d486d21a28162e2ad4e4bf045 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 8 Dec 2024 08:52:35 +0100 Subject: [PATCH 076/273] [Performance] Avoid TraitCollection.AddRange call with empty array (#4274) --- src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs index 30cb0945e8..befe0aa491 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs @@ -170,7 +170,7 @@ internal TestCase ToTestCase() testCase.SetPropertyValue(Constants.PriorityProperty, Priority.Value); } - if (Traits != null) + if (Traits is { Length: > 0 }) { testCase.Traits.AddRange(Traits); } From 97cb7b4cc9be8942ee3ce06fc113d0543a12a60a Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 8 Dec 2024 08:59:01 +0100 Subject: [PATCH 077/273] [Performance] Don't parse the same runsettings for each class in the assembly (#4270) --- .../Discovery/AssemblyEnumerator.cs | 19 +++++++-------- .../Discovery/AssemblyEnumeratorWrapper.cs | 5 ++-- .../Discovery/AssemblyEnumeratorTests.cs | 23 +++++++++---------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs index 883b634e78..7ba81401ee 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs @@ -50,11 +50,6 @@ public AssemblyEnumerator(MSTestSettings settings) => // This would just be resetting the settings to itself in non desktop workflows. MSTestSettings.PopulateSettings(settings); - /// - /// Gets or sets the run settings to use for current discovery session. - /// - public string? RunSettingsXml { get; set; } - /// /// Returns object to be used for controlling lifetime, null means infinite lifetime. /// @@ -71,9 +66,13 @@ public AssemblyEnumerator(MSTestSettings settings) => /// Enumerates through all types in the assembly in search of valid test methods. /// /// The assembly file name. + /// The xml specifying runsettings. /// Contains warnings if any, that need to be passed back to the caller. /// A collection of Test Elements. - internal ICollection EnumerateAssembly(string assemblyFileName, out ICollection warnings) + internal ICollection EnumerateAssembly( + string assemblyFileName, + [StringSyntax(StringSyntaxAttribute.Xml, nameof(runSettingsXml))] string? runSettingsXml, + out ICollection warnings) { DebugEx.Assert(!StringEx.IsNullOrWhiteSpace(assemblyFileName), "Invalid assembly file name."); var warningMessages = new List(); @@ -101,6 +100,8 @@ internal ICollection EnumerateAssembly(string assemblyFileName, ? TestDataSourceDiscoveryOption.DuringExecution : TestDataSourceDiscoveryOption.DuringDiscovery); #pragma warning restore CS0618 // Type or member is obsolete + + Dictionary? testRunParametersFromRunSettings = RunSettingsUtilities.GetTestRunParameters(runSettingsXml); foreach (Type type in types) { if (type == null) @@ -108,7 +109,7 @@ internal ICollection EnumerateAssembly(string assemblyFileName, continue; } - List testsInType = DiscoverTestsInType(assemblyFileName, RunSettingsXml, type, warningMessages, discoverInternals, + List testsInType = DiscoverTestsInType(assemblyFileName, testRunParametersFromRunSettings, type, warningMessages, discoverInternals, testDataSourceDiscovery, testIdGenerationStrategy, fixturesTests); tests.AddRange(testsInType); } @@ -206,7 +207,7 @@ internal virtual TypeEnumerator GetTypeEnumerator(Type type, string assemblyFile private List DiscoverTestsInType( string assemblyFileName, - [StringSyntax(StringSyntaxAttribute.Xml, nameof(runSettingsXml))] string? runSettingsXml, + Dictionary? testRunParametersFromRunSettings, Type type, List warningMessages, bool discoverInternals, @@ -215,7 +216,7 @@ private List DiscoverTestsInType( HashSet fixturesTests) { IDictionary tempSourceLevelParameters = PlatformServiceProvider.Instance.SettingsProvider.GetProperties(assemblyFileName); - tempSourceLevelParameters = RunSettingsUtilities.GetTestRunParameters(runSettingsXml)?.ConcatWithOverwrites(tempSourceLevelParameters) + tempSourceLevelParameters = testRunParametersFromRunSettings?.ConcatWithOverwrites(tempSourceLevelParameters) ?? tempSourceLevelParameters ?? new Dictionary(); var sourceLevelParameters = tempSourceLevelParameters.ToDictionary(x => x.Key, x => (object?)x.Value); diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs index 9c327d2a91..cc81800eeb 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs @@ -107,15 +107,16 @@ private static ICollection GetTestsInIsolation(string fullFileP // This might not be supported if an older version of Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices // assembly is already loaded into the App Domain. + string? xml = null; try { - assemblyEnumerator.RunSettingsXml = runSettings?.SettingsXml; + xml = runSettings?.SettingsXml; } catch { PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning(Resource.OlderTFMVersionFound); } - return assemblyEnumerator.EnumerateAssembly(fullFilePath, out warnings); + return assemblyEnumerator.EnumerateAssembly(fullFilePath, xml, out warnings); } } diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs index 77d616faae..abd54ca45e 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs @@ -71,10 +71,9 @@ public void ConstructorShouldPopulateSettings() }); var mockMessageLogger = new Mock(); var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, mockMessageLogger.Object); - var assemblyEnumerator = new AssemblyEnumerator(adapterSettings) - { - RunSettingsXml = runSettingsXml, - }; + + // Constructor has the side effect of populating the passed settings to MSTestSettings.CurrentSettings + _ = new AssemblyEnumerator(adapterSettings); Verify(MSTestSettings.CurrentSettings.ForcedLegacyMode); Verify(MSTestSettings.CurrentSettings.TestSettingsFile == "DummyPath\\TestSettings1.testsettings"); @@ -226,7 +225,7 @@ public void EnumerateAssemblyShouldReturnEmptyListWhenNoDeclaredTypes() _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); - Verify(_assemblyEnumerator.EnumerateAssembly("DummyAssembly", out _warnings).Count == 0); + Verify(_assemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings).Count == 0); } public void EnumerateAssemblyShouldReturnEmptyListWhenNoTestElementsInAType() @@ -244,7 +243,7 @@ public void EnumerateAssemblyShouldReturnEmptyListWhenNoTestElementsInAType() testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out _warnings)) .Returns((ICollection)null); - Verify(_assemblyEnumerator.EnumerateAssembly("DummyAssembly", out _warnings).Count == 0); + Verify(_assemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings).Count == 0); } public void EnumerateAssemblyShouldReturnTestElementsForAType() @@ -263,7 +262,7 @@ public void EnumerateAssemblyShouldReturnTestElementsForAType() testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out _warnings)) .Returns(new Collection { unitTestElement }); - ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", out _warnings); + ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); Verify(new Collection { unitTestElement }.SequenceEqual(testElements)); } @@ -285,7 +284,7 @@ public void EnumerateAssemblyShouldReturnMoreThanOneTestElementForAType() testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out _warnings)) .Returns(expectedTestElements); - ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", out _warnings); + ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); Verify(expectedTestElements.SequenceEqual(testElements)); } @@ -307,7 +306,7 @@ public void EnumerateAssemblyShouldReturnMoreThanOneTestElementForMoreThanOneTyp testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out _warnings)) .Returns(expectedTestElements); - ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", out _warnings); + ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); expectedTestElements.Add(unitTestElement); expectedTestElements.Add(unitTestElement); @@ -329,7 +328,7 @@ public void EnumerateAssemblyShouldNotLogWarningsIfNonePresent() .Returns(mockAssembly.Object); testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out warningsFromTypeEnumerator)); - testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", out _warnings); + testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); Verify(_warnings.Count == 0); } @@ -351,7 +350,7 @@ public void EnumerateAssemblyShouldLogWarningsIfPresent() .Returns(mockAssembly.Object); testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out warningsFromTypeEnumerator)); - testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", out _warnings); + testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); Verify(warningsFromTypeEnumerator.ToList().SequenceEqual(_warnings)); } @@ -371,7 +370,7 @@ public void EnumerateAssemblyShouldHandleExceptionsWhileEnumeratingAType() .Returns(mockAssembly.Object); testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out _warnings)).Throws(exception); - testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", out _warnings); + testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); Verify(_warnings.ToList().Contains( string.Format( From f560e78864b7bba34336f60bbd8ff52576c55918 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 8 Dec 2024 20:09:31 +0100 Subject: [PATCH 078/273] Simplify Ignore handling in IsTestMethodRunnable (#4281) --- .../Execution/UnitTestRunner.cs | 26 +++++++------------ .../Helpers/ReflectHelper.cs | 9 ------- 2 files changed, 10 insertions(+), 25 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs index fae1a9d7bc..174155f9aa 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs @@ -340,28 +340,22 @@ private bool IsTestMethodRunnable( } } - string? ignoreMessage = null; - bool isIgnoreAttributeOnClass = - _reflectHelper.IsNonDerivedAttributeDefined(testMethodInfo.Parent.ClassType, false); - bool isIgnoreAttributeOnMethod = - _reflectHelper.IsNonDerivedAttributeDefined(testMethodInfo.TestMethod, false); + IgnoreAttribute? ignoreAttributeOnClass = + _reflectHelper.GetFirstNonDerivedAttributeOrDefault(testMethodInfo.Parent.ClassType, inherit: false); + string? ignoreMessage = ignoreAttributeOnClass?.IgnoreMessage; - if (isIgnoreAttributeOnClass) - { - ignoreMessage = _reflectHelper.GetIgnoreMessage(testMethodInfo.Parent.ClassType); - } + IgnoreAttribute? ignoreAttributeOnMethod = + _reflectHelper.GetFirstNonDerivedAttributeOrDefault(testMethodInfo.TestMethod, inherit: false); - if (StringEx.IsNullOrEmpty(ignoreMessage) && isIgnoreAttributeOnMethod) + if (StringEx.IsNullOrEmpty(ignoreMessage) && ignoreAttributeOnMethod is not null) { - ignoreMessage = _reflectHelper.GetIgnoreMessage(testMethodInfo.TestMethod); + ignoreMessage = ignoreAttributeOnMethod.IgnoreMessage; } - if (isIgnoreAttributeOnClass || isIgnoreAttributeOnMethod) + if (ignoreAttributeOnClass is not null || ignoreAttributeOnMethod is not null) { - { - notRunnableResult = [new UnitTestResult(UnitTestOutcome.Ignored, ignoreMessage)]; - return false; - } + notRunnableResult = [new UnitTestResult(UnitTestOutcome.Ignored, ignoreMessage)]; + return false; } notRunnableResult = null; diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index bf6ecc3d15..34a40beda3 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -344,15 +344,6 @@ internal static bool IsDoNotParallelizeSet(Assembly assembly) internal virtual int? GetPriority(MemberInfo priorityAttributeProvider) => GetFirstDerivedAttributeOrDefault(priorityAttributeProvider, inherit: true)?.Priority; - /// - /// Priority if any set for test method. Will return priority if attribute is applied to TestMethod - /// else null. - /// - /// The member to inspect. - /// Priority value if defined. Null otherwise. - internal virtual string? GetIgnoreMessage(MemberInfo ignoreAttributeProvider) => - GetFirstDerivedAttributeOrDefault(ignoreAttributeProvider, inherit: true)?.IgnoreMessage; - /// /// Gets the class cleanup lifecycle for the class, if set. /// From 04a8dcc5399413b48ad4af4640c6b7309b117d7d Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 8 Dec 2024 20:11:00 +0100 Subject: [PATCH 079/273] Simplify AttributeComparer.IsDerived (#4280) --- .../Helpers/AttributeComparer.cs | 21 +------------------ 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/AttributeComparer.cs b/src/Adapter/MSTest.TestAdapter/Helpers/AttributeComparer.cs index 37623af61b..c82f46d996 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/AttributeComparer.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/AttributeComparer.cs @@ -10,24 +10,5 @@ public static bool IsNonDerived(Attribute attribute) => // So, this should NOT be refactored to 'attribute is TAttribute'. attribute.GetType() == typeof(TAttribute); - public static bool IsDerived(Attribute attribute) - { - Type attributeType = attribute.GetType(); - - // IsSubclassOf returns false when the types are equal. - if (attributeType == typeof(TAttribute)) - { - return true; - } - - // IsAssignableFrom also does this internally, but later falls to check generic - // and we don't need that. - if (!typeof(TAttribute).IsInterface) - { - // This returns false when TAttribute is interface (like ITestDataSource). - return attributeType.IsSubclassOf(typeof(TAttribute)); - } - - return typeof(TAttribute).IsAssignableFrom(attributeType); - } + public static bool IsDerived(Attribute attribute) => attribute is TAttribute; } From ae0e9afa20e3fbfd378a941250c72b846e750dea Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 8 Dec 2024 22:12:44 +0100 Subject: [PATCH 080/273] [Performance] Create dictionary with the right capacity (#4276) --- .../MSTestAdapter.PlatformServices/Services/TestDeployment.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs index 7fe557a194..c8fc00c01a 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs @@ -184,7 +184,7 @@ group test by test.Source into testGroup #if !WINDOWS_UWP internal static IDictionary GetDeploymentInformation(string source) { - var properties = new Dictionary(); + var properties = new Dictionary(capacity: 8); string applicationBaseDirectory = string.Empty; From 45e6516fecacb446253b4b38036316a567a2ecb2 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 8 Dec 2024 22:13:34 +0100 Subject: [PATCH 081/273] [Performance] Avoid repetitive string allocations from TestRunDirectories (#4275) --- .../Deployment/TestRunDirectories.cs | 31 ++++++++++++++----- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs index ecb0a273d8..217bc8b6b6 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs @@ -3,6 +3,8 @@ #if !WINDOWS_UWP +using System.Diagnostics.CodeAnalysis; + using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; @@ -40,28 +42,43 @@ public TestRunDirectories(string rootDirectory) RootDeploymentDirectory = rootDirectory; } + [MemberNotNull(nameof(InDirectory), nameof(OutDirectory), nameof(InMachineNameDirectory))] + private void OnRootDeploymentDirectoryUpdated() + { + InDirectory = Path.Combine(RootDeploymentDirectory, DeploymentInDirectorySuffix); + OutDirectory = Path.Combine(RootDeploymentDirectory, DeploymentOutDirectorySuffix); + InMachineNameDirectory = Path.Combine(InDirectory, Environment.MachineName); + } + /// /// Gets or sets the root deployment directory. /// - public string RootDeploymentDirectory { get; set; } + public string RootDeploymentDirectory + { + get => field; + // TODO: Remove the setter as a breaking change and simplify the code. + [MemberNotNull(nameof(InDirectory), nameof(OutDirectory), nameof(InMachineNameDirectory))] + set + { + field = value; + OnRootDeploymentDirectoryUpdated(); + } + } /// /// Gets the In directory. /// - public string InDirectory - => Path.Combine(RootDeploymentDirectory, DeploymentInDirectorySuffix); + public string InDirectory { get; private set; } /// /// Gets the Out directory. /// - public string OutDirectory - => Path.Combine(RootDeploymentDirectory, DeploymentOutDirectorySuffix); + public string OutDirectory { get; private set; } /// /// Gets In\MachineName directory. /// - public string InMachineNameDirectory - => Path.Combine(Path.Combine(RootDeploymentDirectory, DeploymentInDirectorySuffix), Environment.MachineName); + public string InMachineNameDirectory { get; private set; } } #endif From 3e56b47c24976405c24bcb5675f27f5fb0f46993 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 9 Dec 2024 18:47:14 +1100 Subject: [PATCH 082/273] cleanup SourceGeneratedFileOperations (#4285) --- .../SourceGeneratedFileOperations.cs | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedFileOperations.cs b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedFileOperations.cs index 537cd989f4..96cfcf728f 100644 --- a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedFileOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedFileOperations.cs @@ -14,11 +14,10 @@ internal sealed class SourceGeneratedFileOperations : IFileOperations // Not great, but the inner class does some complicated stuff on checking if files exist, better would be to extract the functionality to a class that provides it to both these implementations. private readonly FileOperations _fileOperationsInner = new(skipSourceGeneratorCheck: true); -#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. - public SourceGeneratedReflectionDataProvider ReflectionDataProvider { get; set; } -#pragma warning restore CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider adding the 'required' modifier or declaring as nullable. + // null is allowed here because the ReflectionDataProvider is set by the source generator. + public SourceGeneratedReflectionDataProvider ReflectionDataProvider { get; set; } = null!; - public object? CreateNavigationSession(string source) => + public object CreateNavigationSession(string source) => // locations are in static metadata, nothing to do here. // But don't return null so the consumer thinks we are doing something. new(); @@ -28,18 +27,18 @@ public void DisposeNavigationSession(object? navigationSession) // locations are in static metadata, nothing to do here. } - public bool DoesFileExist(string assemblyFileName) => ((IFileOperations)_fileOperationsInner).DoesFileExist(assemblyFileName); + public bool DoesFileExist(string assemblyFileName) => _fileOperationsInner.DoesFileExist(assemblyFileName); - public string GetFullFilePath(string assemblyFileName) => ((IFileOperations)_fileOperationsInner).GetFullFilePath(assemblyFileName); + public string GetFullFilePath(string assemblyFileName) => _fileOperationsInner.GetFullFilePath(assemblyFileName); public void GetNavigationData(object navigationSession, string className, string methodName, out int minLineNumber, out string? fileName) - => ReflectionDataProvider!.GetNavigationData(className, methodName, out minLineNumber, out fileName); + => ReflectionDataProvider.GetNavigationData(className, methodName, out minLineNumber, out fileName); - public string? GetAssemblyPath(Assembly assembly) + public string GetAssemblyPath(Assembly assembly) => throw new NotSupportedException("Only tests within the same assembly are allowed in source gen mode"); public Assembly LoadAssembly(string assemblyName, bool isReflectionOnly) => isReflectionOnly ? throw new InvalidOperationException("Reflection only mode is not allowed") - : ReflectionDataProvider!.GetAssembly(assemblyName); + : ReflectionDataProvider.GetAssembly(assemblyName); } #endif From aa671a81becf7cdbdcb8294a151a09a74f1dd52b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 9 Dec 2024 18:56:59 +1100 Subject: [PATCH 083/273] remove some un-used parameters (#4283) --- samples/Playground/Program.cs | 2 +- .../ServerMode/TestingPlatformClientFactory.cs | 4 ++-- .../Discovery/AssemblyEnumerator.cs | 13 ++++++------- .../CommandLine/CommandLineHandler.cs | 7 +++---- .../ServerMode/JsonRpc/SerializerUtilities.cs | 6 +++--- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/samples/Playground/Program.cs b/samples/Playground/Program.cs index c49a0d0999..dfa263bd6e 100644 --- a/samples/Playground/Program.cs +++ b/samples/Playground/Program.cs @@ -61,7 +61,7 @@ public static async Task Main(string[] args) }); await discoveryResponse.WaitCompletionAsync(); - ResponseListener runRequest = await client.RunTestsAsync(Guid.NewGuid(), testNodeUpdates.Select(x => x.Node).ToArray(), node => Task.CompletedTask); + ResponseListener runRequest = await client.RunTestsAsync(Guid.NewGuid(), testNodeUpdates.Select(x => x.Node).ToArray(), _ => Task.CompletedTask); await runRequest.WaitCompletionAsync(); await client.ExitAsync(); diff --git a/samples/Playground/ServerMode/TestingPlatformClientFactory.cs b/samples/Playground/ServerMode/TestingPlatformClientFactory.cs index f4da060cd4..2167bdefcd 100644 --- a/samples/Playground/ServerMode/TestingPlatformClientFactory.cs +++ b/samples/Playground/ServerMode/TestingPlatformClientFactory.cs @@ -50,7 +50,7 @@ public static async Task StartAsServerAndConnectToTheClie { OnStandardOutput = (_, output) => builder.AppendLine(CultureInfo.InvariantCulture, $"OnStandardOutput:\n{output}"), OnErrorOutput = (_, output) => builder.AppendLine(CultureInfo.InvariantCulture, $"OnErrorOutput:\n{output}"), - OnExit = (processHandle, exitCode) => builder.AppendLine(CultureInfo.InvariantCulture, $"OnExit: exit code '{exitCode}'"), + OnExit = (_, exitCode) => builder.AppendLine(CultureInfo.InvariantCulture, $"OnExit: exit code '{exitCode}'"), Arguments = $"--server --client-host localhost --client-port {((IPEndPoint)tcpListener.LocalEndpoint).Port}", // Arguments = $"--server --client-host localhost --client-port {((IPEndPoint)tcpListener.LocalEndpoint).Port} --diagnostic --diagnostic-verbosity trace", @@ -173,7 +173,7 @@ public static IProcessHandle Start(ProcessConfiguration config, bool cleanDefaul if (config.OnExit != null) { - process.Exited += (s, e) => config.OnExit.Invoke(processHandle, process.ExitCode); + process.Exited += (_, _) => config.OnExit.Invoke(processHandle, process.ExitCode); } if (config.OnStandardOutput != null) diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs index 7ba81401ee..5a1ea2adae 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs @@ -311,7 +311,6 @@ private static void AddFixtureTests(TestMethodInfo testMethodInfo, List PrintOptionsAsync(IEnumerable optionProviders, int leftPaddingDepth, - bool builtInOnly = false) + async Task PrintOptionsAsync(IEnumerable optionProviders, bool builtInOnly = false) { CommandLineOption[] options = optionProviders @@ -292,11 +291,11 @@ async Task PrintApplicationUsageAsync(string applicationName) .ToArray(); // By default, only system options are built-in but some extensions (e.g. retry) are considered as built-in too, // so we need to union the 2 collections before printing the options. - await PrintOptionsAsync(SystemCommandLineOptionsProviders.Union(nonToolsExtensionProviders), 1, builtInOnly: true); + await PrintOptionsAsync(SystemCommandLineOptionsProviders.Union(nonToolsExtensionProviders), builtInOnly: true); await outputDevice.DisplayAsync(this, EmptyText); await outputDevice.DisplayAsync(this, new TextOutputDeviceData(PlatformResources.HelpExtensionOptions)); - if (!await PrintOptionsAsync(nonToolsExtensionProviders, 1)) + if (!await PrintOptionsAsync(nonToolsExtensionProviders)) { await outputDevice.DisplayAsync(this, new TextOutputDeviceData(PlatformResources.HelpNoExtensionRegistered)); } diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs index 045d23d934..e99de710ee 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs @@ -26,7 +26,7 @@ static SerializerUtilities() Serializers = []; Deserializers = []; - Serializers[typeof(object)] = new ObjectSerializer(o => new Dictionary()); + Serializers[typeof(object)] = new ObjectSerializer(_ => new Dictionary()); Serializers[typeof(KeyValuePair)] = new ObjectSerializer>(o => { Dictionary values = new() @@ -138,7 +138,7 @@ static SerializerUtilities() [JsonRpcStrings.Description] = res.Description, }); - Serializers[typeof(DiscoverResponseArgs)] = new ObjectSerializer(res => new Dictionary { }); + Serializers[typeof(DiscoverResponseArgs)] = new ObjectSerializer(_ => new Dictionary()); Serializers[typeof(RunResponseArgs)] = new ObjectSerializer(res => new Dictionary { @@ -669,7 +669,7 @@ static SerializerUtilities() return new CancelRequestArgs(id); }); - Deserializers[typeof(ExitRequestArgs)] = new ObjectDeserializer(properties => new ExitRequestArgs()); + Deserializers[typeof(ExitRequestArgs)] = new ObjectDeserializer(_ => new ExitRequestArgs()); // Deserialize an error Deserializers[typeof(ErrorMessage)] = new ObjectDeserializer(properties => From e871a5ea9bd415d4522ed90adecec592e2049255 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 9 Dec 2024 18:57:33 +1100 Subject: [PATCH 084/273] remove redundant ascending (#4287) --- .../Helpers/DictionaryHelperTests.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/DictionaryHelperTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/DictionaryHelperTests.cs index 6e7db6c92e..c1ae684171 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/DictionaryHelperTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/DictionaryHelperTests.cs @@ -35,8 +35,8 @@ public void ConcatenatingDictionariesReturnsSourceSideWhenOverwriteIsNullOrEmpty IDictionary actual = source.ConcatWithOverwrites(overwrite, nameof(source), nameof(overwrite)); - IOrderedEnumerable> sortedActual = from entry in actual orderby entry.Key ascending select entry; - IOrderedEnumerable> sortedSource = from entry in source orderby entry.Key ascending select entry; + IOrderedEnumerable> sortedActual = from entry in actual orderby entry.Key select entry; + IOrderedEnumerable> sortedSource = from entry in source orderby entry.Key select entry; Verify(sortedActual.SequenceEqual(sortedSource)); } @@ -52,8 +52,8 @@ public void ConcatenatingDictionariesReturnsOverwriteSideWhenSourceIsNullOrEmpty IDictionary actual = source.ConcatWithOverwrites(overwrite, nameof(source), nameof(overwrite)); - IOrderedEnumerable> sortedActual = from entry in actual orderby entry.Key ascending select entry; - IOrderedEnumerable> sortedOverwrite = from entry in overwrite orderby entry.Key ascending select entry; + IOrderedEnumerable> sortedActual = from entry in actual orderby entry.Key select entry; + IOrderedEnumerable> sortedOverwrite = from entry in overwrite orderby entry.Key select entry; Verify(sortedActual.SequenceEqual(sortedOverwrite)); } @@ -84,8 +84,8 @@ public void ConcatenatingDictionariesShouldMergeThemAndTakeDuplicateKeysFromOver ["bbb"] = "overwrite", }; - IOrderedEnumerable> sortedActual = from entry in actual orderby entry.Key ascending select entry; - IOrderedEnumerable> sortedExpected = from entry in expected orderby entry.Key ascending select entry; + IOrderedEnumerable> sortedActual = from entry in actual orderby entry.Key select entry; + IOrderedEnumerable> sortedExpected = from entry in expected orderby entry.Key select entry; Verify(sortedActual.SequenceEqual(sortedExpected)); } } From 6b1017ddc9fe319c22abd9b06693b496cab2189d Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 9 Dec 2024 19:01:34 +1100 Subject: [PATCH 085/273] remove param values where same as default (#4286) --- .../Hosts/TestHostBuilder.cs | 4 ++-- .../Services/CurrentTestApplicationModuleInfo.cs | 2 +- .../Extensions/VerifyE2E.cs | 4 ++-- .../DiagnosticTests.cs | 2 +- .../DiscoverInternalsProject/UnitTest1.cs | 2 +- .../DynamicDataTestProject/DynamicDataTests.cs | 14 ++++++-------- .../DynamicDataAttributeTests.cs | 6 +++--- .../Helpers/DictionaryHelperTests.cs | 8 ++++---- .../Logging/FileLoggerTests.cs | 2 +- 9 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs index 2bee5296da..9b19eea139 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs @@ -383,7 +383,7 @@ await LogTestHostCreatedAsync( // Check if we're in the test host or we should check test controllers extensions // Environment variable check should not be needed but in case we will rollback to use only env var we will need it. if ((!testHostControllerInfo.HasTestHostController || - systemEnvironment.GetEnvironmentVariable($"{EnvironmentVariableConstants.TESTINGPLATFORM_TESTHOSTCONTROLLER_SKIPEXTENSION}_{testHostControllerInfo.GetTestHostControllerPID(true)}") != "1") + systemEnvironment.GetEnvironmentVariable($"{EnvironmentVariableConstants.TESTINGPLATFORM_TESTHOSTCONTROLLER_SKIPEXTENSION}_{testHostControllerInfo.GetTestHostControllerPID()}") != "1") && !commandLineHandler.IsOptionSet(PlatformCommandLineProvider.DiscoverTestsOptionKey)) { PassiveNode? passiveNode = null; @@ -537,7 +537,7 @@ await LogTestHostCreatedAsync( return null; } - string pipeEnvironmentVariable = $"{EnvironmentVariableConstants.TESTINGPLATFORM_TESTHOSTCONTROLLER_PIPENAME}_{testHostControllerInfo.GetTestHostControllerPID(true)}"; + string pipeEnvironmentVariable = $"{EnvironmentVariableConstants.TESTINGPLATFORM_TESTHOSTCONTROLLER_PIPENAME}_{testHostControllerInfo.GetTestHostControllerPID()}"; string pipeName = environment.GetEnvironmentVariable(pipeEnvironmentVariable) ?? throw new InvalidOperationException($"Unexpected null pipe name from environment variable '{EnvironmentVariableConstants.TESTINGPLATFORM_TESTHOSTCONTROLLER_PIPENAME}'"); // RemoveVariable the environment variable so that it doesn't get passed to the eventually children processes diff --git a/src/Platform/Microsoft.Testing.Platform/Services/CurrentTestApplicationModuleInfo.cs b/src/Platform/Microsoft.Testing.Platform/Services/CurrentTestApplicationModuleInfo.cs index 5053c18b19..15c7d4a418 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/CurrentTestApplicationModuleInfo.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/CurrentTestApplicationModuleInfo.cs @@ -22,7 +22,7 @@ public bool IsCurrentTestApplicationHostDotnetMuxer { get { - string? processPath = GetProcessPath(_environment, _process, false); + string? processPath = GetProcessPath(_environment, _process); return processPath is not null && Path.GetFileNameWithoutExtension(processPath) == "dotnet"; } diff --git a/test/IntegrationTests/MSTest.IntegrationTests/Extensions/VerifyE2E.cs b/test/IntegrationTests/MSTest.IntegrationTests/Extensions/VerifyE2E.cs index 924ca20614..9d69238a49 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/Extensions/VerifyE2E.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/Extensions/VerifyE2E.cs @@ -41,13 +41,13 @@ public static void TestsFailed(IEnumerable actual, params string[] e => ContainsExpectedTestsWithOutcome(actual, TestOutcome.Failed, expectedTests, true); public static void ContainsTestsPassed(IEnumerable actual, IEnumerable testCases, IEnumerable expectedTests, MSTestSettings settings = null) - => ContainsExpectedTestsWithOutcome(actual, TestOutcome.Passed, expectedTests, false); + => ContainsExpectedTestsWithOutcome(actual, TestOutcome.Passed, expectedTests); public static void ContainsTestsPassed(IEnumerable actual, params string[] expectedTests) => ContainsExpectedTestsWithOutcome(actual, TestOutcome.Passed, expectedTests); public static void ContainsTestsFailed(IEnumerable actual, IEnumerable testCases, IEnumerable expectedTests, MSTestSettings settings = null) - => ContainsExpectedTestsWithOutcome(actual, TestOutcome.Failed, expectedTests, false); + => ContainsExpectedTestsWithOutcome(actual, TestOutcome.Failed, expectedTests); public static void ContainsTestsFailed(IEnumerable actual, params string[] expectedTests) => ContainsExpectedTestsWithOutcome(actual, TestOutcome.Failed, expectedTests); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs index da4f899172..65eaeb6028 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs @@ -133,7 +133,7 @@ public async Task Diag_EnableWithEnvironmentVariables_Verbosity_Succeeded(string { EnvironmentVariableConstants.TESTINGPLATFORM_DIAGNOSTIC_VERBOSITY, "Trace" }, }); - await AssertDiagnosticReportWasGeneratedAsync(testHostResult, diagPathPattern, "Trace"); + await AssertDiagnosticReportWasGeneratedAsync(testHostResult, diagPathPattern); } [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] diff --git a/test/IntegrationTests/TestAssets/DiscoverInternalsProject/UnitTest1.cs b/test/IntegrationTests/TestAssets/DiscoverInternalsProject/UnitTest1.cs index aa2f02e272..bef73871c7 100644 --- a/test/IntegrationTests/TestAssets/DiscoverInternalsProject/UnitTest1.cs +++ b/test/IntegrationTests/TestAssets/DiscoverInternalsProject/UnitTest1.cs @@ -56,7 +56,7 @@ internal sealed class SerializableInternalType; internal class DynamicDataTest { [DataTestMethod] - [DynamicData(nameof(DynamicData), DynamicDataSourceType.Property)] + [DynamicData(nameof(DynamicData))] internal void DynamicDataTestMethod(SerializableInternalType serializableInternalType) { } diff --git a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs index f52f036ab7..bc467c3057 100644 --- a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs +++ b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs @@ -22,7 +22,7 @@ public class DynamicDataTests public void DynamicDataTest_SourceMethod(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); [DataTestMethod] - [DynamicData(nameof(ParseUserData), DynamicDataSourceType.Property)] + [DynamicData(nameof(ParseUserData))] public void DynamicDataTest_SourceProperty(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); [DataTestMethod] @@ -31,8 +31,7 @@ public class DynamicDataTests public void DynamicDataTest_SourceMethod_CustomDisplayName(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); [DataTestMethod] - [DynamicData(nameof(ParseUserData), DynamicDataSourceType.Property, - DynamicDataDisplayName = nameof(GetCustomDynamicDataDisplayName))] + [DynamicData(nameof(ParseUserData), DynamicDataDisplayName = nameof(GetCustomDynamicDataDisplayName))] public void DynamicDataTest_SourceProperty_CustomDisplayName(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); [DataTestMethod] @@ -41,8 +40,7 @@ public class DynamicDataTests public void DynamicDataTest_SourceMethod_CustomDisplayNameOtherType(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); // todo [DataTestMethod] - [DynamicData(nameof(ParseUserData), DynamicDataSourceType.Property, - DynamicDataDisplayName = nameof(DataProvider.GetUserDynamicDataDisplayName), DynamicDataDisplayNameDeclaringType = typeof(DataProvider))] + [DynamicData(nameof(ParseUserData), DynamicDataDisplayName = nameof(DataProvider.GetUserDynamicDataDisplayName), DynamicDataDisplayNameDeclaringType = typeof(DataProvider))] public void DynamicDataTest_SourceProperty_CustomDisplayNameOtherType(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); // todo [DataTestMethod] @@ -50,7 +48,7 @@ public class DynamicDataTests public void DynamicDataTest_SourceMethodOtherType(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); [DataTestMethod] - [DynamicData(nameof(DataProvider.UserDataAndExceptedParsedUser), typeof(DataProvider), DynamicDataSourceType.Property)] + [DynamicData(nameof(DataProvider.UserDataAndExceptedParsedUser), typeof(DataProvider))] public void DynamicDataTest_SourcePropertyOtherType(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); [DataTestMethod] @@ -59,7 +57,7 @@ public class DynamicDataTests public void DynamicDataTest_SourceMethodOtherType_CustomDisplayName(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); [DataTestMethod] - [DynamicData(nameof(DataProvider.UserDataAndExceptedParsedUser), typeof(DataProvider), DynamicDataSourceType.Property, + [DynamicData(nameof(DataProvider.UserDataAndExceptedParsedUser), typeof(DataProvider), DynamicDataDisplayName = nameof(GetCustomDynamicDataDisplayName))] public void DynamicDataTest_SourcePropertyOtherType_CustomDisplayName(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); @@ -69,7 +67,7 @@ public class DynamicDataTests public void DynamicDataTest_SourceMethodOtherType_CustomDisplayNameOtherType(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); [DataTestMethod] - [DynamicData(nameof(DataProvider.UserDataAndExceptedParsedUser), typeof(DataProvider), DynamicDataSourceType.Property, + [DynamicData(nameof(DataProvider.UserDataAndExceptedParsedUser), typeof(DataProvider), DynamicDataDisplayName = nameof(DataProvider.GetUserDynamicDataDisplayName), DynamicDataDisplayNameDeclaringType = typeof(DataProvider))] public void DynamicDataTest_SourcePropertyOtherType_CustomDisplayNameOtherType(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs index 60162cf013..cad1caf3e4 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs @@ -244,7 +244,7 @@ public void GetDisplayNameForMultipleArraysOfArraysOfMultipleItems() public void DynamicDataSource_WithTuple_Works() { MethodInfo testMethodInfo = new TestClassTupleData().GetType().GetTypeInfo().GetDeclaredMethod(nameof(TestClassTupleData.DynamicDataTestWithTuple)); - var dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.DataWithTuple), typeof(TestClassTupleData), DynamicDataSourceType.Property); + var dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.DataWithTuple), typeof(TestClassTupleData)); dynamicDataAttribute.GetData(testMethodInfo); dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.GetDataWithTuple), typeof(TestClassTupleData), DynamicDataSourceType.Method); @@ -254,7 +254,7 @@ public void DynamicDataSource_WithTuple_Works() public void DynamicDataSource_WithValueTuple_Works() { MethodInfo testMethodInfo = new TestClassTupleData().GetType().GetTypeInfo().GetDeclaredMethod(nameof(TestClassTupleData.DynamicDataTestWithTuple)); - var dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.DataWithValueTuple), typeof(TestClassTupleData), DynamicDataSourceType.Property); + var dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.DataWithValueTuple), typeof(TestClassTupleData)); dynamicDataAttribute.GetData(testMethodInfo); dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.GetDataWithValueTuple), typeof(TestClassTupleData), DynamicDataSourceType.Method); @@ -264,7 +264,7 @@ public void DynamicDataSource_WithValueTuple_Works() public void DynamicDataSource_WithValueTupleWithTupleSyntax_Works() { MethodInfo testMethodInfo = new TestClassTupleData().GetType().GetTypeInfo().GetDeclaredMethod(nameof(TestClassTupleData.DynamicDataTestWithTuple)); - var dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.DataWithValueTupleWithTupleSyntax), typeof(TestClassTupleData), DynamicDataSourceType.Property); + var dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.DataWithValueTupleWithTupleSyntax), typeof(TestClassTupleData)); dynamicDataAttribute.GetData(testMethodInfo); dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.GetDataWithValueTupleWithTupleSyntax), typeof(TestClassTupleData), DynamicDataSourceType.Method); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/DictionaryHelperTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/DictionaryHelperTests.cs index c1ae684171..0872333d45 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/DictionaryHelperTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/DictionaryHelperTests.cs @@ -15,7 +15,7 @@ public void ConcatenatingDictionariesReturnsEmptyDictionaryWhenBothSidesAreNullO var overwrite = new Dictionary(); - IDictionary actual = source.ConcatWithOverwrites(overwrite, nameof(source), nameof(overwrite)); + IDictionary actual = source.ConcatWithOverwrites(overwrite); var expected = new Dictionary(); actual.ToList().Sort(); @@ -33,7 +33,7 @@ public void ConcatenatingDictionariesReturnsSourceSideWhenOverwriteIsNullOrEmpty Dictionary overwrite = null; - IDictionary actual = source.ConcatWithOverwrites(overwrite, nameof(source), nameof(overwrite)); + IDictionary actual = source.ConcatWithOverwrites(overwrite); IOrderedEnumerable> sortedActual = from entry in actual orderby entry.Key select entry; IOrderedEnumerable> sortedSource = from entry in source orderby entry.Key select entry; @@ -50,7 +50,7 @@ public void ConcatenatingDictionariesReturnsOverwriteSideWhenSourceIsNullOrEmpty ["bbb"] = "overwrite", }; - IDictionary actual = source.ConcatWithOverwrites(overwrite, nameof(source), nameof(overwrite)); + IDictionary actual = source.ConcatWithOverwrites(overwrite); IOrderedEnumerable> sortedActual = from entry in actual orderby entry.Key select entry; IOrderedEnumerable> sortedOverwrite = from entry in overwrite orderby entry.Key select entry; @@ -71,7 +71,7 @@ public void ConcatenatingDictionariesShouldMergeThemAndTakeDuplicateKeysFromOver ["ccc"] = "overwrite", }; - IDictionary actual = source.ConcatWithOverwrites(overwrite, nameof(source), nameof(overwrite)); + IDictionary actual = source.ConcatWithOverwrites(overwrite); var expected = new Dictionary { // this is only present in source, take it diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs index b26ea68c65..e770711541 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs @@ -50,7 +50,7 @@ public void Write_IfMalformedUTF8_ShouldNotCrash() { using TempDirectory tempDirectory = new(nameof(Write_IfMalformedUTF8_ShouldNotCrash)); using FileLogger fileLogger = new( - new FileLoggerOptions(tempDirectory.Path, "Test", fileName: null, true), + new FileLoggerOptions(tempDirectory.Path, "Test", fileName: null), LogLevel.Trace, new SystemClock(), new SystemTask(), From fcee02ac317636f9019b32c22772fdd5968c2999 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 9 Dec 2024 09:06:03 +0100 Subject: [PATCH 086/273] [Performance] Ensure ReflectionOperations return `Attribute[]` when possible (#4271) --- .../Services/ReflectionOperations.cs | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs index 2bb0157c76..8663ff8570 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs @@ -1,6 +1,9 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +#if !NETFRAMEWORK +using System.Diagnostics; +#endif using System.Diagnostics.CodeAnalysis; using System.Reflection; @@ -28,11 +31,20 @@ public class ReflectionOperations : IReflectionOperations /// True to inspect the ancestors of element; otherwise, false. /// The list of attributes on the member. Empty list if none found. [return: NotNullIfNotNull(nameof(memberInfo))] - public object[]? GetCustomAttributes(MemberInfo memberInfo, bool inherit) => + public object[]? GetCustomAttributes(MemberInfo memberInfo, bool inherit) #if NETFRAMEWORK - ReflectionUtility.GetCustomAttributes(memberInfo, inherit).ToArray(); + => ReflectionUtility.GetCustomAttributes(memberInfo, inherit).ToArray(); #else - memberInfo.GetCustomAttributes(inherit); + { + object[] attributes = memberInfo.GetCustomAttributes(typeof(Attribute), inherit); + + // Ensures that when the return of this method is used here: + // https://github.com/microsoft/testfx/blob/e101a9d48773cc935c7b536d25d378d9a3211fee/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs#L461 + // then we are already Attribute[] to avoid LINQ Cast and extra array allocation. + // This assert is solely for performance. Nothing "functional" will go wrong if the assert failed. + Debug.Assert(attributes is Attribute[], $"Expected Attribute[], found '{attributes.GetType()}'."); + return attributes; + } #endif /// @@ -60,6 +72,6 @@ public object[] GetCustomAttributes(Assembly assembly, Type type) => #if NETFRAMEWORK ReflectionUtility.GetCustomAttributes(assembly, type).ToArray(); #else - assembly.GetCustomAttributes(type).ToArray(); + assembly.GetCustomAttributes(type, inherit: true); #endif } From 881b5e65ac64bc253ee38660cc3c69eb9819bc92 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 9 Dec 2024 20:33:37 +1100 Subject: [PATCH 087/273] leverage out null pattern in IsValidDeploymentItem (#4048) --- .../Utilities/DeploymentItemUtility.cs | 4 ++-- .../Utilities/ns13DeploymentItemUtilityTests.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs index 867f593dae..07479ffe20 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs @@ -79,7 +79,7 @@ internal IList GetClassLevelDeploymentItems(Type type, ICollecti /// The warning message if it is an invalid deployment item. /// Returns true if it is a valid deployment item. [SuppressMessage("Microsoft.Design", "CA1021:AvoidOutParameters", MessageId = "2#", Justification = "Internal method.")] - internal static bool IsValidDeploymentItem([NotNullWhen(true)] string? sourcePath, [NotNullWhen(true)] string? relativeOutputDirectory, out string warning) + internal static bool IsValidDeploymentItem([NotNullWhen(true)] string? sourcePath, [NotNullWhen(true)] string? relativeOutputDirectory, [NotNullWhen(false)] out string? warning) { if (StringEx.IsNullOrEmpty(sourcePath)) { @@ -105,7 +105,7 @@ internal static bool IsValidDeploymentItem([NotNullWhen(true)] string? sourcePat return false; } - warning = string.Empty; + warning = null; return true; } diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13DeploymentItemUtilityTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13DeploymentItemUtilityTests.cs index 5f64b0a4ef..dea08157df 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13DeploymentItemUtilityTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13DeploymentItemUtilityTests.cs @@ -389,7 +389,7 @@ public void IsValidDeploymentItemShouldReturnTrueForAValidDeploymentItem() { Verify(DeploymentItemUtility.IsValidDeploymentItem(_defaultDeploymentItemPath, _defaultDeploymentItemOutputDirectory, out string warning)); - Verify(string.Empty.Equals(warning, StringComparison.Ordinal)); + Verify(warning is null); } #endregion From 7b2656e29808427246b795515b8bac9109a83977 Mon Sep 17 00:00:00 2001 From: Artur Spychaj Date: Mon, 9 Dec 2024 21:21:32 +0100 Subject: [PATCH 088/273] Show running tests (#4221) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jakub Jareš Co-authored-by: Amaury Levé --- .../OutputDevice/Terminal/AnsiTerminal.cs | 17 +- .../Terminal/AnsiTerminalTestProgressFrame.cs | 251 +++++++++++++----- .../HumanReadableDurationFormatter.cs | 27 +- .../OutputDevice/Terminal/NonAnsiTerminal.cs | 3 +- .../Terminal/TerminalTestReporter.cs | 52 +++- .../Terminal/TerminalTestReporterOptions.cs | 5 + .../OutputDevice/Terminal/TestDetailState.cs | 37 +++ .../Terminal/TestNodeResultsState.cs | 66 +++++ .../Terminal/TestProgressState.cs | 9 +- .../TestProgressStateAwareTerminal.cs | 8 +- .../OutputDevice/TerminalOutputDevice.cs | 15 +- .../Resources/PlatformResources.resx | 6 + .../Resources/xlf/PlatformResources.cs.xlf | 10 + .../Resources/xlf/PlatformResources.de.xlf | 10 + .../Resources/xlf/PlatformResources.es.xlf | 10 + .../Resources/xlf/PlatformResources.fr.xlf | 10 + .../Resources/xlf/PlatformResources.it.xlf | 10 + .../Resources/xlf/PlatformResources.ja.xlf | 10 + .../Resources/xlf/PlatformResources.ko.xlf | 10 + .../Resources/xlf/PlatformResources.pl.xlf | 10 + .../Resources/xlf/PlatformResources.pt-BR.xlf | 10 + .../Resources/xlf/PlatformResources.ru.xlf | 10 + .../Resources/xlf/PlatformResources.tr.xlf | 10 + .../xlf/PlatformResources.zh-Hans.xlf | 10 + .../xlf/PlatformResources.zh-Hant.xlf | 10 + .../Terminal/TerminalTestReporterTests.cs | 142 +++++++++- 26 files changed, 659 insertions(+), 109 deletions(-) create mode 100644 src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestDetailState.cs create mode 100644 src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs index 9c9341357c..21a664fbb4 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs @@ -45,7 +45,7 @@ internal sealed class AnsiTerminal : ITerminal private readonly bool _useBusyIndicator; private readonly StringBuilder _stringBuilder = new(); private bool _isBatching; - private AnsiTerminalTestProgressFrame _currentFrame = new(Array.Empty(), 0, 0); + private AnsiTerminalTestProgressFrame _currentFrame = new(0, 0); public AnsiTerminal(IConsole console, string? baseDirectory) { @@ -274,27 +274,20 @@ public void SetCursorHorizontal(int position) /// public void EraseProgress() { - if (_currentFrame.ProgressCount == 0) + if (_currentFrame.RenderedLines == null || _currentFrame.RenderedLines.Count == 0) { return; } - AppendLine($"{AnsiCodes.CSI}{_currentFrame.ProgressCount + 2}{AnsiCodes.MoveUpToLineStart}"); + AppendLine($"{AnsiCodes.CSI}{_currentFrame.RenderedLines.Count + 2}{AnsiCodes.MoveUpToLineStart}"); Append($"{AnsiCodes.CSI}{AnsiCodes.EraseInDisplay}"); _currentFrame.Clear(); } public void RenderProgress(TestProgressState?[] progress) { - AnsiTerminalTestProgressFrame newFrame = new(progress, Width, Height); - - // Do not render delta but clear everything if Terminal width or height have changed. - if (newFrame.Width != _currentFrame.Width || newFrame.Height != _currentFrame.Height) - { - EraseProgress(); - } - - newFrame.Render(_currentFrame, this); + AnsiTerminalTestProgressFrame newFrame = new(Width, Height); + newFrame.Render(_currentFrame, progress, terminal: this); _currentFrame = newFrame; } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminalTestProgressFrame.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminalTestProgressFrame.cs index c2b3d7da46..35cd1f7e38 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminalTestProgressFrame.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminalTestProgressFrame.cs @@ -12,43 +12,29 @@ internal sealed class AnsiTerminalTestProgressFrame { private const int MaxColumn = 250; - private readonly (TestProgressState TestProgressState, int DurationLength)[] _progressItems; - public int Width { get; } public int Height { get; } - public int ProgressCount { get; private set; } + public List? RenderedLines { get; set; } - public AnsiTerminalTestProgressFrame(TestProgressState?[] nodes, int width, int height) + public AnsiTerminalTestProgressFrame(int width, int height) { Width = Math.Min(width, MaxColumn); Height = height; - - _progressItems = new (TestProgressState, int)[nodes.Length]; - - foreach (TestProgressState? status in nodes) - { - if (status is not null) - { - _progressItems[ProgressCount++].TestProgressState = status; - } - } } - public void AppendTestWorkerProgress(int i, AnsiTerminal terminal) + public void AppendTestWorkerProgress(TestProgressState progress, RenderedProgressItem currentLine, AnsiTerminal terminal) { - TestProgressState p = _progressItems[i].TestProgressState; - - string durationString = HumanReadableDurationFormatter.Render(p.Stopwatch.Elapsed); + string durationString = HumanReadableDurationFormatter.Render(progress.Stopwatch.Elapsed); - _progressItems[i].DurationLength = durationString.Length; + currentLine.RenderedDurationLength = durationString.Length; int nonReservedWidth = Width - (durationString.Length + 2); - int passed = p.PassedTests; - int failed = p.FailedTests; - int skipped = p.SkippedTests; + int passed = progress.PassedTests; + int failed = progress.FailedTests; + int skipped = progress.SkippedTests; int charsTaken = 0; terminal.Append('['); @@ -85,28 +71,27 @@ public void AppendTestWorkerProgress(int i, AnsiTerminal terminal) terminal.Append(']'); charsTaken++; - // -5 because we want to output at least 1 char from the name, and ' ...' followed by duration terminal.Append(' '); charsTaken++; - AppendToWidth(terminal, p.AssemblyName, nonReservedWidth, ref charsTaken); + AppendToWidth(terminal, progress.AssemblyName, nonReservedWidth, ref charsTaken); - if (charsTaken < nonReservedWidth && (p.TargetFramework != null || p.Architecture != null)) + if (charsTaken < nonReservedWidth && (progress.TargetFramework != null || progress.Architecture != null)) { int lengthNeeded = 0; lengthNeeded++; // for '(' - if (p.TargetFramework != null) + if (progress.TargetFramework != null) { - lengthNeeded += p.TargetFramework.Length; - if (p.Architecture != null) + lengthNeeded += progress.TargetFramework.Length; + if (progress.Architecture != null) { lengthNeeded++; // for '|' } } - if (p.Architecture != null) + if (progress.Architecture != null) { - lengthNeeded += p.Architecture.Length; + lengthNeeded += progress.Architecture.Length; } lengthNeeded++; // for ')' @@ -114,29 +99,41 @@ public void AppendTestWorkerProgress(int i, AnsiTerminal terminal) if ((charsTaken + lengthNeeded) < nonReservedWidth) { terminal.Append(" ("); - if (p.TargetFramework != null) + if (progress.TargetFramework != null) { - terminal.Append(p.TargetFramework); - if (p.Architecture != null) + terminal.Append(progress.TargetFramework); + if (progress.Architecture != null) { terminal.Append('|'); } } - if (p.Architecture != null) + if (progress.Architecture != null) { - terminal.Append(p.Architecture); + terminal.Append(progress.Architecture); } terminal.Append(')'); } } - if (!RoslynString.IsNullOrWhiteSpace(p.Detail)) - { - terminal.Append(" - "); - terminal.Append(p.Detail); - } + terminal.SetCursorHorizontal(Width - durationString.Length); + terminal.Append(durationString); + } + + public void AppendTestWorkerDetail(TestDetailState detail, RenderedProgressItem currentLine, AnsiTerminal terminal) + { + string durationString = HumanReadableDurationFormatter.Render(detail.Stopwatch?.Elapsed); + + currentLine.RenderedDurationLength = durationString.Length; + + int nonReservedWidth = Width - (durationString.Length + 2); + int charsTaken = 0; + + terminal.Append(" "); + charsTaken += 2; + + AppendToWidth(terminal, detail.Text, nonReservedWidth, ref charsTaken); terminal.SetCursorHorizontal(Width - durationString.Length); terminal.Append(durationString); @@ -166,60 +163,131 @@ private static void AppendToWidth(AnsiTerminal terminal, string text, int width, /// /// Render VT100 string to update from current to next frame. /// - public void Render(AnsiTerminalTestProgressFrame previousFrame, AnsiTerminal terminal) + public void Render(AnsiTerminalTestProgressFrame previousFrame, TestProgressState?[] progress, AnsiTerminal terminal) { - // Don't go up if we did not render progress in previous frame or we cleared it. - if (previousFrame.ProgressCount > 0) + // Clear everything if Terminal width or height have changed. + if (Width != previousFrame.Width || Height != previousFrame.Height) + { + terminal.EraseProgress(); + } + + // At the end of the terminal we're going to print the live progress. + // We re-render this progress by moving the cursor to the beginning of the previous progress + // and then overwriting the lines that have changed. + // The assumption we do here is that: + // - Each rendered line is a single line, i.e. a single detail cannot span multiple lines. + // - Each rendered detail can be tracked via a unique ID and version, so that we can + // quickly determine if the detail has changed since the last render. + + // Don't go up if we did not render any lines in previous frame or we already cleared them. + if (previousFrame.RenderedLines != null && previousFrame.RenderedLines.Count > 0) { // Move cursor back to 1st line of progress. - // +2 because we prepend 1 empty line before the progress - // and new line after the progress indicator. - terminal.MoveCursorUp(previousFrame.ProgressCount + 2); + // + 2 because we output and empty line right below. + terminal.MoveCursorUp(previousFrame.RenderedLines.Count + 2); } // When there is nothing to render, don't write empty lines, e.g. when we start the test run, and then we kick off build // in dotnet test, there is a long pause where we have no assemblies and no test results (yet). - if (ProgressCount > 0) + if (progress.Length > 0) { terminal.AppendLine(); } int i = 0; - for (; i < ProgressCount; i++) + RenderedLines = new List(progress.Length * 2); + List progresses = GenerateLinesToRender(progress); + + foreach (object item in progresses) { - // Optimize the rendering. When we have previous frame to compare with, we can decide to rewrite only part of the screen, - // rather than deleting whole line and have the line flicker. Most commonly this will rewrite just the time part of the line. - if (previousFrame.ProgressCount > i) + if (previousFrame.RenderedLines != null && previousFrame.RenderedLines.Count > i) { - if (previousFrame._progressItems[i].TestProgressState.LastUpdate != _progressItems[i].TestProgressState.LastUpdate) + if (item is TestProgressState progressItem) { - // Same everything except time. - string durationString = HumanReadableDurationFormatter.Render(_progressItems[i].TestProgressState.Stopwatch.Elapsed); + var currentLine = new RenderedProgressItem(progressItem.Id, progressItem.Version); + RenderedLines.Add(currentLine); - if (previousFrame._progressItems[i].DurationLength == durationString.Length) + // We have a line that was rendered previously, compare it and decide how to render. + RenderedProgressItem previouslyRenderedLine = previousFrame.RenderedLines[i]; + if (previouslyRenderedLine.ProgressId == progressItem.Id && false) { - terminal.SetCursorHorizontal(MaxColumn); - terminal.Append($"{AnsiCodes.SetCursorHorizontal(MaxColumn)}{AnsiCodes.MoveCursorBackward(durationString.Length)}{durationString}"); - _progressItems[i].DurationLength = durationString.Length; + // This is the same progress item and it was not updated since we rendered it, only update the timestamp if possible to avoid flicker. + string durationString = HumanReadableDurationFormatter.Render(progressItem.Stopwatch.Elapsed); + + if (previouslyRenderedLine.RenderedDurationLength == durationString.Length) + { + // Duration is the same length rewrite just it. + terminal.SetCursorHorizontal(MaxColumn); + terminal.Append($"{AnsiCodes.SetCursorHorizontal(MaxColumn)}{AnsiCodes.MoveCursorBackward(durationString.Length)}{durationString}"); + currentLine.RenderedDurationLength = durationString.Length; + } + else + { + // Duration is not the same length (it is longer because time moves only forward), we need to re-render the whole line + // to avoid writing the duration over the last portion of text: my.dll (1s) -> my.d (1m 1s) + terminal.Append($"{AnsiCodes.CSI}{AnsiCodes.EraseInLine}"); + AppendTestWorkerProgress(progressItem, currentLine, terminal); + } } else { - // Render full line. + // These lines are different or the line was updated. Render the whole line. terminal.Append($"{AnsiCodes.CSI}{AnsiCodes.EraseInLine}"); - AppendTestWorkerProgress(i, terminal); + AppendTestWorkerProgress(progressItem, currentLine, terminal); } } - else + + if (item is TestDetailState detailItem) { - // Render full line. - terminal.Append($"{AnsiCodes.CSI}{AnsiCodes.EraseInLine}"); - AppendTestWorkerProgress(i, terminal); + var currentLine = new RenderedProgressItem(detailItem.Id, detailItem.Version); + RenderedLines.Add(currentLine); + + // We have a line that was rendered previously, compare it and decide how to render. + RenderedProgressItem previouslyRenderedLine = previousFrame.RenderedLines[i]; + if (previouslyRenderedLine.ProgressId == detailItem.Id && previouslyRenderedLine.ProgressVersion == detailItem.Version) + { + // This is the same progress item and it was not updated since we rendered it, only update the timestamp if possible to avoid flicker. + string durationString = HumanReadableDurationFormatter.Render(detailItem.Stopwatch?.Elapsed); + + if (previouslyRenderedLine.RenderedDurationLength == durationString.Length) + { + // Duration is the same length rewrite just it. + terminal.SetCursorHorizontal(MaxColumn); + terminal.Append($"{AnsiCodes.SetCursorHorizontal(MaxColumn)}{AnsiCodes.MoveCursorBackward(durationString.Length)}{durationString}"); + currentLine.RenderedDurationLength = durationString.Length; + } + else + { + // Duration is not the same length (it is longer because time moves only forward), we need to re-render the whole line + // to avoid writing the duration over the last portion of text: my.dll (1s) -> my.d (1m 1s) + terminal.Append($"{AnsiCodes.CSI}{AnsiCodes.EraseInLine}"); + AppendTestWorkerDetail(detailItem, currentLine, terminal); + } + } + else + { + // These lines are different or the line was updated. Render the whole line. + terminal.Append($"{AnsiCodes.CSI}{AnsiCodes.EraseInLine}"); + AppendTestWorkerDetail(detailItem, currentLine, terminal); + } } } else { - // From now on we have to simply WriteLine - AppendTestWorkerProgress(i, terminal); + // We are rendering more lines than we rendered in previous frame + if (item is TestProgressState progressItem) + { + var currentLine = new RenderedProgressItem(progressItem.Id, progressItem.Version); + RenderedLines.Add(currentLine); + AppendTestWorkerProgress(progressItem, currentLine, terminal); + } + + if (item is TestDetailState detailItem) + { + var currentLine = new RenderedProgressItem(detailItem.Id, detailItem.Version); + RenderedLines.Add(currentLine); + AppendTestWorkerDetail(detailItem, currentLine, terminal); + } } // This makes the progress not stick to the last line on the command line, which is @@ -228,12 +296,57 @@ public void Render(AnsiTerminalTestProgressFrame previousFrame, AnsiTerminal ter terminal.AppendLine(); } - // clear no longer used lines - if (i < previousFrame.ProgressCount) + // We rendered more lines in previous frame. Clear them. + if (previousFrame.RenderedLines != null && i < previousFrame.RenderedLines.Count) { terminal.Append($"{AnsiCodes.CSI}{AnsiCodes.EraseInDisplay}"); } } - public void Clear() => ProgressCount = 0; + private List GenerateLinesToRender(TestProgressState?[] progress) + { + var linesToRender = new List(progress.Length); + + // Note: We want to render the list of active tests, but this can easily fill up the full screen. + // As such, we should balance the number of active tests shown per project. + // We do this by distributing the remaining lines for each projects. + TestProgressState[] progressItems = progress.OfType().ToArray(); + int linesToDistribute = (int)(Height * 0.7) - 1 - progressItems.Length; + var detailItems = new IEnumerable[progressItems.Length]; + IEnumerable sortedItemsIndices = Enumerable.Range(0, progressItems.Length).OrderBy(i => progressItems[i].TestNodeResultsState?.Count ?? 0); + + foreach (int sortedItemIndex in sortedItemsIndices) + { + detailItems[sortedItemIndex] = progressItems[sortedItemIndex].TestNodeResultsState?.GetRunningTasks( + linesToDistribute / progressItems.Length) + ?? Array.Empty(); + } + + for (int progressI = 0; progressI < progressItems.Length; progressI++) + { + linesToRender.Add(progressItems[progressI]); + linesToRender.AddRange(detailItems[progressI]); + } + + return linesToRender; + } + + public void Clear() => RenderedLines?.Clear(); + + internal sealed class RenderedProgressItem + { + public RenderedProgressItem(long id, long version) + { + ProgressId = id; + ProgressVersion = version; + } + + public long ProgressId { get; } + + public long ProgressVersion { get; } + + public int RenderedHeight { get; set; } + + public int RenderedDurationLength { get; set; } + } } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/HumanReadableDurationFormatter.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/HumanReadableDurationFormatter.cs index 6d07e8d56b..27aa9af5d1 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/HumanReadableDurationFormatter.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/HumanReadableDurationFormatter.cs @@ -55,8 +55,13 @@ public static void Append(ITerminal terminal, TimeSpan duration, bool wrapInPare private static string GetFormattedPart(int value, bool hasParentValue, string suffix, int paddingWitdh = 2) => $"{(hasParentValue ? " " : string.Empty)}{(hasParentValue ? value.ToString(CultureInfo.InvariantCulture).PadLeft(paddingWitdh, '0') : value.ToString(CultureInfo.InvariantCulture))}{suffix}"; - public static string Render(TimeSpan duration, bool wrapInParentheses = true, bool showMilliseconds = false) + public static string Render(TimeSpan? duration, bool wrapInParentheses = true, bool showMilliseconds = false) { + if (duration is null) + { + return string.Empty; + } + bool hasParentValue = false; var stringBuilder = new StringBuilder(); @@ -66,35 +71,35 @@ public static string Render(TimeSpan duration, bool wrapInParentheses = true, bo stringBuilder.Append('('); } - if (duration.Days > 0) + if (duration.Value.Days > 0) { - stringBuilder.Append(CultureInfo.CurrentCulture, $"{duration.Days}d"); + stringBuilder.Append(CultureInfo.CurrentCulture, $"{duration.Value.Days}d"); hasParentValue = true; } - if (duration.Hours > 0 || hasParentValue) + if (duration.Value.Hours > 0 || hasParentValue) { - stringBuilder.Append(GetFormattedPart(duration.Hours, hasParentValue, "h")); + stringBuilder.Append(GetFormattedPart(duration.Value.Hours, hasParentValue, "h")); hasParentValue = true; } - if (duration.Minutes > 0 || hasParentValue) + if (duration.Value.Minutes > 0 || hasParentValue) { - stringBuilder.Append(GetFormattedPart(duration.Minutes, hasParentValue, "m")); + stringBuilder.Append(GetFormattedPart(duration.Value.Minutes, hasParentValue, "m")); hasParentValue = true; } - if (duration.Seconds > 0 || hasParentValue || !showMilliseconds) + if (duration.Value.Seconds > 0 || hasParentValue || !showMilliseconds) { - stringBuilder.Append(GetFormattedPart(duration.Seconds, hasParentValue, "s")); + stringBuilder.Append(GetFormattedPart(duration.Value.Seconds, hasParentValue, "s")); hasParentValue = true; } if (showMilliseconds) { - if (duration.Milliseconds >= 0 || hasParentValue) + if (duration.Value.Milliseconds >= 0 || hasParentValue) { - stringBuilder.Append(GetFormattedPart(duration.Milliseconds, hasParentValue, "ms", paddingWitdh: 3)); + stringBuilder.Append(GetFormattedPart(duration.Value.Milliseconds, hasParentValue, "ms", paddingWitdh: 3)); } } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs index 8c1f545720..2da9ab982c 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs @@ -183,7 +183,8 @@ 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. - string? detail = !RoslynString.IsNullOrWhiteSpace(p.Detail) ? $"- {p.Detail}" : null; + TestDetailState? activeTest = p.TestNodeResultsState?.GetFirstRunningTask(); + string? detail = !RoslynString.IsNullOrWhiteSpace(activeTest?.Text) ? $"- {activeTest.Text}" : null; Append('['); SetColor(TerminalColor.DarkGreen); Append('+'); diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs index 0c8543d807..44b067a99c 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs @@ -31,6 +31,18 @@ internal sealed partial class TerminalTestReporter : IDisposable internal Func CreateStopwatch { get; set; } = SystemStopwatch.StartNew; + internal event EventHandler OnProgressStartUpdate + { + add => _terminalWithProgress.OnProgressStartUpdate += value; + remove => _terminalWithProgress.OnProgressStartUpdate -= value; + } + + internal event EventHandler OnProgressStopUpdate + { + add => _terminalWithProgress.OnProgressStopUpdate += value; + remove => _terminalWithProgress.OnProgressStopUpdate -= value; + } + private readonly ConcurrentDictionary _assemblies = new(); private readonly List _artifacts = new(); @@ -108,10 +120,12 @@ private static Regex GetFrameRegex() } #endif + private int _counter; + /// /// Initializes a new instance of the class with custom terminal and manual refresh for testing. /// - internal TerminalTestReporter(IConsole console, TerminalTestReporterOptions options) + public TerminalTestReporter(IConsole console, TerminalTestReporterOptions options) { _options = options; @@ -168,7 +182,7 @@ private TestProgressState GetOrAddAssemblyRun(string assembly, string? targetFra return _assemblies.GetOrAdd(key, _ => { IStopwatch sw = CreateStopwatch(); - var assemblyRun = new TestProgressState(assembly, targetFramework, architecture, sw); + var assemblyRun = new TestProgressState(Interlocked.Increment(ref _counter), assembly, targetFramework, architecture, sw); int slotIndex = _terminalWithProgress.AddWorker(assemblyRun); assemblyRun.SlotIndex = slotIndex; @@ -176,7 +190,7 @@ private TestProgressState GetOrAddAssemblyRun(string assembly, string? targetFra }); } - internal void TestExecutionCompleted(DateTimeOffset endTime) + public void TestExecutionCompleted(DateTimeOffset endTime) { _testExecutionEndTime = endTime; _terminalWithProgress.StopShowingProgress(); @@ -375,6 +389,7 @@ internal void TestCompleted( string? targetFramework, string? architecture, string? executionId, + string testNodeUid, string displayName, TestOutcome outcome, TimeSpan duration, @@ -391,6 +406,7 @@ internal void TestCompleted( targetFramework, architecture, executionId, + testNodeUid, displayName, outcome, duration, @@ -406,6 +422,7 @@ internal void TestCompleted( string? targetFramework, string? architecture, string? executionId, + string testNodeUid, string displayName, TestOutcome outcome, TimeSpan duration, @@ -417,6 +434,11 @@ internal void TestCompleted( { TestProgressState asm = _assemblies[$"{assembly}|{targetFramework}|{architecture}|{executionId}"]; + if (_options.ShowActiveTests) + { + asm.TestNodeResultsState?.RemoveRunningTestNode(testNodeUid); + } + switch (outcome) { case TestOutcome.Error: @@ -802,7 +824,7 @@ public void ArtifactAdded(bool outOfProcess, string? assembly, string? targetFra /// /// Let the user know that cancellation was triggered. /// - internal void StartCancelling() + public void StartCancelling() { _wasCancelled = true; _terminalWithProgress.WriteToTerminal(terminal => @@ -857,7 +879,7 @@ internal void WriteWarningMessage(string assembly, string? targetFramework, stri internal void WriteErrorMessage(string assembly, string? targetFramework, string? architecture, string? executionId, Exception exception) => WriteErrorMessage(assembly, targetFramework, architecture, executionId, exception.ToString(), padding: null); - internal void WriteMessage(string text, SystemConsoleColor? color = null, int? padding = null) + public void WriteMessage(string text, SystemConsoleColor? color = null, int? padding = null) { if (color != null) { @@ -980,4 +1002,24 @@ private static TerminalColor ToTerminalColor(ConsoleColor consoleColor) ConsoleColor.White => TerminalColor.White, _ => TerminalColor.Default, }; + + public void TestInProgress( + string assembly, + string? targetFramework, + string? architecture, + string testNodeUid, + string displayName, + string? executionId) + { + TestProgressState asm = _assemblies[$"{assembly}|{targetFramework}|{architecture}|{executionId}"]; + + if (_options.ShowActiveTests) + { + asm.TestNodeResultsState ??= new(Interlocked.Increment(ref _counter)); + asm.TestNodeResultsState.AddRunningTestNode( + Interlocked.Increment(ref _counter), testNodeUid, displayName, CreateStopwatch()); + } + + _terminalWithProgress.UpdateWorker(asm.SlotIndex); + } } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterOptions.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterOptions.cs index d2e84bc340..478453758d 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterOptions.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporterOptions.cs @@ -37,6 +37,11 @@ internal sealed class TerminalTestReporterOptions /// public Func ShowProgress { get; init; } = () => true; + /// + /// Gets a value indicating whether the active tests should be visible when the progress is shown. + /// + public bool ShowActiveTests { get; init; } + /// /// Gets a value indicating whether we should use ANSI escape codes or disable them. When true the capabilities of the console are autodetected. /// diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestDetailState.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestDetailState.cs new file mode 100644 index 0000000000..ad00e3ee42 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestDetailState.cs @@ -0,0 +1,37 @@ +// 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.Testing.Platform.Helpers; + +namespace Microsoft.Testing.Platform.OutputDevice.Terminal; + +internal sealed class TestDetailState +{ + private string _text; + + public TestDetailState(long id, IStopwatch? stopwatch, string text) + { + Id = id; + Stopwatch = stopwatch; + _text = text; + } + + public long Id { get; } + + public long Version { get; set; } + + public IStopwatch? Stopwatch { get; } + + public string Text + { + get => _text; + set + { + if (!_text.Equals(value, StringComparison.Ordinal)) + { + Version++; + _text = value; + } + } + } +} diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs new file mode 100644 index 0000000000..d2532fdcd7 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs @@ -0,0 +1,66 @@ +// 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.Concurrent; +using System.Globalization; + +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.Resources; + +namespace Microsoft.Testing.Platform.OutputDevice.Terminal; + +internal sealed class TestNodeResultsState +{ + public TestNodeResultsState(long id) + { + Id = id; + _summaryDetail = new(id, stopwatch: null, text: string.Empty); + } + + public long Id { get; } + + private readonly TestDetailState _summaryDetail; + private readonly ConcurrentDictionary _testNodeProgressStates = new(); + + public int Count => _testNodeProgressStates.Count; + + public void AddRunningTestNode(int id, string uid, string name, IStopwatch stopwatch) => _testNodeProgressStates[uid] = new TestDetailState(id, stopwatch, name); + + public void RemoveRunningTestNode(string uid) => _testNodeProgressStates.TryRemove(uid, out _); + + public TestDetailState? GetFirstRunningTask() => _testNodeProgressStates.FirstOrDefault().Value; + + public IEnumerable GetRunningTasks(int maxCount) + { + var sortedDetails = _testNodeProgressStates + .Select(d => d.Value) + .OrderByDescending(d => d.Stopwatch?.Elapsed ?? TimeSpan.Zero) + .ToList(); + + bool tooManyItems = sortedDetails.Count > maxCount; + + if (tooManyItems) + { + // Note: If there's too many items to display, the summary will take up one line. + // As such, we can only take maxCount - 1 items. + int itemsToTake = maxCount - 1; + _summaryDetail.Text = + itemsToTake == 0 + // Note: If itemsToTake is 0, then we only show two lines, the project summary and the number of running tests. + ? string.Format(CultureInfo.CurrentCulture, PlatformResources.ActiveTestsRunning_FullTestsCount, sortedDetails.Count) + // If itemsToTake is larger, then we show the project summary, active tests, and the number of active tests that are not shown. + : $"... {string.Format(CultureInfo.CurrentCulture, PlatformResources.ActiveTestsRunning_MoreTestsCount, sortedDetails.Count - itemsToTake)}"; + sortedDetails = sortedDetails.Take(itemsToTake).ToList(); + } + + foreach (TestDetailState? detail in sortedDetails) + { + yield return detail; + } + + if (tooManyItems) + { + yield return _summaryDetail; + } + } +} diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressState.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressState.cs index d117e2df4f..7824e12bc0 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressState.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressState.cs @@ -7,8 +7,9 @@ namespace Microsoft.Testing.Platform.OutputDevice.Terminal; internal sealed class TestProgressState { - public TestProgressState(string assembly, string? targetFramework, string? architecture, IStopwatch stopwatch) + public TestProgressState(long id, string assembly, string? targetFramework, string? architecture, IStopwatch stopwatch) { + Id = id; Assembly = assembly; TargetFramework = targetFramework; Architecture = architecture; @@ -38,11 +39,13 @@ public TestProgressState(string assembly, string? targetFramework, string? archi public int TotalTests { get; internal set; } - public string? Detail { get; internal set; } + public TestNodeResultsState? TestNodeResultsState { get; internal set; } public int SlotIndex { get; internal set; } - public long LastUpdate { get; internal set; } + public long Id { get; internal set; } + + public long Version { get; internal set; } public List<(string? DisplayName, string? UID)> DiscoveredTests { get; internal set; } = new(); diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs index 2f52afaa00..d369d99059 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestProgressStateAwareTerminal.cs @@ -31,6 +31,10 @@ internal sealed partial class TestProgressStateAwareTerminal : IDisposable private Thread? _refresher; private long _counter; + public event EventHandler? OnProgressStartUpdate; + + public event EventHandler? OnProgressStopUpdate; + /// /// The thread proc. /// @@ -42,6 +46,7 @@ private void ThreadProc() { lock (_lock) { + OnProgressStartUpdate?.Invoke(this, EventArgs.Empty); _terminal.StartUpdate(); try { @@ -50,6 +55,7 @@ private void ThreadProc() finally { _terminal.StopUpdate(); + OnProgressStopUpdate?.Invoke(this, EventArgs.Empty); } } } @@ -175,7 +181,7 @@ internal void UpdateWorker(int slotIndex) TestProgressState? progress = _progressItems[slotIndex]; if (progress != null) { - progress.LastUpdate = _counter; + progress.Version = _counter; } } } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs index b5eaff5ff8..f9d521e8a6 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs @@ -160,6 +160,7 @@ public Task InitializeAsync() ShowPassedTests = showPassed, MinimumExpectedTests = PlatformCommandLineProvider.GetMinimumExpectedTests(_commandLineOptions), UseAnsi = !noAnsi, + ShowActiveTests = true, ShowProgress = shouldShowProgress, }); @@ -421,7 +422,13 @@ public async Task ConsumeAsync(IDataProducer dataProducer, IData value, Cancella switch (testNodeStateChanged.TestNode.Properties.SingleOrDefault()) { case InProgressTestNodeStateProperty: - // do nothing. + _terminalTestReporter.TestInProgress( + _assemblyName, + _targetFramework, + _shortArchitecture, + testNodeStateChanged.TestNode.Uid.Value, + testNodeStateChanged.TestNode.DisplayName, + executionId: null); break; case ErrorTestNodeStateProperty errorState: @@ -430,6 +437,7 @@ public async Task ConsumeAsync(IDataProducer dataProducer, IData value, Cancella _targetFramework, _shortArchitecture, executionId: null, + testNodeStateChanged.TestNode.Uid.Value, testNodeStateChanged.TestNode.DisplayName, TestOutcome.Error, duration, @@ -447,6 +455,7 @@ public async Task ConsumeAsync(IDataProducer dataProducer, IData value, Cancella _targetFramework, _shortArchitecture, executionId: null, + testNodeStateChanged.TestNode.Uid.Value, testNodeStateChanged.TestNode.DisplayName, TestOutcome.Fail, duration, @@ -464,6 +473,7 @@ public async Task ConsumeAsync(IDataProducer dataProducer, IData value, Cancella _targetFramework, _shortArchitecture, executionId: null, + testNodeStateChanged.TestNode.Uid.Value, testNodeStateChanged.TestNode.DisplayName, TestOutcome.Timeout, duration, @@ -481,6 +491,7 @@ public async Task ConsumeAsync(IDataProducer dataProducer, IData value, Cancella _targetFramework, _shortArchitecture, executionId: null, + testNodeStateChanged.TestNode.Uid.Value, testNodeStateChanged.TestNode.DisplayName, TestOutcome.Canceled, duration, @@ -498,6 +509,7 @@ public async Task ConsumeAsync(IDataProducer dataProducer, IData value, Cancella _targetFramework, _shortArchitecture, executionId: null, + testNodeStateChanged.TestNode.Uid.Value, testNodeStateChanged.TestNode.DisplayName, outcome: TestOutcome.Passed, duration: duration, @@ -515,6 +527,7 @@ public async Task ConsumeAsync(IDataProducer dataProducer, IData value, Cancella _targetFramework, _shortArchitecture, executionId: null, + testNodeStateChanged.TestNode.Uid.Value, testNodeStateChanged.TestNode.DisplayName, TestOutcome.Skipped, duration, diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx index 3ae6c7d53f..8a899ed676 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx +++ b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx @@ -671,6 +671,12 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is The configuration file '{0}' specified with '--config-file' could not be found. + + and {0} more + + + {0} tests running + Starting test session. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index 3bdbc0f3a3..cf6e086f71 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -386,6 +386,16 @@ Při použití protokolu jsonRpc byl očekáván parametr --client-port. + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' Není zaregistrovaný žádný serializátor s ID {0}. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index 5d14ba2145..d72264fe27 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -386,6 +386,16 @@ "--client-port" wird erwartet, wenn das jsonRpc-Protokoll verwendet wird. + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' Es ist kein Serialisierungsmodul mit der ID "{0}" registriert diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index c0b9273013..41b085f814 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -386,6 +386,16 @@ Se esperaba --client-port cuando se usa el protocolo jsonRpc. + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' No hay ningún serializador registrado con el id. '{0}' diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index 0b8c6bc0b7..329c64aa1b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -386,6 +386,16 @@ Attendu --client-port attendu lorsque le protocole jsonRpc est utilisé. + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' Aucun sérialiseur inscrit avec l’ID « {0} » diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index d3e5c55526..d8fbad5523 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -386,6 +386,16 @@ Previsto --client-port quando viene usato il protocollo jsonRpc. + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' Nessun serializzatore registrato con ID '{0}' diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index 04505b2af6..c75d1f90a6 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -386,6 +386,16 @@ jsonRpc プロトコルを使用する場合、--client-port が必要です。 + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' ID '{0}' で登録されたシリアライザーがありません diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index 8a32fd0626..dbe377653d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -386,6 +386,16 @@ jsonRpc 프로토콜을 사용하는 경우 --client-port가 필요합니다. + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' ID '{0}'(으)로 등록된 직렬 변환기가 없습니다. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index 6b5d42a576..7d9979dca3 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -386,6 +386,16 @@ Oczekiwano parametru --client-port, gdy jest używany protokół jsonRpc. + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' Nie zarejestrowano serializatora z identyfikatorem „{0}” diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index 396831b6e5..f4b2a515c1 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -386,6 +386,16 @@ Esperado --client-port quando o protocolo jsonRpc é usado. + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' Nenhum serializador registrado com a ID “{0}” diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index 6f5ec3345d..7558bc61ed 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -386,6 +386,16 @@ Ожидается --client-port при использовании протокола jsonRpc. + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' Не зарегистрирован сериализатор с ИД "{0}" diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 25f69e948c..13990e1a13 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -386,6 +386,16 @@ JsonRpc protokolü kullanıldığında --client-port bekleniyordu. + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' '{0}' kimliğiyle kayıtlı seri hale getirici yok diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 833edb5f9c..8c6f95657c 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -386,6 +386,16 @@ 使用 jsonRpc 协议时应为 --client-port。 + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' 没有使用 ID“{0}”注册序列化程序 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index 218d20906d..64bddec133 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -386,6 +386,16 @@ 使用 jsonRpc 通訊協定時,必須是 --client-port。 + + and {0} more + and {0} more + + + + {0} tests running + {0} tests running + + No serializer registered with ID '{0}' 沒有使用識別碼 '{0}' 註冊的序列化程式 diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs index d47fe26699..d7bbe0f104 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs @@ -99,16 +99,16 @@ public void OutputFormattingIsCorrect() string standardOutput = "Hello!"; string errorOutput = "Oh no!"; - terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, "PassedTest1", TestOutcome.Passed, TimeSpan.FromSeconds(10), + terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, testNodeUid: "PassedTest1", "PassedTest1", TestOutcome.Passed, TimeSpan.FromSeconds(10), errorMessage: null, exception: null, expected: null, actual: null, standardOutput, errorOutput); - terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, "SkippedTest1", TestOutcome.Skipped, TimeSpan.FromSeconds(10), + terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, testNodeUid: "SkippedTest1", "SkippedTest1", TestOutcome.Skipped, TimeSpan.FromSeconds(10), errorMessage: null, exception: null, expected: null, actual: null, standardOutput, errorOutput); // timed out + canceled + failed should all report as failed in summary - terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, "TimedoutTest1", TestOutcome.Timeout, TimeSpan.FromSeconds(10), + terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, testNodeUid: "TimedoutTest1", "TimedoutTest1", TestOutcome.Timeout, TimeSpan.FromSeconds(10), errorMessage: null, exception: null, expected: null, actual: null, standardOutput, errorOutput); - terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, "CanceledTest1", TestOutcome.Canceled, TimeSpan.FromSeconds(10), + terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, testNodeUid: "CanceledTest1", "CanceledTest1", TestOutcome.Canceled, TimeSpan.FromSeconds(10), errorMessage: null, exception: null, expected: null, actual: null, standardOutput, errorOutput); - terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, "FailedTest1", TestOutcome.Fail, TimeSpan.FromSeconds(10), + terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, testNodeUid: "FailedTest1", "FailedTest1", TestOutcome.Fail, TimeSpan.FromSeconds(10), errorMessage: "Tests failed", exception: new StackTraceException(@$" at FailingTest() in {folder}codefile.cs:line 10"), expected: "ABC", actual: "DEF", standardOutput, errorOutput); terminalReporter.ArtifactAdded(outOfProcess: true, assembly, targetFramework, architecture, executionId: null, testName: null, @$"{folder}artifact1.txt"); terminalReporter.ArtifactAdded(outOfProcess: false, assembly, targetFramework, architecture, executionId: null, testName: null, @$"{folder}artifact2.txt"); @@ -167,12 +167,142 @@ Oh no! Assert.AreEqual(expected, ShowEscape(output)); } + public void OutputProgressFrameIsCorrect() + { + var stringBuilderConsole = new StringBuilderConsole(); + var stopwatchFactory = new StopwatchFactory(); + var terminalReporter = new TerminalTestReporter(stringBuilderConsole, new TerminalTestReporterOptions + { + ShowPassedTests = () => true, + UseAnsi = true, + ForceAnsi = true, + + ShowActiveTests = true, + ShowAssembly = false, + ShowAssemblyStartAndComplete = false, + ShowProgress = () => true, + }) + { + CreateStopwatch = stopwatchFactory.CreateStopwatch, + }; + + var startHandle = new AutoResetEvent(initialState: false); + var stopHandle = new AutoResetEvent(initialState: false); + + // Note: Ensure that we disable the timer updates, so that we can have deterministic output. + terminalReporter.OnProgressStartUpdate += (sender, args) => startHandle.WaitOne(); + terminalReporter.OnProgressStopUpdate += (sender, args) => stopHandle.Set(); + + DateTimeOffset startTime = DateTimeOffset.MinValue; + DateTimeOffset endTime = DateTimeOffset.MaxValue; + terminalReporter.TestExecutionStarted(startTime, 1, isDiscovery: false); + + string targetFramework = "net8.0"; + string architecture = "x64"; + string assembly = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\work\assembly.dll" : "/mnt/work/assembly.dll"; + string folder = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\work\" : "/mnt/work/"; + string folderNoSlash = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:\work" : "/mnt/work"; + string folderLink = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:/work/" : "mnt/work/"; + string folderLinkNoSlash = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? @"C:/work" : "mnt/work"; + + terminalReporter.AssemblyRunStarted(assembly, targetFramework, architecture, executionId: null); + string standardOutput = "Hello!"; + string errorOutput = "Oh no!"; + + // Note: Add 1ms to make the order of the progress frame deterministic. + // Otherwise all tests that run for 1m31s could show in any order. + terminalReporter.TestInProgress(assembly, targetFramework, architecture, testNodeUid: "PassedTest1", displayName: "PassedTest1", executionId: null); + stopwatchFactory.AddTime(TimeSpan.FromMilliseconds(1)); + terminalReporter.TestInProgress(assembly, targetFramework, architecture, testNodeUid: "SkippedTest1", displayName: "SkippedTest1", executionId: null); + stopwatchFactory.AddTime(TimeSpan.FromMilliseconds(1)); + terminalReporter.TestInProgress(assembly, targetFramework, architecture, testNodeUid: "InProgressTest1", displayName: "InProgressTest1", executionId: null); + stopwatchFactory.AddTime(TimeSpan.FromMinutes(1)); + terminalReporter.TestInProgress(assembly, targetFramework, architecture, testNodeUid: "InProgressTest2", displayName: "InProgressTest2", executionId: null); + stopwatchFactory.AddTime(TimeSpan.FromSeconds(30)); + terminalReporter.TestInProgress(assembly, targetFramework, architecture, testNodeUid: "InProgressTest3", displayName: "InProgressTest3", executionId: null); + stopwatchFactory.AddTime(TimeSpan.FromSeconds(1)); + + terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, testNodeUid: "PassedTest1", "PassedTest1", TestOutcome.Passed, TimeSpan.FromSeconds(10), + errorMessage: null, exception: null, expected: null, actual: null, standardOutput, errorOutput); + terminalReporter.TestCompleted(assembly, targetFramework, architecture, executionId: null, testNodeUid: "SkippedTest1", "SkippedTest1", TestOutcome.Skipped, TimeSpan.FromSeconds(10), + errorMessage: null, exception: null, expected: null, actual: null, standardOutput, errorOutput); + + string output = stringBuilderConsole.Output; + startHandle.Set(); + stopHandle.WaitOne(); + + // Note: On MacOS the busy indicator is not rendered. + bool useBusyIndicator = !RuntimeInformation.IsOSPlatform(OSPlatform.OSX); + string busyIndicatorString = useBusyIndicator ? "␛]9;4;3;␛\\" : string.Empty; + + // Note: The progress is drawn after each completed event. + string expected = $""" + {busyIndicatorString}␛[?25l␛[92mpassed␛[m PassedTest1␛[90m ␛[90m(10s 000ms)␛[m + ␛[90m Standard output + Hello! + Error output + Oh no! + ␛[m + [␛[92m✓1␛[m/␛[91mx0␛[m/␛[93m↓0␛[m] assembly.dll (net8.0|x64)␛[2147483640G(1m 31s) + SkippedTest1␛[2147483640G(1m 31s) + InProgressTest1␛[2147483640G(1m 31s) + InProgressTest2␛[2147483643G(31s) + InProgressTest3␛[2147483644G(1s) + ␛[7F + ␛[J␛[93mskipped␛[m SkippedTest1␛[90m ␛[90m(10s 000ms)␛[m + ␛[90m Standard output + Hello! + Error output + Oh no! + ␛[m + [␛[92m✓1␛[m/␛[91mx0␛[m/␛[93m↓1␛[m] assembly.dll (net8.0|x64)␛[2147483640G(1m 31s) + InProgressTest1␛[2147483640G(1m 31s) + InProgressTest2␛[2147483643G(31s) + InProgressTest3␛[2147483644G(1s) + + """; + + Assert.AreEqual(expected, ShowEscape(output)); + } + private static string? ShowEscape(string? text) { string visibleEsc = "\x241b"; return text?.Replace(AnsiCodes.Esc, visibleEsc); } + internal sealed class StopwatchFactory + { + private TimeSpan _currentTime = TimeSpan.Zero; + + public void AddTime(TimeSpan time) => _currentTime += time; + + public IStopwatch CreateStopwatch() => new MockStopwatch(this, _currentTime); + + internal sealed class MockStopwatch : IStopwatch + { + private readonly StopwatchFactory _factory; + + public MockStopwatch(StopwatchFactory factory, TimeSpan startTime) + { + _factory = factory; + StartTime = startTime; + } + + private TimeSpan StartTime { get; } + + public TimeSpan Elapsed => _factory._currentTime - StartTime; + + public void Start() + { + } + + public void Stop() + { + } + } + } + internal class StringBuilderConsole : IConsole { private readonly StringBuilder _output = new(); @@ -181,7 +311,7 @@ internal class StringBuilderConsole : IConsole public int BufferWidth => int.MinValue; - public bool IsOutputRedirected => throw new NotImplementedException(); + public bool IsOutputRedirected => false; public string Output => _output.ToString(); From bd822c7fd899f9ac902505c82bd93dbafff33bbe Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Dec 2024 10:38:51 +0100 Subject: [PATCH 089/273] Refactor GetTestFromMethod (#4279) --- .../Discovery/TypeEnumerator.cs | 42 ++++--- .../Helpers/ReflectHelper.cs | 2 +- ...sts.MockedMethodInfoWithExtraAttributes.cs | 98 +++++++++++++++++ .../Discovery/TypeEnumeratorTests.cs | 104 ++++++++---------- 4 files changed, 174 insertions(+), 72 deletions(-) create mode 100644 test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.MockedMethodInfoWithExtraAttributes.cs diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs index 847cf7e1fc..d84a72df10 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs @@ -201,29 +201,43 @@ internal UnitTestElement GetTestFromMethod(MethodInfo method, bool isDeclaredInT testElement.Traits = traits.ToArray(); - if (_reflectHelper.GetFirstDerivedAttributeOrDefault(method, inherit: true) is CssIterationAttribute cssIteration) - { - testElement.CssIteration = cssIteration.CssIteration; - } + Attribute[] attributes = _reflectHelper.GetCustomAttributesCached(method, inherit: true); + TestMethodAttribute? testMethodAttribute = null; - if (_reflectHelper.GetFirstDerivedAttributeOrDefault(method, inherit: true) is CssProjectStructureAttribute cssProjectStructure) + // Backward looping for backcompat. This used to be calls to _reflectHelper.GetFirstDerivedAttributeOrDefault + // So, to make sure the first attribute always wins, we loop from end to start. + for (int i = attributes.Length - 1; i >= 0; i--) { - testElement.CssProjectStructure = cssProjectStructure.CssProjectStructure; - } - - if (_reflectHelper.GetFirstDerivedAttributeOrDefault(method, inherit: true) is DescriptionAttribute descriptionAttribute) - { - testElement.Description = descriptionAttribute.Description; + if (attributes[i] is TestMethodAttribute tma) + { + testMethodAttribute = tma; + } + else if (attributes[i] is CssIterationAttribute cssIteration) + { + testElement.CssIteration = cssIteration.CssIteration; + } + else if (attributes[i] is CssProjectStructureAttribute cssProjectStructure) + { + testElement.CssProjectStructure = cssProjectStructure.CssProjectStructure; + } + else if (attributes[i] is DescriptionAttribute descriptionAttribute) + { + testElement.Description = descriptionAttribute.Description; + } } - WorkItemAttribute[] workItemAttributes = _reflectHelper.GetDerivedAttributes(method, inherit: true).ToArray(); - if (workItemAttributes.Length != 0) + IEnumerable workItemAttributes = attributes.OfType(); + if (workItemAttributes.Any()) { testElement.WorkItemIds = workItemAttributes.Select(x => x.Id.ToString(CultureInfo.InvariantCulture)).ToArray(); } + // In production, we always have a TestMethod attribute because GetTestFromMethod is called under IsValidTestMethod + // In unit tests, we may not have the test to have TestMethodAttribute. + // TODO: Adjust all unit tests to properly have the attribute and uncomment the assert. + // DebugEx.Assert(testMethodAttribute is not null, "Expected to find a 'TestMethod' attribute."); + // get DisplayName from TestMethodAttribute (or any inherited attribute) - TestMethodAttribute? testMethodAttribute = _reflectHelper.GetFirstDerivedAttributeOrDefault(method, inherit: true); testElement.DisplayName = testMethodAttribute?.DisplayName ?? method.Name; return testElement; diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index 34a40beda3..340da1a1ae 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -428,7 +428,7 @@ internal virtual IEnumerable GetTestPropertiesAsTraits(MemberInfo testPro /// The member to inspect. /// Look at inheritance chain. /// attributes defined. - private Attribute[] GetCustomAttributesCached(ICustomAttributeProvider attributeProvider, bool inherit) + internal Attribute[] GetCustomAttributesCached(ICustomAttributeProvider attributeProvider, bool inherit) { // If the information is cached, then use it otherwise populate the cache using // the reflection APIs. diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.MockedMethodInfoWithExtraAttributes.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.MockedMethodInfoWithExtraAttributes.cs new file mode 100644 index 0000000000..d8a24c8b88 --- /dev/null +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.MockedMethodInfoWithExtraAttributes.cs @@ -0,0 +1,98 @@ +// 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.Globalization; +using System.Reflection; + +#if !NET6_0_OR_GREATER +using Polyfills; +#endif + +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Discovery; + +public partial class TypeEnumeratorTests +{ + private sealed class MockedMethodInfoWithExtraAttributes : MethodInfo + { + private readonly MethodInfo _original; + private readonly Attribute[] _extraAttributes; + + public MockedMethodInfoWithExtraAttributes(MethodInfo original, params Attribute[] extraAttributes) + { + _original = original; + _extraAttributes = extraAttributes; + } + + public override ICustomAttributeProvider ReturnTypeCustomAttributes => _original.ReturnTypeCustomAttributes; + + public override RuntimeMethodHandle MethodHandle => _original.MethodHandle; + + public override MethodAttributes Attributes => _original.Attributes; + + public override string Name => _original.Name; + + public override Type DeclaringType => _original.DeclaringType; + + public override Type ReflectedType => _original.ReflectedType; + + public override IEnumerable CustomAttributes => _original.CustomAttributes; + + public override int MetadataToken => _original.MetadataToken; + + public override Module Module => _original.Module; + + public override MethodImplAttributes MethodImplementationFlags => _original.MethodImplementationFlags; + + public override CallingConventions CallingConvention => _original.CallingConvention; + + public override bool IsGenericMethodDefinition => _original.IsGenericMethodDefinition; + + public override bool ContainsGenericParameters => _original.ContainsGenericParameters; + + public override bool IsGenericMethod => _original.IsGenericMethod; + + public override bool IsSecurityCritical => _original.IsSecurityCritical; + + public override bool IsSecuritySafeCritical => _original.IsSecuritySafeCritical; + + public override bool IsSecurityTransparent => _original.IsSecurityTransparent; + + public override MemberTypes MemberType => _original.MemberType; + + public override Type ReturnType => _original.ReturnType; + + public override ParameterInfo ReturnParameter => _original.ReturnParameter; + + public override Delegate CreateDelegate(Type delegateType) => _original.CreateDelegate(delegateType); + + public override Delegate CreateDelegate(Type delegateType, object target) => _original.CreateDelegate(delegateType, target); + + public override MethodInfo GetBaseDefinition() => _original.GetBaseDefinition(); + + public override object[] GetCustomAttributes(bool inherit) => _original.GetCustomAttributes().Concat(_extraAttributes).ToArray(); + + public override object[] GetCustomAttributes(Type attributeType, bool inherit) => _original.GetCustomAttributes().Concat(_extraAttributes.Where(a => a.GetType().IsAssignableTo(attributeType))).ToArray(); + + public override IList GetCustomAttributesData() => _original.GetCustomAttributesData(); + + public override Type[] GetGenericArguments() => _original.GetGenericArguments(); + + public override MethodInfo GetGenericMethodDefinition() => _original.GetGenericMethodDefinition(); + + public override MethodBody GetMethodBody() => _original.GetMethodBody(); + + public override MethodImplAttributes GetMethodImplementationFlags() => _original.GetMethodImplementationFlags(); + + public override ParameterInfo[] GetParameters() => _original.GetParameters(); + + public override object Invoke(object obj, BindingFlags invokeAttr, Binder binder, object[] parameters, CultureInfo culture) + => _original.Invoke(obj, invokeAttr, binder, parameters, culture); + + public override bool IsDefined(Type attributeType, bool inherit) + => _original.IsDefined(attributeType, inherit) || _extraAttributes.Any(a => a.GetType().IsAssignableTo(attributeType)); + + public override MethodInfo MakeGenericMethod(params Type[] typeArguments) => _original.MakeGenericMethod(typeArguments); + + public override string ToString() => _original.ToString(); + } +} diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs index e3706ea127..78c3b2998e 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs @@ -8,7 +8,6 @@ using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.TestableImplementations; -using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -19,7 +18,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Discovery; -public class TypeEnumeratorTests : TestContainer +public partial class TypeEnumeratorTests : TestContainer { private readonly Mock _mockReflectHelper; private readonly Mock _mockTestMethodValidator; @@ -31,7 +30,11 @@ public class TypeEnumeratorTests : TestContainer public TypeEnumeratorTests() { - _mockReflectHelper = new Mock(); + _mockReflectHelper = new Mock() + { + CallBase = true, + }; + _mockTypeValidator = new Mock(MockBehavior.Default, _mockReflectHelper.Object); _mockTestMethodValidator = new Mock(MockBehavior.Default, _mockReflectHelper.Object); _warnings = new List(); @@ -297,12 +300,6 @@ public void GetTestFromMethodShouldSetIgnoredPropertyToFalseIfNotSetOnTestClassA TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - // Setup mocks - _mockReflectHelper.Setup( - rh => rh.IsNonDerivedAttributeDefined(typeof(DummyTestClass), false)).Returns(false); - _mockReflectHelper.Setup( - rh => rh.IsNonDerivedAttributeDefined(methodInfo, false)).Returns(false); - MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); Verify(testElement is not null); @@ -314,11 +311,9 @@ public void GetTestFromMethodShouldSetTestCategory() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); + methodInfo = new MockedMethodInfoWithExtraAttributes(methodInfo, new TestCategoryAttribute("foo"), new TestCategoryAttribute("bar")); string[] testCategories = ["foo", "bar"]; - // Setup mocks - _mockReflectHelper.Setup(rh => rh.GetTestCategories(methodInfo, typeof(DummyTestClass))).Returns(testCategories); - MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); Verify(testElement is not null); @@ -330,9 +325,7 @@ public void GetTestFromMethodShouldSetDoNotParallelize() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - - // Setup mocks - _mockReflectHelper.Setup(rh => rh.IsDerivedAttributeDefined(It.IsAny(), true)).Returns(true); + methodInfo = new MockedMethodInfoWithExtraAttributes(methodInfo, new DoNotParallelizeAttribute()); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); @@ -345,15 +338,20 @@ public void GetTestFromMethodShouldFillTraitsWithTestProperties() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - var testProperties = new List { new("foo", "bar"), new("fooprime", "barprime") }; - - // Setup mocks - _mockReflectHelper.Setup(rh => rh.GetTestPropertiesAsTraits(methodInfo)).Returns(testProperties); + methodInfo = new MockedMethodInfoWithExtraAttributes( + methodInfo, + new TestMethodAttribute(), + new TestPropertyAttribute("foo", "bar"), + new TestPropertyAttribute("fooprime", "barprime")); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); Verify(testElement is not null); - Verify(testProperties.SequenceEqual(testElement.Traits)); + Verify(testElement.Traits.Length == 2); + Verify(testElement.Traits[0].Name == "foo"); + Verify(testElement.Traits[0].Value == "bar"); + Verify(testElement.Traits[1].Name == "fooprime"); + Verify(testElement.Traits[1].Value == "barprime"); } public void GetTestFromMethodShouldFillTraitsWithTestOwnerPropertyIfPresent() @@ -361,18 +359,23 @@ public void GetTestFromMethodShouldFillTraitsWithTestOwnerPropertyIfPresent() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - var testProperties = new List { new("foo", "bar"), new("fooprime", "barprime") }; - var ownerTrait = new Trait("owner", "mike"); - - // Setup mocks - _mockReflectHelper.Setup(rh => rh.GetTestPropertiesAsTraits(methodInfo)).Returns(testProperties); - _mockReflectHelper.Setup(rh => rh.GetTestOwnerAsTraits(methodInfo)).Returns(ownerTrait); + methodInfo = new MockedMethodInfoWithExtraAttributes( + methodInfo, + new TestMethodAttribute(), + new TestPropertyAttribute("foo", "bar"), + new TestPropertyAttribute("fooprime", "barprime"), + new OwnerAttribute("mike")); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); Verify(testElement is not null); - testProperties.Add(ownerTrait); - Verify(testProperties.SequenceEqual(testElement.Traits)); + Verify(testElement.Traits.Length == 3); + Verify(testElement.Traits[0].Name == "foo"); + Verify(testElement.Traits[0].Value == "bar"); + Verify(testElement.Traits[1].Name == "fooprime"); + Verify(testElement.Traits[1].Value == "barprime"); + Verify(testElement.Traits[2].Name == "Owner"); + Verify(testElement.Traits[2].Value == "mike"); } public void GetTestFromMethodShouldFillTraitsWithTestPriorityPropertyIfPresent() @@ -380,19 +383,18 @@ public void GetTestFromMethodShouldFillTraitsWithTestPriorityPropertyIfPresent() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - var testProperties = new List { new("foo", "bar"), new("fooprime", "barprime") }; - var priorityTrait = new Trait("Priority", "1"); - - // Setup mocks - _mockReflectHelper.Setup(rh => rh.GetTestPropertiesAsTraits(methodInfo)).Returns(testProperties); - _mockReflectHelper.Setup(rh => rh.GetPriority(methodInfo)).Returns(1); - _mockReflectHelper.Setup(rh => rh.GetTestPriorityAsTraits(1)).Returns(priorityTrait); + methodInfo = new MockedMethodInfoWithExtraAttributes(methodInfo, new TestPropertyAttribute("foo", "bar"), new TestPropertyAttribute("fooprime", "barprime"), new PriorityAttribute(1)); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); Verify(testElement is not null); - testProperties.Add(priorityTrait); - Verify(testProperties.SequenceEqual(testElement.Traits)); + Verify(testElement.Traits.Length == 3); + Verify(testElement.Traits[0].Name == "foo"); + Verify(testElement.Traits[0].Value == "bar"); + Verify(testElement.Traits[1].Name == "fooprime"); + Verify(testElement.Traits[1].Value == "barprime"); + Verify(testElement.Traits[2].Name == "Priority"); + Verify(testElement.Traits[2].Value == "1"); } public void GetTestFromMethodShouldSetPriority() @@ -400,9 +402,7 @@ public void GetTestFromMethodShouldSetPriority() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - - // Setup mocks - _mockReflectHelper.Setup(rh => rh.GetPriority(methodInfo)).Returns(1); + methodInfo = new MockedMethodInfoWithExtraAttributes(methodInfo, new PriorityAttribute(1)); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); @@ -415,7 +415,7 @@ public void GetTestFromMethodShouldSetDescription() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - _mockReflectHelper.Setup(rh => rh.GetFirstDerivedAttributeOrDefault(methodInfo, true)).Returns(new DescriptionAttribute("Dummy description")); + methodInfo = new MockedMethodInfoWithExtraAttributes(methodInfo, new DescriptionAttribute("Dummy description")); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); @@ -427,7 +427,7 @@ public void GetTestFromMethodShouldSetWorkItemIds() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - _mockReflectHelper.Setup(rh => rh.GetDerivedAttributes(methodInfo, true)).Returns([new(123), new(345)]); + methodInfo = new MockedMethodInfoWithExtraAttributes(methodInfo, new WorkItemAttribute(123), new WorkItemAttribute(345)); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); @@ -439,7 +439,6 @@ public void GetTestFromMethodShouldSetWorkItemIdsToNullIfNotAny() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - _mockReflectHelper.Setup(rh => rh.GetDerivedAttributes(methodInfo, true)).Returns([]); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); @@ -451,7 +450,7 @@ public void GetTestFromMethodShouldSetCssIteration() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - _mockReflectHelper.Setup(rh => rh.GetFirstDerivedAttributeOrDefault(methodInfo, true)).Returns(new CssIterationAttribute("234")); + methodInfo = new MockedMethodInfoWithExtraAttributes(methodInfo, new CssIterationAttribute("234")); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); @@ -463,7 +462,7 @@ public void GetTestFromMethodShouldSetCssProjectStructure() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - _mockReflectHelper.Setup(rh => rh.GetFirstDerivedAttributeOrDefault(methodInfo, true)).Returns(new CssProjectStructureAttribute("ProjectStructure123")); + methodInfo = new MockedMethodInfoWithExtraAttributes(methodInfo, new CssProjectStructureAttribute("ProjectStructure123")); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); @@ -528,10 +527,7 @@ public void GetTestFromMethodShouldSetDisplayNameToTestMethodNameIfDisplayNameIs SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod(nameof(DummyTestClass.MethodWithVoidReturnType)); - - // Setup mocks to behave like we have [TestMethod] attribute on the method - _mockReflectHelper.Setup( - rh => rh.GetFirstDerivedAttributeOrDefault(It.IsAny(), false)).Returns(new TestMethodAttribute()); + methodInfo = new MockedMethodInfoWithExtraAttributes(methodInfo, new TestMethodAttribute()); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); @@ -544,10 +540,7 @@ public void GetTestFromMethodShouldSetDisplayNameFromTestMethodAttribute() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod(nameof(DummyTestClass.MethodWithVoidReturnType)); - - // Setup mocks to behave like we have [TestMethod("Test method display name.")] attribute on the method - _mockReflectHelper.Setup( - rh => rh.GetFirstDerivedAttributeOrDefault(methodInfo, true)).Returns(new TestMethodAttribute("Test method display name.")); + methodInfo = new MockedMethodInfoWithExtraAttributes(methodInfo, new TestMethodAttribute("Test method display name.")); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); @@ -560,10 +553,7 @@ public void GetTestFromMethodShouldSetDisplayNameFromDataTestMethodAttribute() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); MethodInfo methodInfo = typeof(DummyTestClass).GetMethod(nameof(DummyTestClass.MethodWithVoidReturnType)); - - // Setup mocks to behave like we have [DataTestMethod("Test method display name.")] attribute on the method - _mockReflectHelper.Setup( - rh => rh.GetFirstDerivedAttributeOrDefault(methodInfo, true)).Returns(new DataTestMethodAttribute("Test method display name.")); + methodInfo = new MockedMethodInfoWithExtraAttributes(methodInfo, new DataTestMethodAttribute("Test method display name.")); MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); From 447290e02b71d1b80f75c13ddd738fb9e534891a Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Dec 2024 13:53:53 +0100 Subject: [PATCH 090/273] Preserve message and parameters in MSTEST0025 fixer (#4301) --- ...ssertFailOverAlwaysFalseConditionsFixer.cs | 13 +++- .../Helpers/WellKnownTypeNames.cs | 1 - ...rtFailOverAlwaysFalseConditionsAnalyzer.cs | 51 +++++++++++++--- ...ReviewAlwaysTrueAssertConditionAnalyzer.cs | 15 +++-- ...lOverAlwaysFalseConditionsAnalyzerTests.cs | 61 +++++++++++++++---- 5 files changed, 108 insertions(+), 33 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferAssertFailOverAlwaysFalseConditionsFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferAssertFailOverAlwaysFalseConditionsFixer.cs index 56966e24e2..7b5379e0c9 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferAssertFailOverAlwaysFalseConditionsFixer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferAssertFailOverAlwaysFalseConditionsFixer.cs @@ -9,6 +9,7 @@ using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Editing; using Microsoft.CodeAnalysis.Text; @@ -44,22 +45,28 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) context.RegisterCodeFix( CodeAction.Create( CodeFixResources.ReplaceWithFailAssertionFix, - ct => SwapArgumentsAsync(context.Document, invocationExpr, ct), + ct => UseAssertFailAsync(context.Document, invocationExpr, diagnostic.AdditionalLocations, ct), nameof(PreferAssertFailOverAlwaysFalseConditionsFixer)), context.Diagnostics); } } - private static async Task SwapArgumentsAsync(Document document, InvocationExpressionSyntax invocationExpr, CancellationToken cancellationToken) + private static async Task UseAssertFailAsync(Document document, InvocationExpressionSyntax invocationExpr, IReadOnlyList additionalLocations, CancellationToken cancellationToken) { cancellationToken.ThrowIfCancellationRequested(); DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); SyntaxGenerator generator = editor.Generator; - SyntaxNode newInvocationExpr = generator.InvocationExpression( + var newInvocationExpr = (InvocationExpressionSyntax)generator.InvocationExpression( generator.MemberAccessExpression(generator.IdentifierName("Assert"), "Fail")); + if (additionalLocations.Count >= 1) + { + IEnumerable arguments = additionalLocations.Select(location => (ArgumentSyntax)invocationExpr.FindNode(location.SourceSpan)); + newInvocationExpr = newInvocationExpr.WithArgumentList(SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(arguments))); + } + editor.ReplaceNode(invocationExpr, newInvocationExpr); return editor.GetChangedDocument(); diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs b/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs index 86bd502f22..92bafef649 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs @@ -44,7 +44,6 @@ internal static class WellKnownTypeNames public const string SystemDescriptionAttribute = "System.ComponentModel.DescriptionAttribute"; public const string SystemIAsyncDisposable = "System.IAsyncDisposable"; public const string SystemIDisposable = "System.IDisposable"; - public const string SystemNullable = "System.Nullable`1"; public const string SystemReflectionMethodInfo = "System.Reflection.MethodInfo"; public const string SystemRuntimeCompilerServicesITuple = "System.Runtime.CompilerServices.ITuple"; public const string SystemThreadingTasksTask = "System.Threading.Tasks.Task"; diff --git a/src/Analyzers/MSTest.Analyzers/PreferAssertFailOverAlwaysFalseConditionsAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/PreferAssertFailOverAlwaysFalseConditionsAnalyzer.cs index ec11b318ed..921849d077 100644 --- a/src/Analyzers/MSTest.Analyzers/PreferAssertFailOverAlwaysFalseConditionsAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/PreferAssertFailOverAlwaysFalseConditionsAnalyzer.cs @@ -32,6 +32,8 @@ private enum EqualityStatus private const string ActualParameterName = "actual"; private const string ConditionParameterName = "condition"; private const string ValueParameterName = "value"; + private const string MessageParameterName = "message"; + private const string ParametersParameterName = "parameters"; private static readonly LocalizableResourceString Title = new(nameof(Resources.PreferAssertFailOverAlwaysFalseConditionsTitle), Resources.ResourceManager, typeof(Resources)); private static readonly LocalizableResourceString MessageFormat = new(nameof(Resources.PreferAssertFailOverAlwaysFalseConditionsMessageFormat), Resources.ResourceManager, typeof(Resources)); @@ -57,26 +59,57 @@ public override void Initialize(AnalysisContext context) { Compilation compilation = context.Compilation; INamedTypeSymbol? assertSymbol = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingAssert); - INamedTypeSymbol? nullableSymbol = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemNullable); if (assertSymbol is not null) { - context.RegisterOperationAction(context => AnalyzeOperation(context, assertSymbol, nullableSymbol), OperationKind.Invocation); + context.RegisterOperationAction(context => AnalyzeOperation(context, assertSymbol), OperationKind.Invocation); } }); } - private static void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol assertSymbol, INamedTypeSymbol? nullableSymbol) + private static void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol assertSymbol) { var operation = (IInvocationOperation)context.Operation; if (assertSymbol.Equals(operation.TargetMethod.ContainingType, SymbolEqualityComparer.Default) && - IsAlwaysFalse(operation, nullableSymbol)) + IsAlwaysFalse(operation)) { - context.ReportDiagnostic(operation.CreateDiagnostic(Rule, operation.TargetMethod.Name)); + context.ReportDiagnostic(operation.CreateDiagnostic(Rule, GetAdditionalLocations(operation), properties: null, operation.TargetMethod.Name)); } } - private static bool IsAlwaysFalse(IInvocationOperation operation, INamedTypeSymbol? nullableSymbol) + private static ImmutableArray GetAdditionalLocations(IInvocationOperation operation) + { + IArgumentOperation? messageArg = operation.Arguments.FirstOrDefault(arg => arg.Parameter?.Name == MessageParameterName); + if (messageArg is null) + { + return ImmutableArray.Empty; + } + + IArgumentOperation? parametersArg = operation.Arguments.FirstOrDefault(arg => arg.Parameter?.Name == ParametersParameterName); + if (parametersArg is null) + { + return ImmutableArray.Create(messageArg.Syntax.GetLocation()); + } + + if (parametersArg.ArgumentKind == ArgumentKind.ParamArray) + { + ImmutableArray.Builder builder = ImmutableArray.CreateBuilder(); + builder.Add(messageArg.Syntax.GetLocation()); + if (parametersArg.Value is IArrayCreationOperation { Initializer.ElementValues: { } elements }) + { + foreach (IOperation element in elements) + { + builder.Add(element.Syntax.GetLocation()); + } + } + + return builder.ToImmutable(); + } + + return ImmutableArray.Create(messageArg.Syntax.GetLocation(), parametersArg.Syntax.GetLocation()); + } + + private static bool IsAlwaysFalse(IInvocationOperation operation) => operation.TargetMethod.Name switch { "IsTrue" => GetConditionArgument(operation) is { Value.ConstantValue: { HasValue: true, Value: false } }, @@ -84,16 +117,16 @@ private static bool IsAlwaysFalse(IInvocationOperation operation, INamedTypeSymb "AreEqual" => GetEqualityStatus(operation, ExpectedParameterName) == EqualityStatus.NotEqual, "AreNotEqual" => GetEqualityStatus(operation, NotExpectedParameterName) == EqualityStatus.Equal, "IsNotNull" => GetValueArgument(operation) is { Value.ConstantValue: { HasValue: true, Value: null } }, - "IsNull" => GetValueArgument(operation) is { } valueArgumentOperation && IsNotNullableType(valueArgumentOperation, nullableSymbol), + "IsNull" => GetValueArgument(operation) is { } valueArgumentOperation && IsNotNullableType(valueArgumentOperation), _ => false, }; - private static bool IsNotNullableType(IArgumentOperation valueArgumentOperation, INamedTypeSymbol? nullableSymbol) + private static bool IsNotNullableType(IArgumentOperation valueArgumentOperation) { ITypeSymbol? valueArgType = valueArgumentOperation.Value.GetReferencedMemberOrLocalOrParameter().GetReferencedMemberOrLocalOrParameter(); return valueArgType is not null && valueArgType.NullableAnnotation == NullableAnnotation.NotAnnotated - && !SymbolEqualityComparer.IncludeNullability.Equals(valueArgType.OriginalDefinition, nullableSymbol); + && valueArgType.OriginalDefinition.SpecialType != SpecialType.System_Nullable_T; } private static IArgumentOperation? GetArgumentWithName(IInvocationOperation operation, string name) diff --git a/src/Analyzers/MSTest.Analyzers/ReviewAlwaysTrueAssertConditionAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/ReviewAlwaysTrueAssertConditionAnalyzer.cs index 662877724d..1fe7925b0b 100644 --- a/src/Analyzers/MSTest.Analyzers/ReviewAlwaysTrueAssertConditionAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/ReviewAlwaysTrueAssertConditionAnalyzer.cs @@ -57,25 +57,24 @@ public override void Initialize(AnalysisContext context) { Compilation compilation = context.Compilation; INamedTypeSymbol? assertSymbol = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingAssert); - INamedTypeSymbol? nullableSymbol = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemNullable); if (assertSymbol is not null) { - context.RegisterOperationAction(context => AnalyzeOperation(context, assertSymbol, nullableSymbol), OperationKind.Invocation); + context.RegisterOperationAction(context => AnalyzeOperation(context, assertSymbol), OperationKind.Invocation); } }); } - private static void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol assertSymbol, INamedTypeSymbol? nullableSymbol) + private static void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol assertSymbol) { var operation = (IInvocationOperation)context.Operation; if (assertSymbol.Equals(operation.TargetMethod.ContainingType, SymbolEqualityComparer.Default) && - IsAlwaysTrue(operation, nullableSymbol)) + IsAlwaysTrue(operation)) { context.ReportDiagnostic(operation.CreateDiagnostic(Rule)); } } - private static bool IsAlwaysTrue(IInvocationOperation operation, INamedTypeSymbol? nullableSymbol) + private static bool IsAlwaysTrue(IInvocationOperation operation) => operation.TargetMethod.Name switch { "IsTrue" => GetConditionArgument(operation) is { Value.ConstantValue: { HasValue: true, Value: true } }, @@ -83,16 +82,16 @@ private static bool IsAlwaysTrue(IInvocationOperation operation, INamedTypeSymbo "AreEqual" => GetEqualityStatus(operation, ExpectedParameterName) == EqualityStatus.Equal, "AreNotEqual" => GetEqualityStatus(operation, NotExpectedParameterName) == EqualityStatus.NotEqual, "IsNull" => GetValueArgument(operation) is { Value.ConstantValue: { HasValue: true, Value: null } }, - "IsNotNull" => GetValueArgument(operation) is { } valueArgumentOperation && IsNotNullableType(valueArgumentOperation, nullableSymbol), + "IsNotNull" => GetValueArgument(operation) is { } valueArgumentOperation && IsNotNullableType(valueArgumentOperation), _ => false, }; - private static bool IsNotNullableType(IArgumentOperation valueArgumentOperation, INamedTypeSymbol? nullableSymbol) + private static bool IsNotNullableType(IArgumentOperation valueArgumentOperation) { ITypeSymbol? valueArgType = valueArgumentOperation.Value.GetReferencedMemberOrLocalOrParameter().GetReferencedMemberOrLocalOrParameter(); return valueArgType is not null && valueArgType.NullableAnnotation == NullableAnnotation.NotAnnotated - && !SymbolEqualityComparer.IncludeNullability.Equals(valueArgType.OriginalDefinition, nullableSymbol); + && valueArgType.OriginalDefinition.SpecialType != SpecialType.System_Nullable_T; } private static IArgumentOperation? GetArgumentWithName(IInvocationOperation operation, string name) diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferAssertFailOverAlwaysFalseConditionsAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferAssertFailOverAlwaysFalseConditionsAnalyzerTests.cs index f6a9729152..b2c05361d5 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferAssertFailOverAlwaysFalseConditionsAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferAssertFailOverAlwaysFalseConditionsAnalyzerTests.cs @@ -326,7 +326,44 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail("message"); + } + } + """; + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + public async Task WhenAssertIsTrueIsPassedFalse_WithMessageAndArgsAsParams_Diagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void TestMethod() + { + [|Assert.IsTrue(false, "message", "1")|]; + [|Assert.IsTrue(false, "message", "1", "2")|]; + [|Assert.IsTrue(false, "message", new object[] { "1", "2" })|]; + [|Assert.IsTrue(message: "message", parameters: new object[] { "1", "2" }, condition: false)|]; + } + } + """; + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void TestMethod() + { + Assert.Fail("message", "1"); + Assert.Fail("message", "1", "2"); + Assert.Fail("message", new object[] { "1", "2" }); + Assert.Fail(message: "message", parameters: new object[] { "1", "2" }); } } """; @@ -357,7 +394,7 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail(message: "message"); } } """; @@ -483,7 +520,7 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail("message"); } } """; @@ -515,7 +552,7 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail(message: "message"); } } """; @@ -699,7 +736,7 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail("message"); } } """; @@ -731,7 +768,7 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail(message: "message"); } } """; @@ -934,7 +971,7 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail("message"); } } """; @@ -966,7 +1003,7 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail(message: "message"); } } """; @@ -998,7 +1035,7 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail(message: "message"); } } """; @@ -1146,7 +1183,7 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail("message"); } } """; @@ -1178,7 +1215,7 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail(message: "message"); } } """; @@ -1210,7 +1247,7 @@ public class MyTestClass [TestMethod] public void TestMethod() { - Assert.Fail(); + Assert.Fail(message: "message"); } } """; From 2d0cd70f2240c4f75f2587452fc98255b8289a6d Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 10 Dec 2024 05:11:42 -0800 Subject: [PATCH 091/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2598826 --- .../Resources/xlf/PlatformResources.cs.xlf | 2 +- .../Resources/xlf/PlatformResources.de.xlf | 2 +- .../Resources/xlf/PlatformResources.es.xlf | 4 ++-- .../Resources/xlf/PlatformResources.fr.xlf | 4 ++-- .../Resources/xlf/PlatformResources.it.xlf | 2 +- .../Resources/xlf/PlatformResources.ja.xlf | 4 ++-- .../Resources/xlf/PlatformResources.ko.xlf | 2 +- .../Resources/xlf/PlatformResources.pl.xlf | 2 +- .../Resources/xlf/PlatformResources.pt-BR.xlf | 4 ++-- .../Resources/xlf/PlatformResources.ru.xlf | 4 ++-- .../Resources/xlf/PlatformResources.tr.xlf | 2 +- .../Resources/xlf/PlatformResources.zh-Hans.xlf | 4 ++-- .../Resources/xlf/PlatformResources.zh-Hant.xlf | 4 ++-- 13 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index cf6e086f71..47adbca59a 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -393,7 +393,7 @@ {0} tests running - {0} tests running + {0} spuštěné testy diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index d72264fe27..5102d26462 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -393,7 +393,7 @@ {0} tests running - {0} tests running + {0} ausgeführten Tests diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index 41b085f814..c23458d113 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -388,12 +388,12 @@ and {0} more - and {0} more + y {0} más {0} tests running - {0} tests running + {0} pruebas en ejecución diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index 329c64aa1b..f4bb8dd0b7 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -388,12 +388,12 @@ and {0} more - and {0} more + et {0} de plus {0} tests running - {0} tests running + {0} tests en cours d’exécution diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index d8fbad5523..0de5fa57fa 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -393,7 +393,7 @@ {0} tests running - {0} tests running + {0} test in esecuzione diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index c75d1f90a6..2e622e075e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -388,12 +388,12 @@ and {0} more - and {0} more + その他 {0} 件 {0} tests running - {0} tests running + {0} テストを実行しています diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index dbe377653d..22c32f88ab 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -393,7 +393,7 @@ {0} tests running - {0} tests running + 실행 중인 테스트 {0} diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index 7d9979dca3..c1cd3555bb 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -393,7 +393,7 @@ {0} tests running - {0} tests running + testy {0} uruchomione diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index f4b2a515c1..398b0f293c 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -388,12 +388,12 @@ and {0} more - and {0} more + e mais {0} {0} tests running - {0} tests running + {0} testes em execução diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index 7558bc61ed..a48eef9579 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -388,12 +388,12 @@ and {0} more - and {0} more + и еще {0} {0} tests running - {0} tests running + {0} тестов diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 13990e1a13..4ea66f782c 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -393,7 +393,7 @@ {0} tests running - {0} tests running + {0} test çalıştırılıyor diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 8c6f95657c..4b98c6928f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -388,12 +388,12 @@ and {0} more - and {0} more + 和其他 {0} 项 {0} tests running - {0} tests running + 正在运行 {0} 测试 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index 64bddec133..ec34238c60 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -388,12 +388,12 @@ and {0} more - and {0} more + 和其他 {0} 個 {0} tests running - {0} tests running + 正在執行 {0} 測試 From 23dd83b2c2920f6f5820bc66dde203d11278a2b0 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 10 Dec 2024 20:06:38 +0100 Subject: [PATCH 092/273] Support 'TestPropertyAttribute' on test classes (#4249) --- .../MSTest.TestAdapter/Execution/TypeCache.cs | 11 +- .../Helpers/ReflectHelper.cs | 5 + .../TestMethod/TestPropertyAttribute.cs | 2 +- .../Execution/TestPropertyAttributeTests.cs | 204 ++++++++++++++++++ .../Execution/TypeCacheTests.cs | 25 ++- 5 files changed, 238 insertions(+), 9 deletions(-) create mode 100644 test/UnitTests/MSTestAdapter.UnitTests/Execution/TestPropertyAttributeTests.cs diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index 6ab6227133..5e5f5c68a2 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -911,15 +911,20 @@ private TimeoutInfo GetTestTimeout(MethodInfo methodInfo, TestMethod testMethod) /// /// The test Method Info. /// The test Context. - private static void SetCustomProperties(TestMethodInfo testMethodInfo, ITestContext testContext) + private void SetCustomProperties(TestMethodInfo testMethodInfo, ITestContext testContext) { DebugEx.Assert(testMethodInfo != null, "testMethodInfo is Null"); DebugEx.Assert(testMethodInfo.TestMethod != null, "testMethodInfo.TestMethod is Null"); - object[] attributes = testMethodInfo.TestMethod.GetCustomAttributes(typeof(TestPropertyAttribute), false); + IEnumerable attributes = _reflectionHelper.GetDerivedAttributes(testMethodInfo.TestMethod, inherit: true); DebugEx.Assert(attributes != null, "attributes is null"); - foreach (TestPropertyAttribute attribute in attributes.Cast()) + if (testMethodInfo.TestMethod.DeclaringType is { } testClass) + { + attributes = attributes.Concat(_reflectionHelper.GetDerivedAttributes(testClass, inherit: true)); + } + + foreach (TestPropertyAttribute attribute in attributes) { if (!ValidateAndAssignTestProperty(testMethodInfo, testContext, attribute.Name, attribute.Value)) { diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index 340da1a1ae..9c6a8093b0 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -379,6 +379,11 @@ internal virtual IEnumerable GetTestPropertiesAsTraits(MemberInfo testPro { IEnumerable testPropertyAttributes = GetDerivedAttributes(testPropertyProvider, inherit: true); + if (testPropertyProvider.DeclaringType is { } testClass) + { + testPropertyAttributes = testPropertyAttributes.Concat(GetDerivedAttributes(testClass, inherit: true)); + } + foreach (TestPropertyAttribute testProperty in testPropertyAttributes) { var testPropertyPair = new Trait(testProperty.Name, testProperty.Value); diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TestPropertyAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TestPropertyAttribute.cs index 89d61dd3fe..522f6ed906 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/TestPropertyAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TestPropertyAttribute.cs @@ -6,7 +6,7 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// /// The test property attribute. /// -[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] +[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = true)] public class TestPropertyAttribute : Attribute { /// diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestPropertyAttributeTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestPropertyAttributeTests.cs new file mode 100644 index 0000000000..36e5736182 --- /dev/null +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestPropertyAttributeTests.cs @@ -0,0 +1,204 @@ +// 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.VisualStudio.TestPlatform.MSTest.TestAdapter; +using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; +using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; +using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.TestableImplementations; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +using Moq; + +using TestFramework.ForTestingMSTest; + +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution; + +public class TestPropertyAttributeTests : TestContainer +{ + private readonly TypeCache _typeCache; + + public TestPropertyAttributeTests() + { + _typeCache = new TypeCache(new ReflectHelper()); + var testablePlatformServiceProvider = new TestablePlatformServiceProvider(); + testablePlatformServiceProvider.MockFileOperations.Setup(x => x.LoadAssembly(It.IsAny(), It.IsAny())).Returns(GetType().Assembly); + PlatformServiceProvider.Instance = testablePlatformServiceProvider; + + ReflectHelper.Instance.ClearCache(); + } + + protected override void Dispose(bool disposing) + { + if (!IsDisposed) + { + base.Dispose(disposing); + PlatformServiceProvider.Instance = null; + MSTestSettings.Reset(); + } + } + + #region GetTestMethodInfo tests + + public void GetTestMethodInfoShouldAddPropertiesFromContainingClassCorrectly() + { + string className = typeof(DummyTestClassBase).FullName; + var testMethod = new TestMethod(nameof(DummyTestClassBase.VirtualTestMethodInBaseAndDerived), className, typeof(DummyTestClassBase).Assembly.GetName().Name, isAsync: false); + + var testContext = new TestContextImplementation(testMethod, new StringWriter(), new Dictionary()); + + _ = _typeCache.GetTestMethodInfo( + testMethod, + testContext, + false); + + Assert.IsTrue(testContext.TryGetPropertyValue("TestMethodKeyFromBase", out object value1)); + Assert.AreEqual("TestMethodValueFromBase", value1); + + Assert.IsTrue(testContext.TryGetPropertyValue("DummyTestClassBaseKey1", out object value2)); + Assert.AreEqual("DummyTestClassBaseValue1", value2); + + Assert.IsTrue(testContext.TryGetPropertyValue("DummyTestClassBaseKey2", out object value3)); + Assert.AreEqual("DummyTestClassBaseValue2", value3); + + TestPlatform.ObjectModel.Trait[] traits = ReflectHelper.Instance.GetTestPropertiesAsTraits(typeof(DummyTestClassBase).GetMethod(nameof(DummyTestClassBase.VirtualTestMethodInBaseAndDerived))).ToArray(); + Assert.AreEqual(3, traits.Length); + Assert.AreEqual("TestMethodKeyFromBase", traits[0].Name); + Assert.AreEqual("TestMethodValueFromBase", traits[0].Value); + Assert.AreEqual("DummyTestClassBaseKey1", traits[1].Name); + Assert.AreEqual("DummyTestClassBaseValue1", traits[1].Value); + Assert.AreEqual("DummyTestClassBaseKey2", traits[2].Name); + Assert.AreEqual("DummyTestClassBaseValue2", traits[2].Value); + } + + public void GetTestMethodInfoShouldAddPropertiesFromContainingClassAndBaseClassesAndOverriddenMethodsCorrectly_OverriddenIsTestMethod() + { + string className = typeof(DummyTestClassDerived).FullName; + var testMethod = new TestMethod(nameof(DummyTestClassDerived.VirtualTestMethodInBaseAndDerived), className, typeof(DummyTestClassBase).Assembly.GetName().Name, isAsync: false); + + var testContext = new TestContextImplementation(testMethod, new StringWriter(), new Dictionary()); + + _ = _typeCache.GetTestMethodInfo( + testMethod, + testContext, + false); + + Assert.IsTrue(testContext.TryGetPropertyValue("DerivedMethod1Key", out object value1)); + Assert.AreEqual("DerivedMethod1Value", value1); + + Assert.IsTrue(testContext.TryGetPropertyValue("TestMethodKeyFromBase", out object value2)); + Assert.AreEqual("TestMethodValueFromBase", value2); + + Assert.IsTrue(testContext.TryGetPropertyValue("DummyTestClassDerivedKey1", out object value3)); + Assert.AreEqual("DummyTestClassValue1", value3); + + Assert.IsTrue(testContext.TryGetPropertyValue("DummyTestClassDerivedKey2", out object value4)); + Assert.AreEqual("DummyTestClassValue2", value4); + + Assert.IsTrue(testContext.TryGetPropertyValue("DummyTestClassBaseKey1", out object value5)); + Assert.AreEqual("DummyTestClassBaseValue1", value5); + + Assert.IsTrue(testContext.TryGetPropertyValue("DummyTestClassBaseKey2", out object value6)); + Assert.AreEqual("DummyTestClassBaseValue2", value6); + + TestPlatform.ObjectModel.Trait[] traits = ReflectHelper.Instance.GetTestPropertiesAsTraits(typeof(DummyTestClassDerived).GetMethod(nameof(DummyTestClassDerived.VirtualTestMethodInBaseAndDerived))).ToArray(); + Assert.AreEqual(6, traits.Length); + Assert.AreEqual("DerivedMethod1Key", traits[0].Name); + Assert.AreEqual("DerivedMethod1Value", traits[0].Value); + Assert.AreEqual("TestMethodKeyFromBase", traits[1].Name); + Assert.AreEqual("TestMethodValueFromBase", traits[1].Value); + Assert.AreEqual("DummyTestClassDerivedKey1", traits[2].Name); + Assert.AreEqual("DummyTestClassValue1", traits[2].Value); + Assert.AreEqual("DummyTestClassDerivedKey2", traits[3].Name); + Assert.AreEqual("DummyTestClassValue2", traits[3].Value); + Assert.AreEqual("DummyTestClassBaseKey1", traits[4].Name); + Assert.AreEqual("DummyTestClassBaseValue1", traits[4].Value); + Assert.AreEqual("DummyTestClassBaseKey2", traits[5].Name); + Assert.AreEqual("DummyTestClassBaseValue2", traits[5].Value); + } + + public void GetTestMethodInfoShouldAddPropertiesFromContainingClassAndBaseClassesAndOverriddenMethodsCorrectly_OverriddenIsNotTestMethod() + { + string className = typeof(DummyTestClassDerived).FullName; + var testMethod = new TestMethod(nameof(DummyTestClassDerived.VirtualTestMethodInDerivedButNotTestMethodInBase), className, typeof(DummyTestClassBase).Assembly.GetName().Name, isAsync: false); + + var testContext = new TestContextImplementation(testMethod, new StringWriter(), new Dictionary()); + + _ = _typeCache.GetTestMethodInfo( + testMethod, + testContext, + false); + + Assert.IsTrue(testContext.TryGetPropertyValue("DerivedMethod2Key", out object value1)); + Assert.AreEqual("DerivedMethod2Value", value1); + + Assert.IsTrue(testContext.TryGetPropertyValue("NonTestMethodKeyFromBase", out object value2)); + Assert.AreEqual("NonTestMethodValueFromBase", value2); + + Assert.IsTrue(testContext.TryGetPropertyValue("DummyTestClassDerivedKey1", out object value3)); + Assert.AreEqual("DummyTestClassValue1", value3); + + Assert.IsTrue(testContext.TryGetPropertyValue("DummyTestClassDerivedKey2", out object value4)); + Assert.AreEqual("DummyTestClassValue2", value4); + + Assert.IsTrue(testContext.TryGetPropertyValue("DummyTestClassBaseKey1", out object value5)); + Assert.AreEqual("DummyTestClassBaseValue1", value5); + + Assert.IsTrue(testContext.TryGetPropertyValue("DummyTestClassBaseKey2", out object value6)); + Assert.AreEqual("DummyTestClassBaseValue2", value6); + + TestPlatform.ObjectModel.Trait[] traits = ReflectHelper.Instance.GetTestPropertiesAsTraits(typeof(DummyTestClassDerived).GetMethod(nameof(DummyTestClassDerived.VirtualTestMethodInDerivedButNotTestMethodInBase))).ToArray(); + Assert.AreEqual(6, traits.Length); + Assert.AreEqual("DerivedMethod2Key", traits[0].Name); + Assert.AreEqual("DerivedMethod2Value", traits[0].Value); + Assert.AreEqual("NonTestMethodKeyFromBase", traits[1].Name); + Assert.AreEqual("NonTestMethodValueFromBase", traits[1].Value); + Assert.AreEqual("DummyTestClassDerivedKey1", traits[2].Name); + Assert.AreEqual("DummyTestClassValue1", traits[2].Value); + Assert.AreEqual("DummyTestClassDerivedKey2", traits[3].Name); + Assert.AreEqual("DummyTestClassValue2", traits[3].Value); + Assert.AreEqual("DummyTestClassBaseKey1", traits[4].Name); + Assert.AreEqual("DummyTestClassBaseValue1", traits[4].Value); + Assert.AreEqual("DummyTestClassBaseKey2", traits[5].Name); + Assert.AreEqual("DummyTestClassBaseValue2", traits[5].Value); + } + + #endregion + #region dummy implementations + + [TestClass] + [TestProperty("DummyTestClassBaseKey1", "DummyTestClassBaseValue1")] + [TestProperty("DummyTestClassBaseKey2", "DummyTestClassBaseValue2")] + internal class DummyTestClassBase + { + public TestContext TestContext { get; set; } + + [TestMethod] + [TestProperty("TestMethodKeyFromBase", "TestMethodValueFromBase")] + public virtual void VirtualTestMethodInBaseAndDerived() + { + } + + [TestProperty("NonTestMethodKeyFromBase", "NonTestMethodValueFromBase")] + public virtual void VirtualTestMethodInDerivedButNotTestMethodInBase() + { + } + } + + [TestClass] + [TestProperty("DummyTestClassDerivedKey1", "DummyTestClassValue1")] + [TestProperty("DummyTestClassDerivedKey2", "DummyTestClassValue2")] + internal class DummyTestClassDerived : DummyTestClassBase + { + [TestProperty("DerivedMethod1Key", "DerivedMethod1Value")] + [TestMethod] + public override void VirtualTestMethodInBaseAndDerived() => base.VirtualTestMethodInBaseAndDerived(); + + [TestProperty("DerivedMethod2Key", "DerivedMethod2Value")] + [TestMethod] + public override void VirtualTestMethodInDerivedButNotTestMethodInBase() => base.VirtualTestMethodInDerivedButNotTestMethodInBase(); + } + + #endregion +} diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs index ffbc102efc..7aee7107a5 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs @@ -1031,6 +1031,9 @@ public void GetTestMethodInfoShouldReturnTestMethodInfoForMethodsAdornedWithADer public void GetTestMethodInfoShouldSetTestContextWithCustomProperty() { + // Not using _typeCache here which uses a mocked ReflectHelper which doesn't work well with this test. + // Setting up the mock feels unnecessary when the original production implementation can work just fine. + var typeCache = new TypeCache(new ReflectHelper()); Type type = typeof(DummyTestClassWithTestMethods); MethodInfo methodInfo = type.GetMethod("TestMethodWithCustomProperty"); var testMethod = new TestMethod(methodInfo.Name, type.FullName, "A", isAsync: false); @@ -1039,7 +1042,7 @@ public void GetTestMethodInfoShouldSetTestContextWithCustomProperty() new ThreadSafeStringWriter(null, "test"), new Dictionary()); - _typeCache.GetTestMethodInfo(testMethod, testContext, false); + typeCache.GetTestMethodInfo(testMethod, testContext, false); KeyValuePair customProperty = ((IDictionary)testContext.Properties).FirstOrDefault(p => p.Key.Equals("WhoAmI", StringComparison.Ordinal)); Verify((object)customProperty is not null); @@ -1048,6 +1051,9 @@ public void GetTestMethodInfoShouldSetTestContextWithCustomProperty() public void GetTestMethodInfoShouldReportWarningIfCustomPropertyHasSameNameAsPredefinedProperties() { + // Not using _typeCache here which uses a mocked ReflectHelper which doesn't work well with this test. + // Setting up the mock feels unnecessary when the original production implementation can work just fine. + var typeCache = new TypeCache(new ReflectHelper()); Type type = typeof(DummyTestClassWithTestMethods); MethodInfo methodInfo = type.GetMethod("TestMethodWithOwnerAsCustomProperty"); var testMethod = new TestMethod(methodInfo.Name, type.FullName, "A", isAsync: false); @@ -1056,7 +1062,7 @@ public void GetTestMethodInfoShouldReportWarningIfCustomPropertyHasSameNameAsPre new ThreadSafeStringWriter(null, "test"), new Dictionary()); - TestMethodInfo testMethodInfo = _typeCache.GetTestMethodInfo(testMethod, testContext, false); + TestMethodInfo testMethodInfo = typeCache.GetTestMethodInfo(testMethod, testContext, false); Verify(testMethodInfo is not null); string expectedMessage = string.Format( @@ -1070,6 +1076,9 @@ public void GetTestMethodInfoShouldReportWarningIfCustomPropertyHasSameNameAsPre public void GetTestMethodInfoShouldReportWarningIfCustomPropertyNameIsEmpty() { + // Not using _typeCache here which uses a mocked ReflectHelper which doesn't work well with this test. + // Setting up the mock feels unnecessary when the original production implementation can work just fine. + var typeCache = new TypeCache(new ReflectHelper()); Type type = typeof(DummyTestClassWithTestMethods); MethodInfo methodInfo = type.GetMethod("TestMethodWithEmptyCustomPropertyName"); var testMethod = new TestMethod(methodInfo.Name, type.FullName, "A", isAsync: false); @@ -1078,7 +1087,7 @@ public void GetTestMethodInfoShouldReportWarningIfCustomPropertyNameIsEmpty() new ThreadSafeStringWriter(null, "test"), new Dictionary()); - TestMethodInfo testMethodInfo = _typeCache.GetTestMethodInfo(testMethod, testContext, false); + TestMethodInfo testMethodInfo = typeCache.GetTestMethodInfo(testMethod, testContext, false); Verify(testMethodInfo is not null); string expectedMessage = string.Format( @@ -1091,6 +1100,9 @@ public void GetTestMethodInfoShouldReportWarningIfCustomPropertyNameIsEmpty() public void GetTestMethodInfoShouldReportWarningIfCustomPropertyNameIsNull() { + // Not using _typeCache here which uses a mocked ReflectHelper which doesn't work well with this test. + // Setting up the mock feels unnecessary when the original production implementation can work just fine. + var typeCache = new TypeCache(new ReflectHelper()); Type type = typeof(DummyTestClassWithTestMethods); MethodInfo methodInfo = type.GetMethod("TestMethodWithNullCustomPropertyName"); var testMethod = new TestMethod(methodInfo.Name, type.FullName, "A", isAsync: false); @@ -1099,7 +1111,7 @@ public void GetTestMethodInfoShouldReportWarningIfCustomPropertyNameIsNull() new ThreadSafeStringWriter(null, "test"), new Dictionary()); - TestMethodInfo testMethodInfo = _typeCache.GetTestMethodInfo(testMethod, testContext, false); + TestMethodInfo testMethodInfo = typeCache.GetTestMethodInfo(testMethod, testContext, false); Verify(testMethodInfo is not null); string expectedMessage = string.Format( @@ -1112,6 +1124,9 @@ public void GetTestMethodInfoShouldReportWarningIfCustomPropertyNameIsNull() public void GetTestMethodInfoShouldNotAddDuplicateTestPropertiesToTestContext() { + // Not using _typeCache here which uses a mocked ReflectHelper which doesn't work well with this test. + // Setting up the mock feels unnecessary when the original production implementation can work just fine. + var typeCache = new TypeCache(new ReflectHelper()); Type type = typeof(DummyTestClassWithTestMethods); MethodInfo methodInfo = type.GetMethod("TestMethodWithDuplicateCustomPropertyNames"); var testMethod = new TestMethod(methodInfo.Name, type.FullName, "A", isAsync: false); @@ -1120,7 +1135,7 @@ public void GetTestMethodInfoShouldNotAddDuplicateTestPropertiesToTestContext() new ThreadSafeStringWriter(null, "test"), new Dictionary()); - TestMethodInfo testMethodInfo = _typeCache.GetTestMethodInfo(testMethod, testContext, false); + TestMethodInfo testMethodInfo = typeCache.GetTestMethodInfo(testMethod, testContext, false); Verify(testMethodInfo is not null); From ab879c4d4a92774df5658be63d8a7bbf9687aeda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 10 Dec 2024 20:21:19 +0100 Subject: [PATCH 093/273] Refactor GetResultOrRunClassInitialize to have clearer intent (#4306) --- .../Execution/TestClassInfo.cs | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index 07423c3608..1d94f393f8 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -29,6 +29,8 @@ public class TestClassInfo { private readonly Lock _testClassExecuteSyncObject = new(); + private UnitTestResult? _cachedClassInitializeResult; + /// /// Initializes a new instance of the class. /// @@ -353,10 +355,15 @@ internal UnitTestResult GetResultOrRunClassInitialize(ITestContext testContext, { // For optimization purposes, we duplicate some of the logic of RunClassInitialize here so we don't need to start // a thread for nothing. - if ((ClassInitializeMethod is null && BaseClassInitMethods.Count == 0) - || IsClassInitializeExecuted) + if (ClassInitializeMethod is null && BaseClassInitMethods.Count == 0) { - return DoRun(); + return new() { Outcome = ObjectModelUnitTestOutcome.Passed }; + } + + if (IsClassInitializeExecuted) + { + DebugEx.Assert(_cachedClassInitializeResult is not null, "If class init was called, we should have cached the result."); + return _cachedClassInitializeResult; } UnitTestResult result = new(ObjectModelUnitTestOutcome.Error, "MSTest STATestClass ClassInitialize didn't complete"); @@ -371,6 +378,7 @@ internal UnitTestResult GetResultOrRunClassInitialize(ITestContext testContext, try { entryPointThread.Join(); + _cachedClassInitializeResult = result; return result; } catch (Exception ex) @@ -387,7 +395,9 @@ internal UnitTestResult GetResultOrRunClassInitialize(ITestContext testContext, PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning(Resource.STAIsOnlySupportedOnWindowsWarning); } - return DoRun(); + UnitTestResult result = DoRun(); + _cachedClassInitializeResult = result; + return result; } // Local functions From 056912d997c109a0f63f6a56ce677a1bec7e7b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Tue, 10 Dec 2024 21:42:27 +0100 Subject: [PATCH 094/273] Enroll Testing.Platform project to source build (#4295) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- Directory.Build.targets | 8 +++- azure-pipelines.yml | 1 + eng/Analyzers.props | 3 +- eng/Build.props | 69 ++++++++++++++++------------- eng/DotNetBuild.props | 10 +++++ eng/SourceBuildPrebuiltBaseline.xml | 9 ++++ eng/Version.Details.xml | 24 ++++++++++ 7 files changed, 92 insertions(+), 32 deletions(-) create mode 100644 eng/DotNetBuild.props create mode 100644 eng/SourceBuildPrebuiltBaseline.xml diff --git a/Directory.Build.targets b/Directory.Build.targets index 4220fbc3f6..a64f4a9190 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -10,5 +10,11 @@ 14.0.0.0 14.0.0.0 - + + + + $(NetCurrent) + diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7864d89bee..224aee03bd 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -48,6 +48,7 @@ stages: enablePublishBuildAssets: true enablePublishUsingPipelines: true enableTelemetry: true + enableSourceBuild: true jobs: - job: Windows timeoutInMinutes: 90 diff --git a/eng/Analyzers.props b/eng/Analyzers.props index e1bae4dd9e..a9699b919e 100644 --- a/eng/Analyzers.props +++ b/eng/Analyzers.props @@ -7,7 +7,8 @@ true - + + diff --git a/eng/Build.props b/eng/Build.props index 57aac3a459..5cd34c03f1 100644 --- a/eng/Build.props +++ b/eng/Build.props @@ -4,38 +4,47 @@ all - - - - + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/eng/DotNetBuild.props b/eng/DotNetBuild.props new file mode 100644 index 0000000000..f4d2580ef8 --- /dev/null +++ b/eng/DotNetBuild.props @@ -0,0 +1,10 @@ + + + + + + testfx + true + + + diff --git a/eng/SourceBuildPrebuiltBaseline.xml b/eng/SourceBuildPrebuiltBaseline.xml new file mode 100644 index 0000000000..1b37a10db6 --- /dev/null +++ b/eng/SourceBuildPrebuiltBaseline.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ea277e2c53..a8a58245c4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -25,5 +25,29 @@ https://github.com/microsoft/testanywhere aa2fcc8616d988b234bc1d218465b20c56d0b82f + + + https://github.com/dotnet/diagnostics + 8c505ca6921b5f7e9b8acc234cc8f15035537ee4 + + + + + https://github.com/dotnet/source-build-externals + 4df883d781a4290873b3b968afc0ff0df7132507 + + + + + https://github.com/dotnet/source-build-reference-packages + 94798e07efab2663f2d1a71862780bc365d2e3ab + + + + + https://github.com/dotnet/arcade + 45d845e04c05fbe5da9838c454bbc3af1df6be81 + + From 6aa77155bf533e53f43eeb11e30fd79a25aa6129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 10 Dec 2024 22:05:44 +0100 Subject: [PATCH 095/273] =?UTF-8?q?Revert=20"Refactor=20GetResultOrRunClas?= =?UTF-8?q?sInitialize=20to=20have=20clearer=20intent=E2=80=A6=20(#4311)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Execution/TestClassInfo.cs | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index 1d94f393f8..07423c3608 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -29,8 +29,6 @@ public class TestClassInfo { private readonly Lock _testClassExecuteSyncObject = new(); - private UnitTestResult? _cachedClassInitializeResult; - /// /// Initializes a new instance of the class. /// @@ -355,15 +353,10 @@ internal UnitTestResult GetResultOrRunClassInitialize(ITestContext testContext, { // For optimization purposes, we duplicate some of the logic of RunClassInitialize here so we don't need to start // a thread for nothing. - if (ClassInitializeMethod is null && BaseClassInitMethods.Count == 0) + if ((ClassInitializeMethod is null && BaseClassInitMethods.Count == 0) + || IsClassInitializeExecuted) { - return new() { Outcome = ObjectModelUnitTestOutcome.Passed }; - } - - if (IsClassInitializeExecuted) - { - DebugEx.Assert(_cachedClassInitializeResult is not null, "If class init was called, we should have cached the result."); - return _cachedClassInitializeResult; + return DoRun(); } UnitTestResult result = new(ObjectModelUnitTestOutcome.Error, "MSTest STATestClass ClassInitialize didn't complete"); @@ -378,7 +371,6 @@ internal UnitTestResult GetResultOrRunClassInitialize(ITestContext testContext, try { entryPointThread.Join(); - _cachedClassInitializeResult = result; return result; } catch (Exception ex) @@ -395,9 +387,7 @@ internal UnitTestResult GetResultOrRunClassInitialize(ITestContext testContext, PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning(Resource.STAIsOnlySupportedOnWindowsWarning); } - UnitTestResult result = DoRun(); - _cachedClassInitializeResult = result; - return result; + return DoRun(); } // Local functions From 19b63cda6324e8d0e751b74a4c8f799f5b823b2d Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 11 Dec 2024 09:30:22 +0100 Subject: [PATCH 096/273] Avoid dictionary resizes when the size is approximately known (#4313) --- .../MSTest.TestAdapter/Execution/TestExecutionManager.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs index 9df21eb37a..dc8c9171e6 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs @@ -486,7 +486,9 @@ private void ExecuteTestsWithTestRunner( IDictionary tcmProperties, IDictionary sourceLevelParameters) { - var testContextProperties = new Dictionary(); + // This dictionary will have *at least* 8 entries. Those are the sourceLevelParameters + // which were originally calculated from TestDeployment.GetDeploymentInformation. + var testContextProperties = new Dictionary(capacity: 8); // Add tcm properties. foreach (KeyValuePair propertyPair in tcmProperties) From 17e322a0486a6ea30d49dc303bea82c2166458ac Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 11 Dec 2024 09:51:19 +0100 Subject: [PATCH 097/273] Support '--maximum-failed-tests' to abort test run when failure threshold is reached (#4238) --- .../Execution/ClassCleanupManager.cs | 15 ++ .../Execution/TestClassInfo.cs | 7 +- .../Execution/TestExecutionManager.cs | 9 + .../Execution/UnitTestRunner.cs | 3 + ...TestGracefulStopTestExecutionCapability.cs | 25 +++ .../TestApplicationBuilderExtensions.cs | 7 +- .../IGracefulStopTestExecutionCapability.cs | 19 ++ ...axFailedTestsCommandLineOptionsProvider.cs | 53 ++++++ .../AbortForMaxFailedTestsExtension.cs | 76 ++++++++ .../Helpers/ExitCodes.cs | 1 + .../TestApplicationBuilderExtensions.cs | 8 + .../Hosts/TestHostBuilder.cs | 25 ++- .../OutputDevice/IPlatformOutputDevice.cs | 2 + .../OutputDevice/OutputDeviceManager.cs | 8 +- .../OutputDevice/ProxyOutputDevice.cs | 9 + .../OutputDevice/TerminalOutputDevice.cs | 28 ++- .../OutputDevice/TestProcessRole.cs | 22 +++ .../PublicAPI/PublicAPI.Unshipped.txt | 2 + .../Resources/PlatformResources.resx | 15 +- .../Resources/xlf/PlatformResources.cs.xlf | 20 +++ .../Resources/xlf/PlatformResources.de.xlf | 20 +++ .../Resources/xlf/PlatformResources.es.xlf | 20 +++ .../Resources/xlf/PlatformResources.fr.xlf | 20 +++ .../Resources/xlf/PlatformResources.it.xlf | 20 +++ .../Resources/xlf/PlatformResources.ja.xlf | 20 +++ .../Resources/xlf/PlatformResources.ko.xlf | 20 +++ .../Resources/xlf/PlatformResources.pl.xlf | 20 +++ .../Resources/xlf/PlatformResources.pt-BR.xlf | 20 +++ .../Resources/xlf/PlatformResources.ru.xlf | 20 +++ .../Resources/xlf/PlatformResources.tr.xlf | 20 +++ .../xlf/PlatformResources.zh-Hans.xlf | 20 +++ .../xlf/PlatformResources.zh-Hant.xlf | 20 +++ .../JsonRpc/ServerModePerCallOutputDevice.cs | 24 ++- .../Services/IStopPoliciesService.cs | 19 ++ .../Services/StopPoliciesService.cs | 95 ++++++++++ .../Services/TestApplicationResult.cs | 29 +-- .../HelpInfoTests.cs | 6 + .../MaxFailedTestsExtensionTests.cs | 154 ++++++++++++++++ .../MaxFailedTestsExtensionTests.cs | 167 ++++++++++++++++++ .../Execution/TestClassInfoTests.cs | 22 +++ .../Services/TestApplicationResultTests.cs | 40 +++-- 41 files changed, 1105 insertions(+), 45 deletions(-) create mode 100644 src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestGracefulStopTestExecutionCapability.cs create mode 100644 src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IGracefulStopTestExecutionCapability.cs create mode 100644 src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs create mode 100644 src/Platform/Microsoft.Testing.Platform/Extensions/AbortForMaxFailedTestsExtension.cs create mode 100644 src/Platform/Microsoft.Testing.Platform/OutputDevice/TestProcessRole.cs create mode 100644 src/Platform/Microsoft.Testing.Platform/Services/IStopPoliciesService.cs create mode 100644 src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs create mode 100644 test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs create mode 100644 test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs diff --git a/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs index 8f6d5d75f2..6cd4c78279 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs @@ -62,4 +62,19 @@ public void MarkTestComplete(TestMethodInfo testMethodInfo, TestMethod testMetho ShouldRunEndOfAssemblyCleanup = _remainingTestsByClass.IsEmpty; } } + + internal static void ForceCleanup(TypeCache typeCache) + { + IEnumerable classInfoCache = typeCache.ClassInfoListWithExecutableCleanupMethods; + foreach (TestClassInfo classInfo in classInfoCache) + { + classInfo.ExecuteClassCleanup(); + } + + IEnumerable assemblyInfoCache = typeCache.AssemblyInfoListWithExecutableCleanupMethods; + foreach (TestAssemblyInfo assemblyInfo in assemblyInfoCache) + { + assemblyInfo.ExecuteAssemblyCleanup(); + } + } } diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index 07423c3608..fe29c5998e 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -252,6 +252,7 @@ public void RunClassInitialize(TestContext testContext) // If no class initialize and no base class initialize, return if (ClassInitializeMethod is null && BaseClassInitMethods.Count == 0) { + IsClassInitializeExecuted = true; return; } @@ -558,8 +559,10 @@ internal void ExecuteClassCleanup() lock (_testClassExecuteSyncObject) { if (IsClassCleanupExecuted - // If there is a ClassInitialize method and it has not been executed, then we should not execute ClassCleanup - || (!IsClassInitializeExecuted && ClassInitializeMethod is not null)) + // If ClassInitialize method has not been executed, then we should not execute ClassCleanup + // Note that if there is no ClassInitialze method at all, we will still set + // IsClassInitializeExecuted to true in RunClassInitialize + || !IsClassInitializeExecuted) { return; } diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs index dc8c9171e6..b8af1f04b5 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs @@ -399,6 +399,11 @@ private void ExecuteTestsInSource(IEnumerable tests, IRunContext? runC ExecuteTestsWithTestRunner(testsToRun, frameworkHandle, source, sourceLevelParameters, testRunner); } + if (MSTestGracefulStopTestExecutionCapability.Instance.IsStopRequested) + { + testRunner.ForceCleanup(); + } + PlatformServiceProvider.Instance.AdapterTraceLogger.LogInfo("Executed tests belonging to source {0}", source); } @@ -419,6 +424,10 @@ private void ExecuteTestsWithTestRunner( foreach (TestCase currentTest in orderedTests) { _testRunCancellationToken?.ThrowIfCancellationRequested(); + if (MSTestGracefulStopTestExecutionCapability.Instance.IsStopRequested) + { + break; + } // If it is a fixture test, add it to the list of fixture tests and do not execute it. // It is executed by test itself. diff --git a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs index 174155f9aa..6d6e854add 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs @@ -169,6 +169,7 @@ internal UnitTestResult[] RunSingleTest(TestMethod testMethod, IDictionary ClassCleanupManager.ForceCleanup(_typeCache); } diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestGracefulStopTestExecutionCapability.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestGracefulStopTestExecutionCapability.cs new file mode 100644 index 0000000000..a8ef89ff47 --- /dev/null +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestGracefulStopTestExecutionCapability.cs @@ -0,0 +1,25 @@ +// 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.Testing.Platform.Capabilities.TestFramework; + +namespace Microsoft.VisualStudio.TestTools.UnitTesting; + +#pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. +internal sealed class MSTestGracefulStopTestExecutionCapability : IGracefulStopTestExecutionCapability +#pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. +{ + private MSTestGracefulStopTestExecutionCapability() + { + } + + public static MSTestGracefulStopTestExecutionCapability Instance { get; } = new(); + + public bool IsStopRequested { get; private set; } + + public Task StopTestExecutionAsync(CancellationToken cancellationToken) + { + IsStopRequested = true; + return Task.CompletedTask; + } +} diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs index 2a86adaf09..3cb51f0732 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs @@ -8,6 +8,7 @@ using Microsoft.Testing.Extensions.VSTestBridge.Helpers; using Microsoft.Testing.Platform.Builder; using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Services; namespace Microsoft.VisualStudio.TestTools.UnitTesting; @@ -20,12 +21,16 @@ public static void AddMSTest(this ITestApplicationBuilder testApplicationBuilder testApplicationBuilder.AddRunSettingsService(extension); testApplicationBuilder.AddTestCaseFilterService(extension); testApplicationBuilder.AddTestRunParametersService(extension); +#pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + testApplicationBuilder.AddMaximumFailedTestsService(extension); +#pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. testApplicationBuilder.AddRunSettingsEnvironmentVariableProvider(extension); testApplicationBuilder.RegisterTestFramework( serviceProvider => new TestFrameworkCapabilities( new VSTestBridgeExtensionBaseCapabilities(), #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. - new MSTestBannerCapability(serviceProvider.GetRequiredService())), + new MSTestBannerCapability(serviceProvider.GetRequiredService()), + MSTestGracefulStopTestExecutionCapability.Instance), #pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. (capabilities, serviceProvider) => new MSTestBridgedTestFramework(extension, getTestAssemblies, serviceProvider, capabilities)); } diff --git a/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IGracefulStopTestExecutionCapability.cs b/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IGracefulStopTestExecutionCapability.cs new file mode 100644 index 0000000000..ee8a92dee3 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IGracefulStopTestExecutionCapability.cs @@ -0,0 +1,19 @@ +// 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.Diagnostics.CodeAnalysis; + +namespace Microsoft.Testing.Platform.Capabilities.TestFramework; + +/// +/// A capability to support stopping test execution gracefully, without cancelling/aborting everything. +/// This is used to support '--maximum-failed-tests'. +/// +/// +/// Test frameworks can choose to run any needed cleanup when cancellation is requested. +/// +[Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")] +public interface IGracefulStopTestExecutionCapability : ITestFrameworkCapability +{ + Task StopTestExecutionAsync(CancellationToken cancellationToken); +} diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs new file mode 100644 index 0000000000..e81cc907b7 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs @@ -0,0 +1,53 @@ +// 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.Globalization; + +using Microsoft.Testing.Platform.Extensions; +using Microsoft.Testing.Platform.Extensions.CommandLine; +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.Resources; + +namespace Microsoft.Testing.Platform.CommandLine; + +internal sealed class MaxFailedTestsCommandLineOptionsProvider(IExtension extension) : ICommandLineOptionsProvider +{ + internal const string MaxFailedTestsOptionKey = "maximum-failed-tests"; + + private static readonly IReadOnlyCollection OptionsCache = + [ + new(MaxFailedTestsOptionKey, PlatformResources.PlatformCommandLineMaxFailedTestsOptionDescription, ArgumentArity.ExactlyOne, isHidden: false), + ]; + + public string Uid => extension.Uid; + + public string Version => extension.Version; + + public string DisplayName => extension.DisplayName; + + public string Description => extension.Description; + + public IReadOnlyCollection GetCommandLineOptions() + => OptionsCache; + + public Task IsEnabledAsync() => Task.FromResult(true); + + public Task ValidateCommandLineOptionsAsync(ICommandLineOptions commandLineOptions) + => ValidationResult.ValidTask; + + public Task ValidateOptionArgumentsAsync(CommandLineOption commandOption, string[] arguments) + { + if (commandOption.Name == MaxFailedTestsOptionKey) + { + string arg = arguments[0]; + // We consider --maximum-failed-tests 0 as invalid. + // The idea is that we stop the execution when we *reach* the max failed tests, not when *exceed*. + // So the value 1 means, stop execution on the first failure. + return int.TryParse(arg, out int maxFailedTestsResult) && maxFailedTestsResult > 0 + ? ValidationResult.ValidTask + : ValidationResult.InvalidTask(string.Format(CultureInfo.InvariantCulture, PlatformResources.MaxFailedTestsMustBePositive, arg)); + } + + throw ApplicationStateGuard.Unreachable(); + } +} diff --git a/src/Platform/Microsoft.Testing.Platform/Extensions/AbortForMaxFailedTestsExtension.cs b/src/Platform/Microsoft.Testing.Platform/Extensions/AbortForMaxFailedTestsExtension.cs new file mode 100644 index 0000000000..78e4999b3c --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/Extensions/AbortForMaxFailedTestsExtension.cs @@ -0,0 +1,76 @@ +// 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.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.CommandLine; +using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Extensions.TestHost; +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.Messages; +using Microsoft.Testing.Platform.Resources; +using Microsoft.Testing.Platform.Services; + +namespace Microsoft.Testing.Platform.Extensions; + +internal sealed class AbortForMaxFailedTestsExtension : IDataConsumer +{ + private readonly int? _maxFailedTests; + private readonly IGracefulStopTestExecutionCapability? _capability; + private readonly IStopPoliciesService _policiesService; + private readonly ITestApplicationCancellationTokenSource _testApplicationCancellationTokenSource; + private int _failCount; + + public AbortForMaxFailedTestsExtension( + ICommandLineOptions commandLineOptions, + IGracefulStopTestExecutionCapability? capability, + IStopPoliciesService policiesService, + ITestApplicationCancellationTokenSource testApplicationCancellationTokenSource) + { + if (commandLineOptions.TryGetOptionArgumentList(MaxFailedTestsCommandLineOptionsProvider.MaxFailedTestsOptionKey, out string[]? args) && + int.TryParse(args[0], out int maxFailedTests) && + maxFailedTests > 0) + { + _maxFailedTests = maxFailedTests; + } + + _capability = capability; + _policiesService = policiesService; + _testApplicationCancellationTokenSource = testApplicationCancellationTokenSource; + } + + public Type[] DataTypesConsumed { get; } = [typeof(TestNodeUpdateMessage)]; + + /// + public string Uid { get; } = nameof(AbortForMaxFailedTestsExtension); + + /// + public string Version { get; } = AppVersion.DefaultSemVer; + + /// + public string DisplayName { get; } = nameof(AbortForMaxFailedTestsExtension); + + /// + public string Description { get; } = PlatformResources.AbortForMaxFailedTestsDescription; + + /// + public Task IsEnabledAsync() => Task.FromResult(_maxFailedTests.HasValue && _capability is not null); + + public async Task ConsumeAsync(IDataProducer dataProducer, IData value, CancellationToken cancellationToken) + { + var node = (TestNodeUpdateMessage)value; + + // If we are called, the extension is enabled, which means both _maxFailedTests and capability are not null. + RoslynDebug.Assert(_maxFailedTests is not null); + RoslynDebug.Assert(_capability is not null); + + TestNodeStateProperty testNodeStateProperty = node.TestNode.Properties.Single(); + if (TestNodePropertiesCategories.WellKnownTestNodeTestRunOutcomeFailedProperties.Any(t => t == testNodeStateProperty.GetType()) && + ++_failCount >= _maxFailedTests.Value && + // If already triggered, don't do it again. + !_policiesService.IsMaxFailedTestsTriggered) + { + await _capability.StopTestExecutionAsync(_testApplicationCancellationTokenSource.CancellationToken); + await _policiesService.ExecuteMaxFailedTestsCallbacksAsync(_maxFailedTests.Value, _testApplicationCancellationTokenSource.CancellationToken); + } + } +} diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/ExitCodes.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/ExitCodes.cs index 28514ae2c0..79e8fd0864 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/ExitCodes.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/ExitCodes.cs @@ -22,4 +22,5 @@ internal static class ExitCodes public const int TestAdapterTestSessionFailure = 10; public const int DependentProcessExited = 11; public const int IncompatibleProtocolVersion = 12; + public const int TestExecutionStoppedForMaxFailedTests = 13; } diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs index 512dc9e6a8..bae0af6c00 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs @@ -15,4 +15,12 @@ public static class TestApplicationBuilderExtensions { public static void AddTreeNodeFilterService(this ITestApplicationBuilder testApplicationBuilder, IExtension extension) => testApplicationBuilder.CommandLine.AddProvider(() => new TreeNodeFilterCommandLineOptionsProvider(extension)); + + /// + /// Registers the command-line options provider for '--maximum-failed-tests'. + /// + /// The test application builder. + [Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")] + public static void AddMaximumFailedTestsService(this ITestApplicationBuilder builder, IExtension extension) + => builder.CommandLine.AddProvider(() => new MaxFailedTestsCommandLineOptionsProvider(extension)); } diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs index 9b19eea139..b071f4fb9f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs @@ -206,6 +206,10 @@ public async Task BuildAsync( // Set the concrete command line options to the proxy. commandLineOptionsProxy.SetCommandLineOptions(commandLineHandler); + // This is needed by output device. + var policiesService = new StopPoliciesService(testApplicationCancellationTokenSource); + serviceProvider.AddService(policiesService); + bool hasServerFlag = commandLineHandler.TryGetOptionArgumentList(PlatformCommandLineProvider.ServerOptionKey, out string[]? protocolName); bool isJsonRpcProtocol = protocolName is null || protocolName.Length == 0 || protocolName[0].Equals(PlatformCommandLineProvider.JsonRpcProtocolName, StringComparison.OrdinalIgnoreCase); @@ -313,9 +317,9 @@ public async Task BuildAsync( // Register the ITestApplicationResult TestApplicationResult testApplicationResult = new( proxyOutputDevice, - serviceProvider.GetTestApplicationCancellationTokenSource(), serviceProvider.GetCommandLineOptions(), - serviceProvider.GetEnvironment()); + serviceProvider.GetEnvironment(), + policiesService); serviceProvider.AddService(testApplicationResult); // ============= SETUP COMMON SERVICE USED IN ALL MODES END ===============// @@ -376,6 +380,8 @@ await LogTestHostCreatedAsync( TestHostOrchestratorConfiguration testHostOrchestratorConfiguration = await TestHostOrchestratorManager.BuildAsync(serviceProvider); if (testHostOrchestratorConfiguration.TestHostOrchestrators.Length > 0 && !commandLineHandler.IsOptionSet(PlatformCommandLineProvider.DiscoverTestsOptionKey)) { + policiesService.ProcessRole = TestProcessRole.TestHostOrchestrator; + await proxyOutputDevice.HandleProcessRoleAsync(TestProcessRole.TestHostOrchestrator); return new TestHostOrchestratorHost(testHostOrchestratorConfiguration, serviceProvider); } @@ -411,6 +417,8 @@ await LogTestHostCreatedAsync( if (testHostControllers.RequireProcessRestart) { testHostControllerInfo.IsCurrentProcessTestHostController = true; + policiesService.ProcessRole = TestProcessRole.TestHostController; + await proxyOutputDevice.HandleProcessRoleAsync(TestProcessRole.TestHostController); TestHostControllersTestHost testHostControllersTestHost = new(testHostControllers, testHostControllersServiceProvider, passiveNode, systemEnvironment, loggerFactory, systemClock); await LogTestHostCreatedAsync( @@ -424,6 +432,8 @@ await LogTestHostCreatedAsync( } // ======= TEST HOST MODE ======== // + policiesService.ProcessRole = TestProcessRole.TestHost; + await proxyOutputDevice.HandleProcessRoleAsync(TestProcessRole.TestHost); // Setup the test host working folder. // Out of the test host controller extension the current working directory is the test host working directory. @@ -724,6 +734,17 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD dataConsumersBuilder.Add(pushOnlyProtocolDataConsumer); } + var abortForMaxFailedTestsExtension = new AbortForMaxFailedTestsExtension( + serviceProvider.GetCommandLineOptions(), + serviceProvider.GetTestFrameworkCapabilities().GetCapability(), + serviceProvider.GetRequiredService(), + serviceProvider.GetTestApplicationCancellationTokenSource()); + + if (await abortForMaxFailedTestsExtension.IsEnabledAsync()) + { + dataConsumersBuilder.Add(abortForMaxFailedTestsExtension); + } + IDataConsumer[] dataConsumerServices = dataConsumersBuilder.ToArray(); // Build the message bus diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/IPlatformOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/IPlatformOutputDevice.cs index 25d1bf12ae..22705e1968 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/IPlatformOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/IPlatformOutputDevice.cs @@ -15,4 +15,6 @@ internal interface IPlatformOutputDevice : IExtension Task DisplayAfterSessionEndRunAsync(); Task DisplayAsync(IOutputDeviceDataProducer producer, IOutputDeviceData data); + + Task HandleProcessRoleAsync(TestProcessRole processRole); } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs index e8e7ac88b0..78d4dafb0f 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/OutputDeviceManager.cs @@ -1,6 +1,7 @@ // 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.Testing.Platform.Logging; using Microsoft.Testing.Platform.ServerMode; using Microsoft.Testing.Platform.Services; @@ -33,7 +34,9 @@ internal async Task BuildAsync(ServiceProvider serviceProvide return new ProxyOutputDevice( nonServerOutputDevice, useServerModeOutputDevice - ? new ServerModePerCallOutputDevice(serviceProvider) + ? new ServerModePerCallOutputDevice( + serviceProvider.GetService(), + serviceProvider.GetRequiredService()) : null); } @@ -51,5 +54,6 @@ public static TerminalOutputDevice GetDefaultTerminalOutputDevice(ServiceProvide serviceProvider.GetCommandLineOptions(), serviceProvider.GetFileLoggerInformation(), serviceProvider.GetLoggerFactory(), - serviceProvider.GetClock()); + serviceProvider.GetClock(), + serviceProvider.GetRequiredService()); } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/ProxyOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/ProxyOutputDevice.cs index 6896debd84..b2d0b2ed4c 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/ProxyOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/ProxyOutputDevice.cs @@ -62,4 +62,13 @@ internal async Task InitializeAsync(ServerTestHost serverTestHost) await _serverModeOutputDevice.InitializeAsync(serverTestHost); } } + + internal async Task HandleProcessRoleAsync(TestProcessRole processRole) + { + await OriginalOutputDevice.HandleProcessRoleAsync(processRole); + if (_serverModeOutputDevice is not null) + { + await _serverModeOutputDevice.HandleProcessRoleAsync(processRole); + } + } } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs index f9d521e8a6..f049246cab 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs @@ -49,6 +49,7 @@ internal sealed partial class TerminalOutputDevice : IHotReloadPlatformOutputDev private readonly IFileLoggerInformation? _fileLoggerInformation; private readonly ILoggerFactory _loggerFactory; private readonly IClock _clock; + private readonly IStopPoliciesService _policiesService; private readonly string? _longArchitecture; private readonly string? _shortArchitecture; @@ -72,7 +73,8 @@ internal sealed partial class TerminalOutputDevice : IHotReloadPlatformOutputDev public TerminalOutputDevice(ITestApplicationCancellationTokenSource testApplicationCancellationTokenSource, IConsole console, ITestApplicationModuleInfo testApplicationModuleInfo, ITestHostControllerInfo testHostControllerInfo, IAsyncMonitor asyncMonitor, IRuntimeFeature runtimeFeature, IEnvironment environment, IProcessHandler process, IPlatformInformation platformInformation, - ICommandLineOptions commandLineOptions, IFileLoggerInformation? fileLoggerInformation, ILoggerFactory loggerFactory, IClock clock) + ICommandLineOptions commandLineOptions, IFileLoggerInformation? fileLoggerInformation, ILoggerFactory loggerFactory, IClock clock, + IStopPoliciesService policiesService) { _testApplicationCancellationTokenSource = testApplicationCancellationTokenSource; _console = console; @@ -87,6 +89,7 @@ public TerminalOutputDevice(ITestApplicationCancellationTokenSource testApplicat _fileLoggerInformation = fileLoggerInformation; _loggerFactory = loggerFactory; _clock = clock; + _policiesService = policiesService; if (_runtimeFeature.IsDynamicCodeSupported) { @@ -110,8 +113,15 @@ public TerminalOutputDevice(ITestApplicationCancellationTokenSource testApplicat } } - public Task InitializeAsync() + public async Task InitializeAsync() { + await _policiesService.RegisterOnAbortCallbackAsync( + () => + { + _terminalTestReporter?.StartCancelling(); + return Task.CompletedTask; + }); + if (_fileLoggerInformation is not null) { _logger = _loggerFactory.CreateLogger(GetType().ToString()); @@ -163,10 +173,6 @@ public Task InitializeAsync() ShowActiveTests = true, ShowProgress = shouldShowProgress, }); - - _testApplicationCancellationTokenSource.CancellationToken.Register(() => _terminalTestReporter.StartCancelling()); - - return Task.CompletedTask; } private string GetShortArchitecture(string runtimeIdentifier) @@ -593,4 +599,14 @@ public async Task ConsumeAsync(IDataProducer dataProducer, IData value, Cancella public void Dispose() => _terminalTestReporter?.Dispose(); + + public async Task HandleProcessRoleAsync(TestProcessRole processRole) + { + if (processRole == TestProcessRole.TestHost) + { + await _policiesService.RegisterOnMaxFailedTestsCallbackAsync( + async (maxFailedTests, _) => await DisplayAsync( + this, new TextOutputDeviceData(string.Format(CultureInfo.InvariantCulture, PlatformResources.ReachedMaxFailedTestsMessage, maxFailedTests)))); + } + } } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TestProcessRole.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TestProcessRole.cs new file mode 100644 index 0000000000..0955e45246 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TestProcessRole.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.Testing.Platform; + +internal enum TestProcessRole +{ + /// + /// Indicates that the currently running process is the test host. + /// + TestHost, + + /// + /// Indicates that the currently running process is the test host controller. + /// + TestHostController, + + /// + /// Indicates that the currently running process is the test host orchestrator. + /// + TestHostOrchestrator, +} diff --git a/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt b/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt index 3976e688ef..1d1c2b5ca1 100644 --- a/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt @@ -6,6 +6,8 @@ Microsoft.Testing.Platform.OutputDevice.ErrorMessageOutputDeviceData.Message.get Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData.Message.get -> string! Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData.WarningMessageOutputDeviceData(string! message) -> void +[TPEXP]Microsoft.Testing.Platform.Capabilities.TestFramework.IGracefulStopTestExecutionCapability +[TPEXP]Microsoft.Testing.Platform.Capabilities.TestFramework.IGracefulStopTestExecutionCapability.StopTestExecutionAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! [TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty [TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutput.get -> string! [TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutput.init -> void diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx index 8a899ed676..4047fa6895 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx +++ b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx @@ -700,4 +700,17 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Exception during the cancellation of request id '{0}' {0} is the request id - \ No newline at end of file + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + + diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index 47adbca59a..95c3be44f2 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted Přerušeno @@ -371,6 +376,11 @@ Rozhraní ILoggerFactory ještě nebylo sestaveno. + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. Sběrnice zpráv ještě nebyla sestavena nebo už není v této fázi použitelná. @@ -535,6 +545,11 @@ Dostupné hodnoty jsou Trace, Debug, Information, Warning, Error a Critical.Umožňuje zobrazit informace o testovací aplikaci .NET. + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options --list-tests a --minimum-expected-tests jsou nekompatibilní možnosti. @@ -623,6 +638,11 @@ Může mít jenom jeden argument jako řetězec ve formátu <value>[h|m|s] Proces měl být ukončen před tím, než jsme mohli určit tuto hodnotu. + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times Opakování se po {0} pokusech nezdařilo. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index 5102d26462..5ad7e52816 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted Abgebrochen @@ -371,6 +376,11 @@ Die ILoggerFactory wurde noch nicht erstellt. + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. Der Nachrichtenbus wurde noch nicht erstellt oder kann zu diesem Zeitpunkt nicht mehr verwendet werden. @@ -535,6 +545,11 @@ Die verfügbaren Werte sind "Trace", "Debug", "Information", "Warning", "Error" Zeigen Sie .NET-Testanwendungsinformationen an. + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options "--list-tests" und "--minimum-expected-tests" sind inkompatible Optionen. @@ -623,6 +638,11 @@ Nimmt ein Argument als Zeichenfolge im Format <value>[h|m|s], wobei "value Der Prozess hätte beendet werden müssen, bevor dieser Wert ermittelt werden kann + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times Wiederholungsfehler nach {0} Mal diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index c23458d113..58c731750f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted Anulado @@ -371,6 +376,11 @@ ILoggerFactory aún no se ha compilado. + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. El bus de mensajes aún no se ha compilado o ya no se puede usar en esta fase. @@ -535,6 +545,11 @@ Los valores disponibles son 'Seguimiento', 'Depurar', 'Información', 'Advertenc Muestre la información de la aplicación de prueba de .NET. + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options “--list-tests” y “--minimum-expected-tests” son opciones incompatibles @@ -623,6 +638,11 @@ Toma un argumento como cadena con el formato <value>[h|m|s] donde 'value' El proceso debería haberse terminado para poder determinar este valor + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times Error al reintentar después de {0} veces diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index f4bb8dd0b7..6529f58252 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted Abandonné @@ -371,6 +376,11 @@ ILoggerFactory n’a pas encore été généré. + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. Le bus de messages n’a pas encore été généré ou n’est plus utilisable à ce stade. @@ -535,6 +545,11 @@ Les valeurs disponibles sont « Trace », « Debug », « Information », Afficher les informations de l’application de test .NET. + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options « --list-tests » et « --minimum-expected-tests » sont des options incompatibles @@ -623,6 +638,11 @@ Prend un argument sous forme de chaîne au format <value>[h|m|s] où « v Le processus aurait dû s’arrêter avant que nous puissions déterminer cette valeur + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times Échec de la nouvelle tentative après {0} fois diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index 0de5fa57fa..15d86d4003 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted Operazione interrotta @@ -371,6 +376,11 @@ ILoggerFactory non è stato ancora compilato. + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. Il bus di messaggi non è stato ancora compilato o non è più utilizzabile in questa fase. @@ -535,6 +545,11 @@ I valori disponibili sono 'Trace', 'Debug', 'Information', 'Warning', 'Error' e Visualizza le informazioni sull'applicazione di test .NET. + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options '--list-tests' e '--minimum-expected-tests' sono opzioni incompatibili @@ -623,6 +638,11 @@ Acquisisce un argomento come stringa nel formato <value>[h|m|s] dove 'valu Il processo dovrebbe essere terminato prima di poter determinare questo valore + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times Tentativi non riusciti dopo {0} tentativi diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index 2e622e075e..18e1d555d3 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted 中止されました @@ -371,6 +376,11 @@ ILoggerFactory はまだ構築されていません。 + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. メッセージ バスはまだ構築されていないか、この段階ではこれ以上使用できません。 @@ -536,6 +546,11 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an .NET テスト アプリケーション情報を表示します。 + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options '--list-tests' と '--minimum-expected-tests' は互換性のないオプションです @@ -624,6 +639,11 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is この値を決定する前にプロセスを終了する必要があります + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times 再試行が {0} 回後に失敗しました diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index 22c32f88ab..c8b3cbeb40 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted 중단됨 @@ -371,6 +376,11 @@ ILoggerFactory가 아직 빌드되지 않았습니다. + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. 메시지 버스가 아직 빌드되지 않았거나 이 단계에서 더 이상 사용할 수 없습니다. @@ -535,6 +545,11 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an .NET 테스트 애플리케이션 정보를 표시합니다. + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options '--list-tests' 및 '--minimum-expected-tests'는 호환되지 않는 옵션입니다. @@ -623,6 +638,11 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is 이 값을 결정하려면 프로세스가 종료되어야 합니다. + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times {0}회 후 다시 시도 실패 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index c1cd3555bb..010f80b6d0 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted Przerwano @@ -371,6 +376,11 @@ Obiekt ILoggerFactory nie został jeszcze skompilowany. + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. Magistrala komunikatów nie została jeszcze zbudowana lub nie można jej już na tym etapie użyteczna. @@ -535,6 +545,11 @@ Dostępne wartości to „Trace”, „Debug”, „Information”, „Warning Wyświetl informacje o aplikacji testowej platformy .NET. + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options Opcje „--list-tests” i „--minimum-expected-tests” są niezgodne @@ -623,6 +638,11 @@ Pobiera jeden argument jako ciąg w formacie <value>[h|m|s], gdzie element Proces powinien zakończyć się przed ustaleniem tej wartości + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times Ponowna próba nie powiodła się po {0} razach diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index 398b0f293c..6046c82389 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted Anulado @@ -371,6 +376,11 @@ O ILoggerFactory ainda não foi criado. + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. O barramento de mensagens ainda não foi criado ou não pode mais ser usado nesse estágio. @@ -535,6 +545,11 @@ Os valores disponíveis são 'Rastreamento', 'Depuração', 'Informação', 'Avi Exibir informações do aplicativo de teste do .NET. + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options '--list-tests' e '--minimum-expected-tests' são opções incompatíveis @@ -623,6 +638,11 @@ Recebe um argumento como cadeia de caracteres no formato <valor>[h|m|s] em O processo deve ter sido encerrado antes que possamos determinar esse valor + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times Falha na repetição após o {0} tempo diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index a48eef9579..59ba762b05 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted Прервано @@ -371,6 +376,11 @@ Параметр ILoggerFactory еще не создан. + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. Шина сообщений еще не построена или на данном этапе непригодна для использования. @@ -535,6 +545,11 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an Отображение сведений о тестовом приложении .NET. + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options Параметры "--list-tests" и "--minimum-expected-tests" несовместимы @@ -623,6 +638,11 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Процесс должен быть завершен, прежде чем мы сможем определить это значение + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times Повторные попытки ({0}) завершились неудачно diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 4ea66f782c..bbaf34f0ff 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted Durduruldu @@ -371,6 +376,11 @@ ILoggerFactory henüz derlenmedi. + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. İleti veri yolu henüz derlenmedi veya bu aşamada artık kullanılamıyor. @@ -535,6 +545,11 @@ Kullanılabilir değerler: 'Trace', 'Debug', 'Information', 'Warning', 'Error' v .NET test uygulaması bilgilerini görüntüler. + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options '--list-tests' ve '--minimum-expected-tests' uyumsuz seçenekler @@ -623,6 +638,11 @@ Bir bağımsız değişkeni, 'value' değerinin kayan olduğu <value>[h|m| Bu değeri belirleyebilmemiz için süreçten çıkılmış olması gerekir + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times Yeniden deneme {0} deneme sonrasında başarısız oldu diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 4b98c6928f..1e6719edca 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted 已中止 @@ -371,6 +376,11 @@ 尚未生成 ILoggerFactory。 + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. 消息总线尚未生成或在此阶段不再可用。 @@ -535,6 +545,11 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an 显示 .NET 测试应用程序信息。 + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options “--list-tests”和“--minimum-expected-tests”是不兼容的选项 @@ -623,6 +638,11 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is 在我们确定此值之前,流程应该已退出 + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times {0} 次之后重试失败 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index ec34238c60..5d8b20aad0 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -2,6 +2,11 @@ + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + + Aborted 已中止 @@ -371,6 +376,11 @@ 尚未建置 ILoggerFactory。 + + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + + The message bus has not been built yet or is no more usable at this stage. 訊息匯流排尚未建置或在此階段無法再使用。 @@ -535,6 +545,11 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an 顯示 .NET 測試應用程式資訊。 + + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifies a maximum number of test failures that, when exceeded, will abort the test run. + + '--list-tests' and '--minimum-expected-tests' are incompatible options '--list-tests' 和 '--minimum-expected-tests' 是不相容的選項 @@ -623,6 +638,11 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is 在我們確定此值之前,流程應已結束 + + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + {0} is the number of max failed tests. + Retry failed after {0} times 在 {0} 次重試之後失敗 diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs index 091f782ad3..8c831b8f7f 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs @@ -15,17 +15,21 @@ namespace Microsoft.Testing.Platform.ServerMode; -internal sealed class ServerModePerCallOutputDevice : IPlatformOutputDevice +internal sealed class ServerModePerCallOutputDevice : IPlatformOutputDevice, IOutputDeviceDataProducer { - private readonly IServiceProvider _serviceProvider; + private readonly FileLoggerProvider? _fileLoggerProvider; + private readonly IStopPoliciesService _policiesService; private readonly ConcurrentBag _messages = new(); private IServerTestHost? _serverTestHost; private static readonly string[] NewLineStrings = { "\r\n", "\n" }; - public ServerModePerCallOutputDevice(IServiceProvider serviceProvider) - => _serviceProvider = serviceProvider; + public ServerModePerCallOutputDevice(FileLoggerProvider? fileLoggerProvider, IStopPoliciesService policiesService) + { + _fileLoggerProvider = fileLoggerProvider; + _policiesService = policiesService; + } internal async Task InitializeAsync(IServerTestHost serverTestHost) { @@ -94,7 +98,7 @@ public async Task DisplayBannerAsync(string? bannerMessage) public async Task DisplayBeforeSessionStartAsync() { - if (_serviceProvider.GetService() is { FileLogger.FileName: { } logFileName }) + if (_fileLoggerProvider is { FileLogger.FileName: { } logFileName }) { await LogAsync(LogLevel.Trace, string.Format(CultureInfo.InvariantCulture, PlatformResources.StartingTestSessionWithLogFilePath, logFileName), padding: null); } @@ -149,4 +153,14 @@ private static string GetIndentedMessage(string message, int? padding) return builder.ToString(); } + + public async Task HandleProcessRoleAsync(TestProcessRole processRole) + { + if (processRole == TestProcessRole.TestHost) + { + await _policiesService.RegisterOnMaxFailedTestsCallbackAsync( + async (maxFailedTests, _) => await DisplayAsync( + this, new TextOutputDeviceData(string.Format(CultureInfo.InvariantCulture, PlatformResources.ReachedMaxFailedTestsMessage, maxFailedTests)))); + } + } } diff --git a/src/Platform/Microsoft.Testing.Platform/Services/IStopPoliciesService.cs b/src/Platform/Microsoft.Testing.Platform/Services/IStopPoliciesService.cs new file mode 100644 index 0000000000..d82def8818 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/Services/IStopPoliciesService.cs @@ -0,0 +1,19 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.Testing.Platform.Services; + +internal interface IStopPoliciesService +{ + bool IsMaxFailedTestsTriggered { get; } + + bool IsAbortTriggered { get; } + + Task RegisterOnMaxFailedTestsCallbackAsync(Func callback); + + Task RegisterOnAbortCallbackAsync(Func callback); + + Task ExecuteMaxFailedTestsCallbacksAsync(int maxFailedTests, CancellationToken cancellationToken); + + Task ExecuteAbortCallbacksAsync(); +} diff --git a/src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs b/src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs new file mode 100644 index 0000000000..fdd0b5f032 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs @@ -0,0 +1,95 @@ +// 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.Concurrent; + +using Microsoft.Testing.Platform.Helpers; + +namespace Microsoft.Testing.Platform.Services; + +internal sealed class StopPoliciesService : IStopPoliciesService +{ + private readonly ITestApplicationCancellationTokenSource _testApplicationCancellationTokenSource; + + private BlockingCollection>? _maxFailedTestsCallbacks; + private BlockingCollection>? _abortCallbacks; + private int _lastMaxFailedTests; + + public StopPoliciesService(ITestApplicationCancellationTokenSource testApplicationCancellationTokenSource) + { + _testApplicationCancellationTokenSource = testApplicationCancellationTokenSource; + +#pragma warning disable VSTHRD101 // Avoid unsupported async delegates + // Note: If cancellation already requested, Register will still invoke the callback. + testApplicationCancellationTokenSource.CancellationToken.Register(async () => await ExecuteAbortCallbacksAsync()); +#pragma warning restore VSTHRD101 // Avoid unsupported async delegates + } + + internal TestProcessRole? ProcessRole { get; set; } + + public bool IsMaxFailedTestsTriggered { get; private set; } + + public bool IsAbortTriggered { get; private set; } + + private static void RegisterCallback(ref BlockingCollection? callbacks, T callback) + => (callbacks ??= new()).Add(callback); + + public async Task ExecuteMaxFailedTestsCallbacksAsync(int maxFailedTests, CancellationToken cancellationToken) + { + _lastMaxFailedTests = maxFailedTests; + IsMaxFailedTestsTriggered = true; + if (_maxFailedTestsCallbacks is null) + { + return; + } + + foreach (Func callback in _maxFailedTestsCallbacks) + { + // For now, we are fine if the callback crashed us. It shouldn't happen for our + // current usage anyway and the APIs around this are all internal for now. + await callback.Invoke(maxFailedTests, cancellationToken); + } + } + + public async Task ExecuteAbortCallbacksAsync() + { + IsAbortTriggered = true; + + if (_abortCallbacks is null) + { + return; + } + + foreach (Func callback in _abortCallbacks) + { + // For now, we are fine if the callback crashed us. It shouldn't happen for our + // current usage anyway and the APIs around this are all internal for now. + await callback.Invoke(); + } + } + + public async Task RegisterOnMaxFailedTestsCallbackAsync(Func callback) + { + if (ProcessRole != TestProcessRole.TestHost) + { + throw ApplicationStateGuard.Unreachable(); + } + + if (IsMaxFailedTestsTriggered) + { + await callback(_lastMaxFailedTests, _testApplicationCancellationTokenSource.CancellationToken); + } + + RegisterCallback(ref _maxFailedTestsCallbacks, callback); + } + + public async Task RegisterOnAbortCallbackAsync(Func callback) + { + if (IsAbortTriggered) + { + await callback(); + } + + RegisterCallback(ref _abortCallbacks, callback); + } +} diff --git a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs index 3304d317de..0b19b09d89 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs @@ -13,20 +13,28 @@ namespace Microsoft.Testing.Platform.Services; -internal sealed class TestApplicationResult( - IOutputDevice outputService, - ITestApplicationCancellationTokenSource testApplicationCancellationTokenSource, - ICommandLineOptions commandLineOptions, - IEnvironment environment) : ITestApplicationProcessExitCode, IOutputDeviceDataProducer +internal sealed class TestApplicationResult : ITestApplicationProcessExitCode, IOutputDeviceDataProducer { - private readonly IOutputDevice _outputService = outputService; - private readonly ITestApplicationCancellationTokenSource _testApplicationCancellationTokenSource = testApplicationCancellationTokenSource; - private readonly ICommandLineOptions _commandLineOptions = commandLineOptions; - private readonly IEnvironment _environment = environment; + private readonly IOutputDevice _outputService; + private readonly ICommandLineOptions _commandLineOptions; + private readonly IEnvironment _environment; + private readonly IStopPoliciesService _policiesService; private readonly List _failedTests = []; private int _totalRanTests; private bool _testAdapterTestSessionFailure; + public TestApplicationResult( + IOutputDevice outputService, + ICommandLineOptions commandLineOptions, + IEnvironment environment, + IStopPoliciesService policiesService) + { + _outputService = outputService; + _commandLineOptions = commandLineOptions; + _environment = environment; + _policiesService = policiesService; + } + /// public string Uid { get; } = nameof(TestApplicationResult); @@ -81,9 +89,10 @@ public Task ConsumeAsync(IDataProducer dataProducer, IData value, CancellationTo public int GetProcessExitCode() { int exitCode = ExitCodes.Success; + exitCode = exitCode == ExitCodes.Success && _policiesService.IsMaxFailedTestsTriggered ? ExitCodes.TestExecutionStoppedForMaxFailedTests : exitCode; exitCode = exitCode == ExitCodes.Success && _testAdapterTestSessionFailure ? ExitCodes.TestAdapterTestSessionFailure : exitCode; exitCode = exitCode == ExitCodes.Success && _failedTests.Count > 0 ? ExitCodes.AtLeastOneTestFailed : exitCode; - exitCode = exitCode == ExitCodes.Success && _testApplicationCancellationTokenSource.CancellationToken.IsCancellationRequested ? ExitCodes.TestSessionAborted : exitCode; + exitCode = exitCode == ExitCodes.Success && _policiesService.IsAbortTriggered ? ExitCodes.TestSessionAborted : exitCode; // If the user has specified the VSTestAdapterMode option, then we don't want to return a non-zero exit code if no tests ran. if (!_commandLineOptions.IsOptionSet(PlatformCommandLineProvider.VSTestAdapterModeOptionKey)) diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs index 8894ffbc2d..e64b0928f5 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs @@ -71,6 +71,8 @@ Takes one argument as string in the format [h|m|s] where 'value' is float Extension options: --filter Filters tests using the given expression. For more information, see the Filter option details section. For more information and examples on how to use selective unit test filtering, see https://learn.microsoft.com/dotnet/core/testing/selective-unit-tests. + --maximum-failed-tests + Specifies a maximum number of test failures that, when exceeded, will abort the test run. --no-ansi Disable outputting ANSI escape characters to screen. --no-progress @@ -113,6 +115,10 @@ public async Task Info_WhenMSTestExtensionRegistered_OutputInfoContentOfRegister Arity: 1..N Hidden: False Description: Specify or override a key-value pair parameter. For more information and examples, see https://learn.microsoft.com/visualstudio/test/configure-unit-tests-by-using-a-dot-runsettings-file#testrunparameters + --maximum-failed-tests + Arity: 1 + Hidden: False + Description: Specifies a maximum number of test failures that, when exceeded, will abort the test run. """; testHostResult.AssertOutputContains(output); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs new file mode 100644 index 0000000000..9c5f2fe087 --- /dev/null +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs @@ -0,0 +1,154 @@ +// 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.Globalization; +using System.Text.RegularExpressions; + +using Microsoft.Testing.Platform.Acceptance.IntegrationTests; +using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; +using Microsoft.Testing.Platform.Helpers; + +namespace MSTest.Acceptance.IntegrationTests; + +[TestGroup] +public sealed class MaxFailedTestsExtensionTests : AcceptanceTestBase +{ + private const string AssetName = nameof(MaxFailedTestsExtensionTests); + private readonly TestAssetFixture _testAssetFixture; + + public MaxFailedTestsExtensionTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) + : base(testExecutionContext) => _testAssetFixture = testAssetFixture; + + [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + public async Task SimpleMaxFailedTestsScenario(string tfm) + { + var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + + TestHostResult testHostResult = await testHost.ExecuteAsync("--maximum-failed-tests 3"); + testHostResult.AssertExitCodeIs(ExitCodes.TestExecutionStoppedForMaxFailedTests); + + int total = int.Parse(Regex.Match(testHostResult.StandardOutput, @"total: (\d+)").Groups[1].Value, CultureInfo.InvariantCulture); + + // We can't know the number of tests that will be executed exactly due to the async + // nature of publish/consume on the platform side. But we expect the cancellation to + // happen "fast" enough that we don't execute all tests. + Assert.IsTrue(total < 12); + Assert.IsTrue(total >= 5); + + testHostResult = await testHost.ExecuteAsync(); + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + + total = int.Parse(Regex.Match(testHostResult.StandardOutput, @"total: (\d+)").Groups[1].Value, CultureInfo.InvariantCulture); + Assert.AreEqual(12, total); + } + + [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] + public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + { + private const string Sources = """ +#file MaxFailedTestsExtensionTests.csproj + + + $TargetFrameworks$ + true + Exe + enable + preview + + + + + + + +#file UnitTest1.cs +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[TestClass] +public class UnitTest1 +{ + [TestMethod] + public void Test1() + { + Assert.Fail(); + } + + [TestMethod] + public void Test2() + { + } + + [TestMethod] + public void Test3() + { + } + + [TestMethod] + public void Test4() + { + Assert.Fail(); + } + + [TestMethod] + public void Test5() + { + Assert.Fail(); + } + + [TestMethod] + public async Task Test6() + { + await Task.Delay(10); + } + + [TestMethod] + public async Task Test7() + { + await Task.Delay(10); + } + + [TestMethod] + public async Task Test8() + { + await Task.Delay(10); + } + + [TestMethod] + public async Task Test9() + { + await Task.Delay(10); + } + + [TestMethod] + public async Task Test10() + { + await Task.Delay(10); + } + + [TestMethod] + public async Task Test11() + { + await Task.Delay(10); + } + + [TestMethod] + public async Task Test12() + { + await Task.Delay(10); + } +} +"""; + + public string TargetAssetPath => GetAssetPath(AssetName); + + public override IEnumerable<(string ID, string Name, string Code)> GetAssetsToGenerate() + { + yield return (AssetName, AssetName, + Sources + .PatchTargetFrameworks(TargetFrameworks.All) + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); + } + } +} diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs new file mode 100644 index 0000000000..1f9883dbec --- /dev/null +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs @@ -0,0 +1,167 @@ +// 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.Testing.Platform.Acceptance.IntegrationTests.Helpers; +using Microsoft.Testing.Platform.Helpers; + +namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; + +[TestGroup] +public class MaxFailedTestsExtensionTests : AcceptanceTestBase +{ + private const string AssetName = nameof(MaxFailedTestsExtensionTests); + private readonly TestAssetFixture _testAssetFixture; + + public MaxFailedTestsExtensionTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) + : base(testExecutionContext) => _testAssetFixture = testAssetFixture; + + public async Task TestMaxFailedTestsShouldCallStopTestExecutionAsync() + { + var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, TargetFrameworks.NetCurrent.Arguments); + TestHostResult testHostResult = await testHost.ExecuteAsync("--maximum-failed-tests 2"); + + testHostResult.AssertExitCodeIs(ExitCodes.TestExecutionStoppedForMaxFailedTests); + + testHostResult.AssertOutputContains("Test session is aborting due to reaching failures ('2') specified by the '--maximum-failed-tests' option."); + testHostResult.AssertOutputContainsSummary(failed: 3, passed: 3, skipped: 0); + } + + [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] + public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + { + private const string Sources = """ +#file MaxFailedTestsExtensionTests.csproj + + + $TargetFrameworks$ + Exe + true + enable + preview + + + + + + +#file Program.cs +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading.Tasks; +using System.Threading; +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.Helpers; + +internal sealed class Program +{ + public static async Task Main(string[] args) + { + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + var adapter = new DummyAdapter(); + builder.RegisterTestFramework(_ => new Capabilities(), (_, __) => adapter); + +#pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + builder.AddMaximumFailedTestsService(adapter); +#pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); + } +} + +internal class DummyAdapter : ITestFramework, IDataProducer +{ + public string Uid => nameof(DummyAdapter); + + public string Version => string.Empty; + + public string DisplayName => string.Empty; + + public string Description => string.Empty; + + public Type[] DataTypesProduced => new[] { typeof(TestNodeUpdateMessage) }; + + public Task CloseTestSessionAsync(CloseTestSessionContext context) => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + + public Task CreateTestSessionAsync(CreateTestSessionContext context) => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + + public async Task ExecuteRequestAsync(ExecuteRequestContext context) + { + // First fail. + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "1", DisplayName = "Test1", Properties = new(new FailedTestNodeStateProperty()) })); + + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "2", DisplayName = "Test2", Properties = new(PassedTestNodeStateProperty.CachedInstance) })); + + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "3", DisplayName = "Test3", Properties = new(PassedTestNodeStateProperty.CachedInstance) })); + + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "4", DisplayName = "Test4", Properties = new(PassedTestNodeStateProperty.CachedInstance) })); + + if (GracefulStop.Instance.IsStopRequested) throw new InvalidOperationException("Unexpected stop request!"); + + // Second fail. + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "5", DisplayName = "Test5", Properties = new(new FailedTestNodeStateProperty()) })); + + await GracefulStop.Instance.TCS.Task; + + if (!GracefulStop.Instance.IsStopRequested) throw new InvalidOperationException("Expected stop request!"); + + // Third fail. + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "6", DisplayName = "Test6", Properties = new(new FailedTestNodeStateProperty()) })); + + context.Complete(); + } + + public Task IsEnabledAsync() => Task.FromResult(true); +} + +internal class Capabilities : ITestFrameworkCapabilities +{ + IReadOnlyCollection ICapabilities.Capabilities => [GracefulStop.Instance]; +} + +#pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. +internal sealed class GracefulStop : IGracefulStopTestExecutionCapability +#pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. +{ + private GracefulStop() + { + } + + public static GracefulStop Instance { get; } = new(); + + public TaskCompletionSource TCS { get; } = new(); + + public bool IsStopRequested { get; private set; } + + public Task StopTestExecutionAsync(CancellationToken cancellationToken) + { + IsStopRequested = true; + TCS.SetResult(); + return Task.CompletedTask; + } +} + +"""; + + public string TargetAssetPath => GetAssetPath(AssetName); + + public override IEnumerable<(string ID, string Name, string Code)> GetAssetsToGenerate() + { + yield return (AssetName, AssetName, + Sources + .PatchTargetFrameworks(TargetFrameworks.NetCurrent) + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); + } + } +} diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs index c4840468df..9fc878852d 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs @@ -419,6 +419,7 @@ public void RunClassCleanupShouldInvokeIfClassCleanupMethod() _testClassInfo.ClassCleanupMethod = typeof(DummyTestClass).GetMethod(nameof(DummyTestClass.ClassCleanupMethod)); // Act + _testClassInfo.RunClassInitialize(null); _testClassInfo.ExecuteClassCleanup(); // Assert @@ -446,6 +447,7 @@ public void RunClassCleanupShouldReturnAssertFailureExceptionDetails() _testClassInfo.ClassCleanupMethod = typeof(DummyTestClass).GetMethod(nameof(DummyTestClass.ClassCleanupMethod)); // Act + _testClassInfo.RunClassInitialize(null); Exception classCleanupException = VerifyThrows(_testClassInfo.ExecuteClassCleanup); // Assert @@ -461,6 +463,7 @@ public void RunClassCleanupShouldReturnAssertInconclusiveExceptionDetails() _testClassInfo.ClassCleanupMethod = typeof(DummyTestClass).GetMethod(nameof(DummyTestClass.ClassCleanupMethod)); // Act + _testClassInfo.RunClassInitialize(null); Exception classCleanupException = VerifyThrows(_testClassInfo.ExecuteClassCleanup); // Assert @@ -476,6 +479,7 @@ public void RunClassCleanupShouldReturnExceptionDetailsOfNonAssertExceptions() _testClassInfo.ClassCleanupMethod = typeof(DummyTestClass).GetMethod(nameof(DummyTestClass.ClassCleanupMethod)); // Act + _testClassInfo.RunClassInitialize(null); Exception classCleanupException = VerifyThrows(_testClassInfo.ExecuteClassCleanup); // Assert @@ -493,6 +497,7 @@ public void RunBaseClassCleanupWithNoDerivedClassCleanupShouldReturnExceptionDet _testClassInfo.BaseClassCleanupMethods.Add(baseClassCleanupMethod); // Act + _testClassInfo.RunClassInitialize(null); Exception classCleanupException = VerifyThrows(_testClassInfo.ExecuteClassCleanup); // Assert @@ -515,6 +520,22 @@ public void RunBaseClassCleanupEvenIfThereIsNoDerivedClassCleanup() // Assert Verify(_testClassInfo.HasExecutableCleanupMethod); + Verify(classCleanupCallCount == 0, "DummyBaseTestClass.CleanupClassMethod call count"); + + // Act 2 + _testClassInfo.RunClassInitialize(null); + _testClassInfo.ExecuteClassCleanup(); + + // Assert 2 + Verify(_testClassInfo.HasExecutableCleanupMethod); + Verify(_testClassInfo.IsClassInitializeExecuted); + Verify(classCleanupCallCount == 1, "DummyBaseTestClass.CleanupClassMethod call count"); + + // Act 3 + _testClassInfo.ExecuteClassCleanup(); + + // Assert 3 + Verify(_testClassInfo.HasExecutableCleanupMethod); Verify(classCleanupCallCount == 1, "DummyBaseTestClass.CleanupClassMethod call count"); } @@ -526,6 +547,7 @@ public void RunClassCleanupShouldThrowTheInnerMostExceptionWhenThereAreMultipleN DummyTestClass.ClassCleanupMethodBody = FailingStaticHelper.DoWork; _testClassInfo.ClassCleanupMethod = typeof(DummyTestClass).GetMethod("ClassCleanupMethod"); + _testClassInfo.RunClassInitialize(null); Exception classCleanupException = VerifyThrows(_testClassInfo.ExecuteClassCleanup); Verify(classCleanupException.Message.StartsWith("Class Cleanup method DummyTestClass.ClassCleanupMethod failed. Error Message: System.InvalidOperationException: I fail..", StringComparison.Ordinal)); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs index 6964e6aa45..804d5aecf0 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs @@ -15,7 +15,7 @@ namespace Microsoft.Testing.Platform.UnitTests; public sealed class TestApplicationResultTests : TestBase { private readonly TestApplicationResult _testApplicationResult - = new(new Mock().Object, new Mock().Object, new Mock().Object, new Mock().Object); + = new(new Mock().Object, new Mock().Object, new Mock().Object, new Mock().Object); public TestApplicationResultTests(ITestExecutionContext testExecutionContext) : base(testExecutionContext) @@ -68,15 +68,17 @@ public async Task GetProcessExitCodeAsync_If_Failed_Tests_Returns_AtLeastOneTest public async Task GetProcessExitCodeAsync_If_Canceled_Returns_TestSessionAborted() { Mock testApplicationCancellationTokenSource = new(); + // CTS should not be created in SetupGet so that the mocked ITestApplicationCancellationTokenSource returns the same instance on every access + // which is the case in the real production implementation. + CancellationTokenSource cancellationTokenSource = new(); testApplicationCancellationTokenSource.SetupGet(x => x.CancellationToken).Returns(() => { - CancellationTokenSource cancellationTokenSource = new(); cancellationTokenSource.Cancel(); return cancellationTokenSource.Token; }); TestApplicationResult testApplicationResult - = new(new Mock().Object, testApplicationCancellationTokenSource.Object, new Mock().Object, new Mock().Object); + = new(new Mock().Object, new Mock().Object, new Mock().Object, new StopPoliciesService(testApplicationCancellationTokenSource.Object)); await testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, @@ -108,9 +110,10 @@ public async Task GetProcessExitCodeAsync_If_TestAdapter_Returns_TestAdapterTest public async Task GetProcessExitCodeAsync_If_MinimumExpectedTests_Violated_Returns_MinimumExpectedTestsPolicyViolation() { TestApplicationResult testApplicationResult - = new(new Mock().Object, new Mock().Object, - new CommandLineOption(PlatformCommandLineProvider.MinimumExpectedTestsOptionKey, ["2"]), - new Mock().Object); + = new( + new Mock().Object, + new CommandLineOption(PlatformCommandLineProvider.MinimumExpectedTestsOptionKey, ["2"]), + new Mock().Object, new Mock().Object); await testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, @@ -136,9 +139,10 @@ TestApplicationResult testApplicationResult public async Task GetProcessExitCodeAsync_OnDiscovery_No_Tests_Discovered_Returns_ZeroTests() { TestApplicationResult testApplicationResult - = new(new Mock().Object, new Mock().Object, - new CommandLineOption(PlatformCommandLineProvider.DiscoverTestsOptionKey, []), - new Mock().Object); + = new( + new Mock().Object, + new CommandLineOption(PlatformCommandLineProvider.DiscoverTestsOptionKey, []), + new Mock().Object, new Mock().Object); await testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, @@ -154,9 +158,10 @@ TestApplicationResult testApplicationResult public async Task GetProcessExitCodeAsync_OnDiscovery_Some_Tests_Discovered_Returns_Success() { TestApplicationResult testApplicationResult - = new(new Mock().Object, new Mock().Object, - new CommandLineOption(PlatformCommandLineProvider.DiscoverTestsOptionKey, []), - new Mock().Object); + = new( + new Mock().Object, + new CommandLineOption(PlatformCommandLineProvider.DiscoverTestsOptionKey, []), + new Mock().Object, new Mock().Object); await testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, @@ -188,12 +193,15 @@ public void GetProcessExitCodeAsync_IgnoreExitCodes(string argument, int expecte foreach (TestApplicationResult testApplicationResult in new TestApplicationResult[] { - new(new Mock().Object, new Mock().Object, + new( + new Mock().Object, new CommandLineOption(PlatformCommandLineProvider.IgnoreExitCodeOptionKey, argument is null ? [] : [argument]), - new Mock().Object), - new(new Mock().Object, new Mock().Object, + new Mock().Object, new Mock().Object), + new( + new Mock().Object, new Mock().Object, - environment.Object), + environment.Object, + new Mock().Object), }) { Assert.AreEqual(expectedExitCode, testApplicationResult.GetProcessExitCode()); From 87c21728a3371c37180d2caa1b2f6a0d1999feac Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 11 Dec 2024 10:06:39 +0100 Subject: [PATCH 098/273] Cleanup duplicate logic for timeout handling when creating assembly info (#4317) --- .../MSTest.TestAdapter/Execution/TypeCache.cs | 118 +++++------------- 1 file changed, 30 insertions(+), 88 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index 5e5f5c68a2..0ce373c00e 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -383,6 +383,26 @@ private TestClassInfo CreateClassInfo(Type classType, TestMethod testMethod) #region AssemblyInfo creation and cache logic. + private TimeoutInfo? TryGetTimeoutInfo(MethodInfo methodInfo, FixtureKind fixtureKind) + { + TimeoutAttribute? timeoutAttribute = _reflectionHelper.GetFirstNonDerivedAttributeOrDefault(methodInfo, inherit: false); + if (timeoutAttribute != null) + { + if (!timeoutAttribute.HasCorrectTimeout) + { + string message = string.Format(CultureInfo.CurrentCulture, Resource.UTA_ErrorInvalidTimeout, methodInfo.DeclaringType!.FullName, methodInfo.Name); + throw new TypeInspectionException(message); + } + + return TimeoutInfo.FromTimeoutAttribute(timeoutAttribute); + } + + var globalTimeout = TimeoutInfo.FromFixtureSettings(fixtureKind); + return globalTimeout.Timeout > 0 + ? globalTimeout + : null; + } + /// /// Get the assembly info for the parameter type. /// @@ -403,11 +423,6 @@ private TestAssemblyInfo GetAssemblyInfo(Type type) foreach (Type t in types) { - if (t == null) - { - continue; - } - try { // Only examine classes which are TestClass or derives from TestClass attribute @@ -433,41 +448,12 @@ private TestAssemblyInfo GetAssemblyInfo(Type type) if (IsAssemblyOrClassInitializeMethod(methodInfo)) { assemblyInfo.AssemblyInitializeMethod = methodInfo; - - TimeoutAttribute? timeoutAttribute = _reflectionHelper.GetFirstNonDerivedAttributeOrDefault(methodInfo, inherit: false); - if (timeoutAttribute != null) - { - if (!timeoutAttribute.HasCorrectTimeout) - { - string message = string.Format(CultureInfo.CurrentCulture, Resource.UTA_ErrorInvalidTimeout, methodInfo.DeclaringType!.FullName, methodInfo.Name); - throw new TypeInspectionException(message); - } - - assemblyInfo.AssemblyInitializeMethodTimeoutMilliseconds = TimeoutInfo.FromTimeoutAttribute(timeoutAttribute); - } - else if (MSTestSettings.CurrentSettings.AssemblyInitializeTimeout > 0) - { - assemblyInfo.AssemblyInitializeMethodTimeoutMilliseconds = TimeoutInfo.FromFixtureSettings(FixtureKind.AssemblyInitialize); - } + assemblyInfo.AssemblyInitializeMethodTimeoutMilliseconds = TryGetTimeoutInfo(methodInfo, FixtureKind.AssemblyInitialize); } else if (IsAssemblyOrClassCleanupMethod(methodInfo)) { assemblyInfo.AssemblyCleanupMethod = methodInfo; - TimeoutAttribute? timeoutAttribute = _reflectionHelper.GetFirstNonDerivedAttributeOrDefault(methodInfo, inherit: false); - if (timeoutAttribute != null) - { - if (!timeoutAttribute.HasCorrectTimeout) - { - string message = string.Format(CultureInfo.CurrentCulture, Resource.UTA_ErrorInvalidTimeout, methodInfo.DeclaringType!.FullName, methodInfo.Name); - throw new TypeInspectionException(message); - } - - assemblyInfo.AssemblyCleanupMethodTimeoutMilliseconds = TimeoutInfo.FromTimeoutAttribute(timeoutAttribute); - } - else if (MSTestSettings.CurrentSettings.AssemblyCleanupTimeout > 0) - { - assemblyInfo.AssemblyCleanupMethodTimeoutMilliseconds = TimeoutInfo.FromFixtureSettings(FixtureKind.AssemblyCleanup); - } + assemblyInfo.AssemblyCleanupMethodTimeoutMilliseconds = TryGetTimeoutInfo(methodInfo, FixtureKind.AssemblyCleanup); } } } @@ -594,20 +580,9 @@ private void UpdateInfoIfClassInitializeOrCleanupMethod( if (isInitializeMethod) { - TimeoutAttribute? timeoutAttribute = _reflectionHelper.GetFirstNonDerivedAttributeOrDefault(methodInfo, inherit: false); - if (timeoutAttribute != null) + if (TryGetTimeoutInfo(methodInfo, FixtureKind.ClassInitialize) is { } timeoutInfo) { - if (!timeoutAttribute.HasCorrectTimeout) - { - string message = string.Format(CultureInfo.CurrentCulture, Resource.UTA_ErrorInvalidTimeout, methodInfo.DeclaringType!.FullName, methodInfo.Name); - throw new TypeInspectionException(message); - } - - classInfo.ClassInitializeMethodTimeoutMilliseconds.Add(methodInfo, TimeoutInfo.FromTimeoutAttribute(timeoutAttribute)); - } - else if (MSTestSettings.CurrentSettings.ClassInitializeTimeout > 0) - { - classInfo.ClassInitializeMethodTimeoutMilliseconds.Add(methodInfo, TimeoutInfo.FromFixtureSettings(FixtureKind.ClassInitialize)); + classInfo.ClassInitializeMethodTimeoutMilliseconds.Add(methodInfo, timeoutInfo); } if (isBase) @@ -627,20 +602,9 @@ private void UpdateInfoIfClassInitializeOrCleanupMethod( if (isCleanupMethod) { - TimeoutAttribute? timeoutAttribute = _reflectionHelper.GetFirstNonDerivedAttributeOrDefault(methodInfo, inherit: false); - if (timeoutAttribute != null) - { - if (!timeoutAttribute.HasCorrectTimeout) - { - string message = string.Format(CultureInfo.CurrentCulture, Resource.UTA_ErrorInvalidTimeout, methodInfo.DeclaringType!.FullName, methodInfo.Name); - throw new TypeInspectionException(message); - } - - classInfo.ClassCleanupMethodTimeoutMilliseconds.Add(methodInfo, TimeoutInfo.FromTimeoutAttribute(timeoutAttribute)); - } - else if (MSTestSettings.CurrentSettings.ClassCleanupTimeout > 0) + if (TryGetTimeoutInfo(methodInfo, FixtureKind.ClassCleanup) is { } timeoutInfo) { - classInfo.ClassCleanupMethodTimeoutMilliseconds.Add(methodInfo, TimeoutInfo.FromFixtureSettings(FixtureKind.ClassCleanup)); + classInfo.ClassCleanupMethodTimeoutMilliseconds.Add(methodInfo, timeoutInfo); } if (isBase) @@ -693,20 +657,9 @@ private void UpdateInfoIfTestInitializeOrCleanupMethod( if (hasTestInitialize) { - TimeoutAttribute? timeoutAttribute = _reflectionHelper.GetFirstNonDerivedAttributeOrDefault(methodInfo, inherit: false); - if (timeoutAttribute != null) + if (TryGetTimeoutInfo(methodInfo, FixtureKind.TestInitialize) is { } timeoutInfo) { - if (!timeoutAttribute.HasCorrectTimeout) - { - string message = string.Format(CultureInfo.CurrentCulture, Resource.UTA_ErrorInvalidTimeout, methodInfo.DeclaringType!.FullName, methodInfo.Name); - throw new TypeInspectionException(message); - } - - classInfo.TestInitializeMethodTimeoutMilliseconds.Add(methodInfo, TimeoutInfo.FromTimeoutAttribute(timeoutAttribute)); - } - else if (MSTestSettings.CurrentSettings.TestInitializeTimeout > 0) - { - classInfo.TestInitializeMethodTimeoutMilliseconds.Add(methodInfo, TimeoutInfo.FromFixtureSettings(FixtureKind.TestInitialize)); + classInfo.TestInitializeMethodTimeoutMilliseconds.Add(methodInfo, timeoutInfo); } if (!isBase) @@ -724,20 +677,9 @@ private void UpdateInfoIfTestInitializeOrCleanupMethod( if (hasTestCleanup) { - TimeoutAttribute? timeoutAttribute = _reflectionHelper.GetFirstNonDerivedAttributeOrDefault(methodInfo, inherit: false); - if (timeoutAttribute != null) - { - if (!timeoutAttribute.HasCorrectTimeout) - { - string message = string.Format(CultureInfo.CurrentCulture, Resource.UTA_ErrorInvalidTimeout, methodInfo.DeclaringType!.FullName, methodInfo.Name); - throw new TypeInspectionException(message); - } - - classInfo.TestCleanupMethodTimeoutMilliseconds.Add(methodInfo, TimeoutInfo.FromTimeoutAttribute(timeoutAttribute)); - } - else if (MSTestSettings.CurrentSettings.TestCleanupTimeout > 0) + if (TryGetTimeoutInfo(methodInfo, FixtureKind.TestCleanup) is { } timeoutInfo) { - classInfo.TestCleanupMethodTimeoutMilliseconds.Add(methodInfo, TimeoutInfo.FromFixtureSettings(FixtureKind.TestCleanup)); + classInfo.TestCleanupMethodTimeoutMilliseconds.Add(methodInfo, timeoutInfo); } if (!isBase) From e1051b604ed22ecf75e5361be0c1cd17f0d03e21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 11 Dec 2024 11:59:33 +0100 Subject: [PATCH 099/273] Update dependencies from devdiv/DevDiv/vs-code-coverage, microsoft/testanywhere (#4319) --- eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index a8a58245c4..c41acf13b5 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,17 +13,17 @@ https://github.com/dotnet/arcade 45d845e04c05fbe5da9838c454bbc3af1df6be81 - + https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage eb105201ff904a7d5c6fac39de838a4bb6966a93 - + https://github.com/microsoft/testanywhere 33cb71263430f0dbe8f9ffd4edd76d837cb05259 https://github.com/microsoft/testanywhere - aa2fcc8616d988b234bc1d218465b20c56d0b82f + 2346f405dcb5150b567970995dc978feb26b2db0 @@ -43,11 +43,11 @@ 94798e07efab2663f2d1a71862780bc365d2e3ab - - - https://github.com/dotnet/arcade - 45d845e04c05fbe5da9838c454bbc3af1df6be81 - + + + https://github.com/dotnet/arcade + 45d845e04c05fbe5da9838c454bbc3af1df6be81 + diff --git a/eng/Versions.props b/eng/Versions.props index 7522c58f20..8da454c658 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,9 +8,9 @@ 10.0.0-beta.24604.4 - 17.13.2-preview.24605.2 + 17.13.2-preview.24606.2 - 1.5.0-preview.24604.2 + 1.5.0-preview.24608.1 1.0.0-alpha.24473.2 From 23321d75d1ad3c27f69be2a0c204dbc2136fe8b3 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 11 Dec 2024 12:19:20 +0100 Subject: [PATCH 100/273] [Refactor] Use `List` rather than `Collection` (#4315) --- .../Discovery/AssemblyEnumerator.cs | 11 ++--- .../Discovery/AssemblyEnumeratorWrapper.cs | 8 ++-- .../Discovery/TypeEnumerator.cs | 20 ++++---- .../Discovery/TypeValidator.cs | 2 +- .../Discovery/UnitTestDiscoverer.cs | 2 +- .../Discovery/AssemblyEnumeratorTests.cs | 47 ++++++++++--------- .../AssemblyEnumeratorWrapperTests.cs | 2 +- .../Discovery/TypeEnumeratorTests.cs | 24 +++++----- 8 files changed, 55 insertions(+), 61 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs index 5a1ea2adae..dc95277fea 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs @@ -72,17 +72,16 @@ public AssemblyEnumerator(MSTestSettings settings) => internal ICollection EnumerateAssembly( string assemblyFileName, [StringSyntax(StringSyntaxAttribute.Xml, nameof(runSettingsXml))] string? runSettingsXml, - out ICollection warnings) + List warnings) { DebugEx.Assert(!StringEx.IsNullOrWhiteSpace(assemblyFileName), "Invalid assembly file name."); - var warningMessages = new List(); var tests = new List(); // Contains list of assembly/class names for which we have already added fixture tests. var fixturesTests = new HashSet(); 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); @@ -109,12 +108,11 @@ internal ICollection EnumerateAssembly( continue; } - List testsInType = DiscoverTestsInType(assemblyFileName, testRunParametersFromRunSettings, type, warningMessages, discoverInternals, + List testsInType = DiscoverTestsInType(assemblyFileName, testRunParametersFromRunSettings, type, warnings, discoverInternals, testDataSourceDiscovery, testIdGenerationStrategy, fixturesTests); tests.AddRange(testsInType); } - warnings = warningMessages; return tests; } @@ -228,8 +226,7 @@ private List DiscoverTestsInType( { typeFullName = type.FullName; TypeEnumerator testTypeEnumerator = GetTypeEnumerator(type, assemblyFileName, discoverInternals, discoveryOption, testIdGenerationStrategy); - ICollection? unitTestCases = testTypeEnumerator.Enumerate(out ICollection warningsFromTypeEnumerator); - warningMessages.AddRange(warningsFromTypeEnumerator); + List? unitTestCases = testTypeEnumerator.Enumerate(warningMessages); if (unitTestCases != null) { diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs index cc81800eeb..84fd028284 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs @@ -27,7 +27,7 @@ internal sealed class AssemblyEnumeratorWrapper /// The run Settings. /// Contains warnings if any, that need to be passed back to the caller. /// A collection of test elements. - internal ICollection? GetTests(string? assemblyFileName, IRunSettings? runSettings, out ICollection warnings) + internal ICollection? GetTests(string? assemblyFileName, IRunSettings? runSettings, out List warnings) { warnings = new List(); @@ -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) { @@ -98,7 +98,7 @@ internal sealed class AssemblyEnumeratorWrapper } } - private static ICollection GetTestsInIsolation(string fullFilePath, IRunSettings? runSettings, out ICollection warnings) + private static ICollection GetTestsInIsolation(string fullFilePath, IRunSettings? runSettings, List warnings) { using MSTestAdapter.PlatformServices.Interface.ITestSourceHost isolationHost = PlatformServiceProvider.Instance.CreateTestSourceHost(fullFilePath, runSettings, frameworkHandle: null); @@ -117,6 +117,6 @@ private static ICollection GetTestsInIsolation(string fullFileP PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning(Resource.OlderTFMVersionFound); } - return assemblyEnumerator.EnumerateAssembly(fullFilePath, xml, out warnings); + return assemblyEnumerator.EnumerateAssembly(fullFilePath, xml, warnings); } } diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs index d84a72df10..179dcd9c4b 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs @@ -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; @@ -54,10 +53,8 @@ internal TypeEnumerator(Type type, string assemblyFilePath, ReflectHelper reflec /// /// Contains warnings if any, that need to be passed back to the caller. /// list of test cases. - internal virtual ICollection? Enumerate(out ICollection warnings) + internal virtual List? Enumerate(List warnings) { - warnings = new Collection(); - if (!_typeValidator.IsValidTestClass(_type, warnings)) { return null; @@ -72,11 +69,11 @@ internal TypeEnumerator(Type type, string assemblyFilePath, ReflectHelper reflec /// /// Contains warnings if any, that need to be passed back to the caller. /// List of Valid Tests. - internal Collection GetTests(ICollection warnings) + internal List GetTests(List warnings) { bool foundDuplicateTests = false; var foundTests = new HashSet(); - var tests = new Collection(); + var tests = new List(); // Test class is already valid. Verify methods. // PERF: GetRuntimeMethods is used here to get all methods, including non-public, and static methods. @@ -119,12 +116,11 @@ internal Collection GetTests(ICollection warnings) currentType = currentType.BaseType; } - return new Collection( - 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(); } /// diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs index 916c7da27a..89529b150c 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs @@ -49,7 +49,7 @@ internal TypeValidator(ReflectHelper reflectHelper, bool discoverInternals) /// The reflected type. /// Contains warnings if any, that need to be passed back to the caller. /// Return true if it is a valid test class. - internal virtual bool IsValidTestClass(Type type, ICollection warnings) + internal virtual bool IsValidTestClass(Type type, List 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 diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs b/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs index bc669c1e79..d81212d69c 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs @@ -58,7 +58,7 @@ internal virtual void DiscoverTestsInSource( ITestCaseDiscoverySink discoverySink, IDiscoveryContext? discoveryContext) { - ICollection? testElements = _assemblyEnumeratorWrapper.GetTests(source, discoveryContext?.RunSettings, out ICollection? warnings); + ICollection? testElements = _assemblyEnumeratorWrapper.GetTests(source, discoveryContext?.RunSettings, out List warnings); bool treatDiscoveryWarningsAsErrors = MSTestSettings.CurrentSettings.TreatDiscoveryWarningsAsErrors; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs index abd54ca45e..d09607fabc 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs @@ -26,7 +26,7 @@ public class AssemblyEnumeratorTests : TestContainer private readonly AssemblyEnumerator _assemblyEnumerator; private readonly TestablePlatformServiceProvider _testablePlatformServiceProvider; - private ICollection _warnings; + private readonly List _warnings; public AssemblyEnumeratorTests() { @@ -225,7 +225,7 @@ public void EnumerateAssemblyShouldReturnEmptyListWhenNoDeclaredTypes() _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); - Verify(_assemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings).Count == 0); + Verify(_assemblyEnumerator.EnumerateAssembly("DummyAssembly", null, _warnings).Count == 0); } public void EnumerateAssemblyShouldReturnEmptyListWhenNoTestElementsInAType() @@ -240,10 +240,10 @@ public void EnumerateAssemblyShouldReturnEmptyListWhenNoTestElementsInAType() .Returns([typeof(DummyTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); - testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out _warnings)) - .Returns((ICollection)null); + testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(_warnings)) + .Returns((List)null); - Verify(_assemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings).Count == 0); + Verify(_assemblyEnumerator.EnumerateAssembly("DummyAssembly", null, _warnings).Count == 0); } public void EnumerateAssemblyShouldReturnTestElementsForAType() @@ -259,10 +259,10 @@ public void EnumerateAssemblyShouldReturnTestElementsForAType() .Returns([typeof(DummyTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); - testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out _warnings)) - .Returns(new Collection { unitTestElement }); + testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(_warnings)) + .Returns(new List { unitTestElement }); - ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); + ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, _warnings); Verify(new Collection { unitTestElement }.SequenceEqual(testElements)); } @@ -272,7 +272,7 @@ public void EnumerateAssemblyShouldReturnMoreThanOneTestElementForAType() Mock mockAssembly = CreateMockTestableAssembly(); var testableAssemblyEnumerator = new TestableAssemblyEnumerator(); var unitTestElement = new UnitTestElement(new TestMethod("DummyMethod", "DummyClass", "DummyAssembly", false)); - var expectedTestElements = new Collection { unitTestElement, unitTestElement }; + var expectedTestElements = new List { unitTestElement, unitTestElement }; // Setup mocks mockAssembly.Setup(a => a.GetTypes()) @@ -281,10 +281,10 @@ public void EnumerateAssemblyShouldReturnMoreThanOneTestElementForAType() .Returns([typeof(DummyTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); - testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out _warnings)) + testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(_warnings)) .Returns(expectedTestElements); - ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); + ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, _warnings); Verify(expectedTestElements.SequenceEqual(testElements)); } @@ -294,7 +294,7 @@ public void EnumerateAssemblyShouldReturnMoreThanOneTestElementForMoreThanOneTyp Mock mockAssembly = CreateMockTestableAssembly(); var testableAssemblyEnumerator = new TestableAssemblyEnumerator(); var unitTestElement = new UnitTestElement(new TestMethod("DummyMethod", "DummyClass", "DummyAssembly", false)); - var expectedTestElements = new Collection { unitTestElement, unitTestElement }; + var expectedTestElements = new List { unitTestElement, unitTestElement }; // Setup mocks mockAssembly.Setup(a => a.GetTypes()) @@ -303,10 +303,10 @@ public void EnumerateAssemblyShouldReturnMoreThanOneTestElementForMoreThanOneTyp .Returns([typeof(DummyTestClass).GetTypeInfo(), typeof(DummyTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); - testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out _warnings)) + testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(_warnings)) .Returns(expectedTestElements); - ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); + ICollection testElements = testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, _warnings); expectedTestElements.Add(unitTestElement); expectedTestElements.Add(unitTestElement); @@ -317,7 +317,7 @@ public void EnumerateAssemblyShouldNotLogWarningsIfNonePresent() { Mock mockAssembly = CreateMockTestableAssembly(); var testableAssemblyEnumerator = new TestableAssemblyEnumerator(); - ICollection warningsFromTypeEnumerator = []; + List warningsFromTypeEnumerator = []; // Setup mocks mockAssembly.Setup(a => a.GetTypes()) @@ -326,9 +326,9 @@ public void EnumerateAssemblyShouldNotLogWarningsIfNonePresent() .Returns([typeof(InternalTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); - testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out warningsFromTypeEnumerator)); + testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(warningsFromTypeEnumerator)); - testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); + testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, _warnings); Verify(_warnings.Count == 0); } @@ -336,7 +336,7 @@ public void EnumerateAssemblyShouldLogWarningsIfPresent() { Mock mockAssembly = CreateMockTestableAssembly(); var testableAssemblyEnumerator = new TestableAssemblyEnumerator(); - ICollection warningsFromTypeEnumerator = new Collection + var warningsFromTypeEnumerator = new List { "DummyWarning", }; @@ -348,11 +348,12 @@ public void EnumerateAssemblyShouldLogWarningsIfPresent() .Returns([typeof(InternalTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); - testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out warningsFromTypeEnumerator)); + testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(_warnings)) + .Callback(() => _warnings.AddRange(warningsFromTypeEnumerator)); - testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); + testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, _warnings); - Verify(warningsFromTypeEnumerator.ToList().SequenceEqual(_warnings)); + Verify(warningsFromTypeEnumerator.SequenceEqual(_warnings)); } public void EnumerateAssemblyShouldHandleExceptionsWhileEnumeratingAType() @@ -368,9 +369,9 @@ public void EnumerateAssemblyShouldHandleExceptionsWhileEnumeratingAType() .Returns([typeof(InternalTestClass).GetTypeInfo()]); _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("DummyAssembly", false)) .Returns(mockAssembly.Object); - testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(out _warnings)).Throws(exception); + testableAssemblyEnumerator.MockTypeEnumerator.Setup(te => te.Enumerate(_warnings)).Throws(exception); - testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, out _warnings); + testableAssemblyEnumerator.EnumerateAssembly("DummyAssembly", null, _warnings); Verify(_warnings.ToList().Contains( string.Format( diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorWrapperTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorWrapperTests.cs index 8b3b433213..2fef0edc25 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorWrapperTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorWrapperTests.cs @@ -21,7 +21,7 @@ public class AssemblyEnumeratorWrapperTests : TestContainer private readonly AssemblyEnumeratorWrapper _testableAssemblyEnumeratorWrapper; private readonly TestablePlatformServiceProvider _testablePlatformServiceProvider; - private ICollection _warnings; + private List _warnings; public AssemblyEnumeratorWrapperTests() { diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs index 78c3b2998e..3e2e123c22 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs @@ -26,7 +26,7 @@ public partial class TypeEnumeratorTests : TestContainer private readonly TestablePlatformServiceProvider _testablePlatformServiceProvider; private readonly Mock _mockMessageLogger; - private ICollection _warnings; + private readonly List _warnings; public TypeEnumeratorTests() { @@ -58,7 +58,7 @@ protected override void Dispose(bool disposing) public void EnumerateShouldReturnNullIfTypeIsNotValid() { TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(IDummyInterface), string.Empty); - Verify(typeEnumerator.Enumerate(out _warnings) is null); + Verify(typeEnumerator.Enumerate(_warnings) is null); } public void EnumerateShouldReturnEmptyCollectionWhenNoValidTestMethodsExist() @@ -66,7 +66,7 @@ public void EnumerateShouldReturnEmptyCollectionWhenNoValidTestMethodsExist() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: false, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), string.Empty); - ICollection tests = typeEnumerator.Enumerate(out _warnings); + ICollection tests = typeEnumerator.Enumerate(_warnings); Verify(tests is not null); Verify(tests.Count == 0); @@ -81,7 +81,7 @@ public void GetTestsShouldReturnDeclaredTestMethods() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyBaseTestClass), Assembly.GetExecutingAssembly().FullName); - ICollection tests = typeEnumerator.Enumerate(out _warnings); + ICollection tests = typeEnumerator.Enumerate(_warnings); Verify(tests is not null); @@ -94,7 +94,7 @@ public void GetTestsShouldReturnBaseTestMethodsInSameAssembly() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyDerivedTestClass), Assembly.GetExecutingAssembly().FullName); - ICollection tests = typeEnumerator.Enumerate(out _warnings); + ICollection tests = typeEnumerator.Enumerate(_warnings); Verify(tests is not null); @@ -125,7 +125,7 @@ public void GetTestsShouldReturnBaseTestMethodsFromAnotherAssemblyByDefault() TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyDerivedTestClass), Assembly.GetExecutingAssembly().FullName); - ICollection tests = typeEnumerator.Enumerate(out _warnings); + ICollection tests = typeEnumerator.Enumerate(_warnings); Verify(tests is not null); @@ -155,7 +155,7 @@ public void GetTestsShouldReturnBaseTestMethodsFromAnotherAssemblyByConfiguratio SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyDerivedTestClass), Assembly.GetExecutingAssembly().FullName); - ICollection tests = typeEnumerator.Enumerate(out _warnings); + ICollection tests = typeEnumerator.Enumerate(_warnings); Verify(tests is not null); @@ -186,7 +186,7 @@ public void GetTestsShouldNotReturnBaseTestMethodsFromAnotherAssemblyByConfigura SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: false); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyDerivedTestClass), Assembly.GetExecutingAssembly().FullName); - ICollection tests = typeEnumerator.Enumerate(out _warnings); + ICollection tests = typeEnumerator.Enumerate(_warnings); Verify(tests is not null); @@ -200,7 +200,7 @@ public void GetTestsShouldNotReturnHiddenTestMethods() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyHidingTestClass), Assembly.GetExecutingAssembly().FullName); - ICollection tests = typeEnumerator.Enumerate(out _warnings); + ICollection tests = typeEnumerator.Enumerate(_warnings); Verify(tests is not null); @@ -219,7 +219,7 @@ public void GetTestsShouldReturnOverriddenTestMethods() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyOverridingTestClass), Assembly.GetExecutingAssembly().FullName); - ICollection tests = typeEnumerator.Enumerate(out _warnings); + ICollection tests = typeEnumerator.Enumerate(_warnings); Verify(tests is not null); @@ -242,7 +242,7 @@ public void GetTestsShouldNotReturnHiddenTestMethodsFromAnyLevel() SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummySecondHidingTestClass), Assembly.GetExecutingAssembly().FullName); - ICollection tests = typeEnumerator.Enumerate(out _warnings); + ICollection tests = typeEnumerator.Enumerate(_warnings); Verify(tests is not null); @@ -567,7 +567,7 @@ public void GetTestFromMethodShouldSetDisplayNameFromDataTestMethodAttribute() private void SetupTestClassAndTestMethods(bool isValidTestClass, bool isValidTestMethod, bool isMethodFromSameAssembly) { - _mockTypeValidator.Setup(tv => tv.IsValidTestClass(It.IsAny(), It.IsAny>())) + _mockTypeValidator.Setup(tv => tv.IsValidTestClass(It.IsAny(), It.IsAny>())) .Returns(isValidTestClass); _mockTestMethodValidator.Setup( tmv => tmv.IsValidTestMethod(It.IsAny(), It.IsAny(), It.IsAny>())).Returns(isValidTestMethod); From 88286f6325f11ec2c5519734bdb8bec527fe6fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 11 Dec 2024 13:35:01 +0100 Subject: [PATCH 101/273] Fix displaying progress in non-ansi terminal (#4320) --- .../OutputDevice/Terminal/NonAnsiTerminal.cs | 8 ++++---- .../OutputDevice/Terminal/TestNodeResultsState.cs | 2 -- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs index 2da9ab982c..3f91a8a4be 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs @@ -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('+'); @@ -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); diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs index d2532fdcd7..d0dc3f4056 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs @@ -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 GetRunningTasks(int maxCount) { var sortedDetails = _testNodeProgressStates From 33f94f8e54d6caf157b593fb5f455a4b38121945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 11 Dec 2024 16:44:54 +0100 Subject: [PATCH 102/273] Allow to disable test expansion on implementations of ITestDataSource (#4269) --- .../Discovery/AssemblyEnumerator.cs | 248 +++++++++--------- .../Discovery/TypeEnumerator.cs | 38 +-- .../MSTest.TestAdapter/Execution/TypeCache.cs | 44 +++- .../Helpers/ReflectHelper.cs | 11 + .../Attributes/DataSource/DataRowAttribute.cs | 5 +- .../DataSource/DynamicDataAttribute.cs | 5 +- .../TestDataSourceDiscoveryAttribute.cs | 8 +- .../TestDataSourceDiscoveryOption.cs | 5 + .../TestDataSourceOptionsAttribute.cs | 27 ++ .../ITestDataSourceUnfoldingCapability.cs | 38 +++ .../PublicAPI/PublicAPI.Unshipped.txt | 13 + .../DataExtensibilityTests.cs | 53 +++- .../Parameterized tests/DynamicDataTests.cs | 44 +++- .../DataExtensibilityTests.cs | 2 +- .../Parameterized tests/DynamicDataTests.cs | 2 +- .../DisableExpansionTests.cs | 67 +++++ .../TestDataSourceExTests.cs | 26 +- .../Discovery/AssemblyEnumeratorTests.cs | 12 +- .../Discovery/TypeEnumeratorTests.cs | 5 +- 19 files changed, 462 insertions(+), 191 deletions(-) create mode 100644 src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceOptionsAttribute.cs create mode 100644 src/TestFramework/TestFramework/Interfaces/ITestDataSourceUnfoldingCapability.cs create mode 100644 test/IntegrationTests/TestAssets/DynamicDataTestProject/DisableExpansionTests.cs diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs index dc95277fea..e810b570de 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs @@ -90,15 +90,26 @@ internal ICollection EnumerateAssembly( DataRowAttribute.TestIdGenerationStrategy = testIdGenerationStrategy; DynamicDataAttribute.TestIdGenerationStrategy = testIdGenerationStrategy; - TestDataSourceDiscoveryOption testDataSourceDiscovery = ReflectHelper.GetTestDataSourceDiscoveryOption(assembly) + TestDataSourceUnfoldingStrategy dataSourcesUnfoldingStrategy = ReflectHelper.GetTestDataSourceOptions(assembly)?.UnfoldingStrategy switch + { + // When strategy is auto we want to unfold + TestDataSourceUnfoldingStrategy.Auto => TestDataSourceUnfoldingStrategy.Unfold, + // When strategy is set, let's use it + { } value => value, + // When the attribute is not set, let's look at the legacy attribute +#pragma warning disable CS0612 // Type or member is obsolete #pragma warning disable CS0618 // Type or member is obsolete - - // When using legacy strategy, there is no point in trying to "read" data during discovery - // as the ID generator will ignore it. - ?? (testIdGenerationStrategy == TestIdGenerationStrategy.Legacy - ? TestDataSourceDiscoveryOption.DuringExecution - : TestDataSourceDiscoveryOption.DuringDiscovery); + null => (ReflectHelper.GetTestDataSourceDiscoveryOption(assembly), testIdGenerationStrategy) switch +#pragma warning restore CS0612 // Type or member is obsolete + { + (TestDataSourceDiscoveryOption.DuringExecution, _) => TestDataSourceUnfoldingStrategy.Fold, + // When using legacy strategy, there is no point in trying to "read" data during discovery + // as the ID generator will ignore it. + (null, TestIdGenerationStrategy.Legacy) => TestDataSourceUnfoldingStrategy.Fold, #pragma warning restore CS0618 // Type or member is obsolete + _ => TestDataSourceUnfoldingStrategy.Unfold, + }, + }; Dictionary? testRunParametersFromRunSettings = RunSettingsUtilities.GetTestRunParameters(runSettingsXml); foreach (Type type in types) @@ -109,7 +120,7 @@ internal ICollection EnumerateAssembly( } List testsInType = DiscoverTestsInType(assemblyFileName, testRunParametersFromRunSettings, type, warnings, discoverInternals, - testDataSourceDiscovery, testIdGenerationStrategy, fixturesTests); + dataSourcesUnfoldingStrategy, testIdGenerationStrategy, fixturesTests); tests.AddRange(testsInType); } @@ -192,15 +203,14 @@ internal static string GetLoadExceptionDetails(ReflectionTypeLoadException ex) /// The reflected assembly name. /// True to discover test classes which are declared internal in /// addition to test classes which are declared public. - /// to use when generating tests. /// to use when generating TestId. /// a TypeEnumerator instance. - internal virtual TypeEnumerator GetTypeEnumerator(Type type, string assemblyFileName, bool discoverInternals, TestDataSourceDiscoveryOption discoveryOption, TestIdGenerationStrategy testIdGenerationStrategy) + internal virtual TypeEnumerator GetTypeEnumerator(Type type, string assemblyFileName, bool discoverInternals, TestIdGenerationStrategy testIdGenerationStrategy) { var typeValidator = new TypeValidator(ReflectHelper, discoverInternals); var testMethodValidator = new TestMethodValidator(ReflectHelper, discoverInternals); - return new TypeEnumerator(type, assemblyFileName, ReflectHelper, typeValidator, testMethodValidator, discoveryOption, testIdGenerationStrategy); + return new TypeEnumerator(type, assemblyFileName, ReflectHelper, typeValidator, testMethodValidator, testIdGenerationStrategy); } private List DiscoverTestsInType( @@ -209,7 +219,7 @@ private List DiscoverTestsInType( Type type, List warningMessages, bool discoverInternals, - TestDataSourceDiscoveryOption discoveryOption, + TestDataSourceUnfoldingStrategy dataSourcesUnfoldingStrategy, TestIdGenerationStrategy testIdGenerationStrategy, HashSet fixturesTests) { @@ -225,24 +235,22 @@ private List DiscoverTestsInType( try { typeFullName = type.FullName; - TypeEnumerator testTypeEnumerator = GetTypeEnumerator(type, assemblyFileName, discoverInternals, discoveryOption, testIdGenerationStrategy); + TypeEnumerator testTypeEnumerator = GetTypeEnumerator(type, assemblyFileName, discoverInternals, testIdGenerationStrategy); List? unitTestCases = testTypeEnumerator.Enumerate(warningMessages); if (unitTestCases != null) { foreach (UnitTestElement test in unitTestCases) { - if (discoveryOption == TestDataSourceDiscoveryOption.DuringDiscovery) + if (_typeCache.GetTestMethodInfoForDiscovery(test.TestMethod) is { } testMethodInfo) { - Lazy testMethodInfo = GetTestMethodInfo(sourceLevelParameters, test); - // Add fixture tests like AssemblyInitialize, AssemblyCleanup, ClassInitialize, ClassCleanup. - if (MSTestSettings.CurrentSettings.ConsiderFixturesAsSpecialTests && testMethodInfo.Value is not null) + if (MSTestSettings.CurrentSettings.ConsiderFixturesAsSpecialTests) { - AddFixtureTests(testMethodInfo.Value, tests, fixturesTests); + AddFixtureTests(testMethodInfo, tests, fixturesTests); } - if (DynamicDataAttached(test, testMethodInfo, tests)) + if (TryUnfoldITestDataSources(test, testMethodInfo, dataSourcesUnfoldingStrategy, tests)) { continue; } @@ -264,46 +272,6 @@ private List DiscoverTestsInType( return tests; } - private Lazy GetTestMethodInfo(IDictionary sourceLevelParameters, UnitTestElement test) => - new(() => - { - // NOTE: From this place we don't have any path that would let the user write a message on the TestContext and we don't do - // anything with what would be printed anyway so we can simply use a simple StringWriter. - using var writer = new StringWriter(); - TestMethod testMethod = test.TestMethod; - MSTestAdapter.PlatformServices.Interface.ITestContext testContext = PlatformServiceProvider.Instance.GetTestContext(testMethod, writer, sourceLevelParameters); - return _typeCache.GetTestMethodInfo(testMethod, testContext, MSTestSettings.CurrentSettings.CaptureDebugTraces); - }); - - private static bool DynamicDataAttached(UnitTestElement test, Lazy testMethodInfo, List tests) - { - // It should always be `true`, but if any part of the chain is obsolete; it might not contain those. - // Since we depend on those properties, if they don't exist, we bail out early. - if (!test.TestMethod.HasManagedMethodAndTypeProperties) - { - return false; - } - - DynamicDataType originalDataType = test.TestMethod.DataType; - - // PERF: For perf we started setting DataType in TypeEnumerator, so when it is None we will not reach this line. - // But if we do run this code, we still reset it to None, because the code that determines if this is data drive test expects the value to be None - // and only sets it when needed. - // - // If you remove this line and acceptance tests still pass you are okay. - test.TestMethod.DataType = DynamicDataType.None; - - // The data source tests that we can process currently are those using attributes that - // implement ITestDataSource (i.e, DataRow and DynamicData attributes). - // However, for DataSourceAttribute, we currently don't have anyway to process it during discovery. - // (Note: this method is only called under discoveryOption == TestDataSourceDiscoveryOption.DuringDiscovery) - // So we want to return false from this method for non ITestDataSource (whether it's None or DataSourceAttribute). Otherwise, the test - // will be completely skipped which is wrong behavior. - return originalDataType == DynamicDataType.ITestDataSource && - testMethodInfo.Value != null && - TryProcessITestDataSourceTests(test, testMethodInfo.Value, tests); - } - private static void AddFixtureTests(TestMethodInfo testMethodInfo, List tests, HashSet fixtureTests) { string assemblyName = testMethodInfo.Parent.Parent.Assembly.GetName().Name!; @@ -384,100 +352,146 @@ static UnitTestElement GetFixtureTest(string classFullName, string assemblyLocat } } - private static bool TryProcessITestDataSourceTests(UnitTestElement test, TestMethodInfo testMethodInfo, List tests) + private static bool TryUnfoldITestDataSources(UnitTestElement test, TestMethodInfo testMethodInfo, TestDataSourceUnfoldingStrategy dataSourcesUnfoldingStrategy, List tests) { + // It should always be `true`, but if any part of the chain is obsolete; it might not contain those. + // Since we depend on those properties, if they don't exist, we bail out early. + if (!test.TestMethod.HasManagedMethodAndTypeProperties) + { + return false; + } + // We don't have a special method to filter attributes that are not derived from Attribute, so we take all // attributes and filter them. We don't have to care if there is one, because this method is only entered when // there is at least one (we determine this in TypeEnumerator.GetTestFromMethod. IEnumerable testDataSources = ReflectHelper.Instance.GetDerivedAttributes(testMethodInfo.MethodInfo, inherit: false).OfType(); + // We need to use a temporary list to avoid adding tests to the main list if we fail to expand any data source. + List tempListOfTests = new(); + try { - return ProcessITestDataSourceTests(test, new(testMethodInfo.MethodInfo, test.DisplayName), testDataSources, tests); + bool isDataDriven = false; + foreach (ITestDataSource dataSource in testDataSources) + { + isDataDriven = true; + if (!TryUnfoldITestDataSource(dataSource, dataSourcesUnfoldingStrategy, test, new(testMethodInfo.MethodInfo, test.DisplayName), tempListOfTests)) + { + // TODO: Improve multi-source design! + // Ideally we would want to consider each data source separately but when one source cannot be expanded, + // we will run all sources from the given method so we need to bail-out "globally". + return false; + } + } + + if (tempListOfTests.Count > 0) + { + tests.AddRange(tempListOfTests); + } + + return isDataDriven; } catch (Exception ex) { string message = string.Format(CultureInfo.CurrentCulture, Resource.CannotEnumerateIDataSourceAttribute, test.TestMethod.ManagedTypeName, test.TestMethod.ManagedMethodName, ex); PlatformServiceProvider.Instance.AdapterTraceLogger.LogInfo($"DynamicDataEnumerator: {message}"); + + if (tempListOfTests.Count > 0) + { + tests.AddRange(tempListOfTests); + } + return false; } } - private static bool ProcessITestDataSourceTests(UnitTestElement test, ReflectionTestMethodInfo methodInfo, IEnumerable testDataSources, - List tests) + private static bool TryUnfoldITestDataSource(ITestDataSource dataSource, TestDataSourceUnfoldingStrategy dataSourcesUnfoldingStrategy, UnitTestElement test, ReflectionTestMethodInfo methodInfo, List tests) { - foreach (ITestDataSource dataSource in testDataSources) + var unfoldingCapability = dataSource as ITestDataSourceUnfoldingCapability; + + // If the global strategy is to fold and local has no strategy or uses Auto then return false + if (dataSourcesUnfoldingStrategy == TestDataSourceUnfoldingStrategy.Fold + && (unfoldingCapability is null || unfoldingCapability.UnfoldingStrategy == TestDataSourceUnfoldingStrategy.Auto)) { - IEnumerable? data; + return false; + } + + // If the data source specifies the unfolding strategy as fold then return false + if (unfoldingCapability?.UnfoldingStrategy == TestDataSourceUnfoldingStrategy.Fold) + { + return false; + } + + // Otherwise, unfold the data source and verify it can be serialized. + IEnumerable? data; - // This code is to discover tests. To run the tests code is in TestMethodRunner.ExecuteDataSourceBasedTests. - // Any change made here should be reflected in TestMethodRunner.ExecuteDataSourceBasedTests as well. - data = dataSource.GetData(methodInfo); + // This code is to discover tests. To run the tests code is in TestMethodRunner.ExecuteDataSourceBasedTests. + // Any change made here should be reflected in TestMethodRunner.ExecuteDataSourceBasedTests as well. + data = dataSource.GetData(methodInfo); - if (!data.Any()) + if (!data.Any()) + { + if (!MSTestSettings.CurrentSettings.ConsiderEmptyDataSourceAsInconclusive) { - if (!MSTestSettings.CurrentSettings.ConsiderEmptyDataSourceAsInconclusive) - { - throw dataSource.GetExceptionForEmptyDataSource(methodInfo); - } + throw dataSource.GetExceptionForEmptyDataSource(methodInfo); + } - UnitTestElement discoveredTest = test.Clone(); - // Make the test not data driven, because it had no data. - discoveredTest.TestMethod.DataType = DynamicDataType.None; - discoveredTest.DisplayName = dataSource.GetDisplayName(methodInfo, null) ?? discoveredTest.DisplayName; + UnitTestElement discoveredTest = test.Clone(); + // Make the test not data driven, because it had no data. + discoveredTest.TestMethod.DataType = DynamicDataType.None; + discoveredTest.DisplayName = dataSource.GetDisplayName(methodInfo, null) ?? discoveredTest.DisplayName; - tests.Add(discoveredTest); + tests.Add(discoveredTest); - continue; - } + return true; + } - var testDisplayNameFirstSeen = new Dictionary(); - var discoveredTests = new List(); - int index = 0; + var testDisplayNameFirstSeen = new Dictionary(); + var discoveredTests = new List(); + int index = 0; - foreach (object?[] d in data) - { - UnitTestElement discoveredTest = test.Clone(); - discoveredTest.DisplayName = dataSource.GetDisplayName(methodInfo, d) ?? discoveredTest.DisplayName; + foreach (object?[] d in data) + { + UnitTestElement discoveredTest = test.Clone(); + discoveredTest.DisplayName = dataSource.GetDisplayName(methodInfo, d) ?? discoveredTest.DisplayName; - // If strategy is DisplayName and we have a duplicate test name don't expand the test, bail out. + // If strategy is DisplayName and we have a duplicate test name don't expand the test, bail out. #pragma warning disable CS0618 // Type or member is obsolete - if (test.TestMethod.TestIdGenerationStrategy == TestIdGenerationStrategy.DisplayName - && testDisplayNameFirstSeen.TryGetValue(discoveredTest.DisplayName!, out int firstIndexSeen)) - { - string warning = string.Format(CultureInfo.CurrentCulture, Resource.CannotExpandIDataSourceAttribute_DuplicateDisplayName, firstIndexSeen, index, discoveredTest.DisplayName); - warning = string.Format(CultureInfo.CurrentCulture, Resource.CannotExpandIDataSourceAttribute, test.TestMethod.ManagedTypeName, test.TestMethod.ManagedMethodName, warning); - PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning($"DynamicDataEnumerator: {warning}"); + if (test.TestMethod.TestIdGenerationStrategy == TestIdGenerationStrategy.DisplayName + && testDisplayNameFirstSeen.TryGetValue(discoveredTest.DisplayName!, out int firstIndexSeen)) + { + string warning = string.Format(CultureInfo.CurrentCulture, Resource.CannotExpandIDataSourceAttribute_DuplicateDisplayName, firstIndexSeen, index, discoveredTest.DisplayName); + warning = string.Format(CultureInfo.CurrentCulture, Resource.CannotExpandIDataSourceAttribute, test.TestMethod.ManagedTypeName, test.TestMethod.ManagedMethodName, warning); + PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning($"DynamicDataEnumerator: {warning}"); - // Duplicated display name so bail out. Caller will handle adding the original test. - return false; - } + // Duplicated display name so bail out. Caller will handle adding the original test. + return false; + } #pragma warning restore CS0618 // Type or member is obsolete - try - { - discoveredTest.TestMethod.SerializedData = DataSerializationHelper.Serialize(d); - discoveredTest.TestMethod.DataType = DynamicDataType.ITestDataSource; - } - catch (SerializationException ex) - { - string warning = string.Format(CultureInfo.CurrentCulture, Resource.CannotExpandIDataSourceAttribute_CannotSerialize, index, discoveredTest.DisplayName); - warning += Environment.NewLine; - warning += ex.ToString(); - warning = string.Format(CultureInfo.CurrentCulture, Resource.CannotExpandIDataSourceAttribute, test.TestMethod.ManagedTypeName, test.TestMethod.ManagedMethodName, warning); - PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning($"DynamicDataEnumerator: {warning}"); - - // Serialization failed for the type, bail out. Caller will handle adding the original test. - return false; - } - - discoveredTests.Add(discoveredTest); - testDisplayNameFirstSeen[discoveredTest.DisplayName!] = index++; + try + { + discoveredTest.TestMethod.SerializedData = DataSerializationHelper.Serialize(d); + discoveredTest.TestMethod.DataType = DynamicDataType.ITestDataSource; + } + catch (SerializationException ex) + { + string warning = string.Format(CultureInfo.CurrentCulture, Resource.CannotExpandIDataSourceAttribute_CannotSerialize, index, discoveredTest.DisplayName); + warning += Environment.NewLine; + warning += ex.ToString(); + warning = string.Format(CultureInfo.CurrentCulture, Resource.CannotExpandIDataSourceAttribute, test.TestMethod.ManagedTypeName, test.TestMethod.ManagedMethodName, warning); + PlatformServiceProvider.Instance.AdapterTraceLogger.LogWarning($"DynamicDataEnumerator: {warning}"); + + // Serialization failed for the type, bail out. Caller will handle adding the original test. + return false; } - tests.AddRange(discoveredTests); + discoveredTests.Add(discoveredTest); + testDisplayNameFirstSeen[discoveredTest.DisplayName!] = index++; } + tests.AddRange(discoveredTests); + return true; } } diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs index 179dcd9c4b..ca1eaf47a1 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs @@ -25,7 +25,6 @@ internal class TypeEnumerator private readonly TypeValidator _typeValidator; private readonly TestMethodValidator _testMethodValidator; private readonly TestIdGenerationStrategy _testIdGenerationStrategy; - private readonly TestDataSourceDiscoveryOption _discoveryOption; private readonly ReflectHelper _reflectHelper; /// @@ -37,7 +36,7 @@ internal class TypeEnumerator /// The validator for test classes. /// The validator for test methods. /// to use when generating TestId. - internal TypeEnumerator(Type type, string assemblyFilePath, ReflectHelper reflectHelper, TypeValidator typeValidator, TestMethodValidator testMethodValidator, TestDataSourceDiscoveryOption discoveryOption, TestIdGenerationStrategy testIdGenerationStrategy) + internal TypeEnumerator(Type type, string assemblyFilePath, ReflectHelper reflectHelper, TypeValidator typeValidator, TestMethodValidator testMethodValidator, TestIdGenerationStrategy testIdGenerationStrategy) { _type = type; _assemblyFilePath = assemblyFilePath; @@ -45,7 +44,6 @@ internal TypeEnumerator(Type type, string assemblyFilePath, ReflectHelper reflec _typeValidator = typeValidator; _testMethodValidator = testMethodValidator; _testIdGenerationStrategy = testIdGenerationStrategy; - _discoveryOption = discoveryOption; } /// @@ -154,22 +152,6 @@ internal UnitTestElement GetTestFromMethod(MethodInfo method, bool isDeclaredInT method.DeclaringType.Assembly); } - // PERF: When discovery option is set to DuringDiscovery, we will expand data on tests to one test case - // per data item. This will happen in AssemblyEnumerator. But AssemblyEnumerator does not have direct access to - // the method info or method attributes, so it would create a TestMethodInfo to see if the test is data driven. - // Creating TestMethodInfo is expensive and should be done only for a test that we know is data driven. - // - // So to optimize this we check if we have some data source attribute. Because here we have access to all attributes - // and we store that info in DataType. AssemblyEnumerator will pick this up and will get the real test data in the expensive way - // or it will skip over getting the data cheaply, when DataType = DynamicDataType.None. - // - // This needs to be done only when DuringDiscovery is set, because otherwise we would populate the DataType, but we would not populate - // and execution would not try to re-populate the data, because DataType is already set to data driven, so it would just throw error about empty data. - if (_discoveryOption == TestDataSourceDiscoveryOption.DuringDiscovery) - { - testMethod.DataType = GetDynamicDataType(method); - } - var testElement = new UnitTestElement(testMethod) { // Get compiler generated type name for async test method (either void returning or task returning). @@ -238,22 +220,4 @@ internal UnitTestElement GetTestFromMethod(MethodInfo method, bool isDeclaredInT return testElement; } - - private DynamicDataType GetDynamicDataType(MethodInfo method) - { - foreach (Attribute attribute in _reflectHelper.GetDerivedAttributes(method, inherit: true)) - { - if (AttributeComparer.IsDerived(attribute)) - { - return DynamicDataType.ITestDataSource; - } - - if (AttributeComparer.IsDerived(attribute)) - { - return DynamicDataType.DataSourceAttribute; - } - } - - return DynamicDataType.None; - } } diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index 0ce373c00e..676b4ce83b 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -89,9 +89,6 @@ public IEnumerable AssemblyInfoListWithExecutableCleanupMethod /// /// Get the test method info corresponding to the parameter test Element. /// - /// The test Method. - /// The test Context. - /// Indicates whether the test method should capture debug traces. /// The . public TestMethodInfo? GetTestMethodInfo(TestMethod testMethod, ITestContext testContext, bool captureDebugTraces) { @@ -109,7 +106,29 @@ public IEnumerable AssemblyInfoListWithExecutableCleanupMethod } // Get the testMethod - return ResolveTestMethod(testMethod, testClassInfo, testContext, captureDebugTraces); + return ResolveTestMethodInfo(testMethod, testClassInfo, testContext, captureDebugTraces); + } + + /// + /// Get the test method info corresponding to the parameter test Element. + /// + /// The . + public TestMethodInfo? GetTestMethodInfoForDiscovery(TestMethod testMethod) + { + Guard.NotNull(testMethod); + + // Get the classInfo (This may throw as GetType calls assembly.GetType(..,true);) + TestClassInfo? testClassInfo = GetClassInfo(testMethod); + + if (testClassInfo == null) + { + // This means the class containing the test method could not be found. + // Return null so we return a not found result. + return null; + } + + // Get the testMethod + return ResolveTestMethodInfoForDiscovery(testMethod, testClassInfo); } /// @@ -704,23 +723,18 @@ private void UpdateInfoIfTestInitializeOrCleanupMethod( /// cannot be found, or a function is found that returns non-void, the result is /// set to error. /// - /// The test Method. - /// The test Class Info. - /// The test Context. - /// Indicates whether the test method should capture debug traces. /// /// The TestMethodInfo for the given test method. Null if the test method could not be found. /// - private TestMethodInfo? ResolveTestMethod(TestMethod testMethod, TestClassInfo testClassInfo, ITestContext testContext, bool captureDebugTraces) + private TestMethodInfo ResolveTestMethodInfo(TestMethod testMethod, TestClassInfo testClassInfo, ITestContext testContext, bool captureDebugTraces) { DebugEx.Assert(testMethod != null, "testMethod is Null"); DebugEx.Assert(testClassInfo != null, "testClassInfo is Null"); MethodInfo methodInfo = GetMethodInfoForTestMethod(testMethod, testClassInfo); - ExpectedExceptionBaseAttribute? expectedExceptionAttribute = _reflectionHelper.ResolveExpectedExceptionHelper(methodInfo, testMethod); TimeoutInfo timeout = GetTestTimeout(methodInfo, testMethod); - + ExpectedExceptionBaseAttribute? expectedExceptionAttribute = _reflectionHelper.ResolveExpectedExceptionHelper(methodInfo, testMethod); var testMethodOptions = new TestMethodOptions(timeout, expectedExceptionAttribute, testContext, captureDebugTraces, GetTestMethodAttribute(methodInfo, testClassInfo)); var testMethodInfo = new TestMethodInfo(methodInfo, testClassInfo, testMethodOptions); @@ -729,6 +743,14 @@ private void UpdateInfoIfTestInitializeOrCleanupMethod( return testMethodInfo; } + private TestMethodInfo ResolveTestMethodInfoForDiscovery(TestMethod testMethod, TestClassInfo testClassInfo) + { + MethodInfo methodInfo = GetMethodInfoForTestMethod(testMethod, testClassInfo); + + // Let's build a fake options type as it won't be used. + return new TestMethodInfo(methodInfo, testClassInfo, new(TimeoutInfo.FromTimeout(-1), null, null, false, null)); + } + /// /// Provides the Test Method Extension Attribute of the TestClass. /// diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index 9c6a8093b0..c576d3b6bd 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -278,11 +278,22 @@ internal static TestIdGenerationStrategy GetTestIdGenerationStrategy(Assembly as /// Gets TestDataSourceDiscovery assembly level attribute. /// /// The test assembly. + [Obsolete] internal static TestDataSourceDiscoveryOption? GetTestDataSourceDiscoveryOption(Assembly assembly) => PlatformServiceProvider.Instance.ReflectionOperations.GetCustomAttributes(assembly, typeof(TestDataSourceDiscoveryAttribute)) .OfType() .FirstOrDefault()?.DiscoveryOption; + /// + /// Gets TestDataSourceOptions assembly level attribute. + /// + /// The test assembly. + /// The TestDataSourceOptionsAttribute if set. Null otherwise. + internal static TestDataSourceOptionsAttribute? GetTestDataSourceOptions(Assembly assembly) + => PlatformServiceProvider.Instance.ReflectionOperations.GetCustomAttributes(assembly, typeof(TestDataSourceOptionsAttribute)) + .OfType() + .FirstOrDefault(); + /// /// Get the parallelization behavior for a test method. /// diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs index 661f2fd551..270452d4db 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs @@ -11,7 +11,7 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// Attribute to define in-line data for a test method. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] -public class DataRowAttribute : Attribute, ITestDataSource +public class DataRowAttribute : Attribute, ITestDataSource, ITestDataSourceUnfoldingCapability { /// /// Initializes a new instance of the class. @@ -55,6 +55,9 @@ public DataRowAttribute(string?[]? stringArrayData) /// public string? DisplayName { get; set; } + /// + public TestDataSourceUnfoldingStrategy UnfoldingStrategy { get; set; } = TestDataSourceUnfoldingStrategy.Auto; + /// public IEnumerable GetData(MethodInfo methodInfo) => [Data]; diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs index 151685f3b8..2abb53a755 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs @@ -33,7 +33,7 @@ public enum DynamicDataSourceType /// Attribute to define dynamic data for a test method. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] -public sealed class DynamicDataAttribute : Attribute, ITestDataSource, ITestDataSourceEmptyDataSourceExceptionInfo +public sealed class DynamicDataAttribute : Attribute, ITestDataSource, ITestDataSourceEmptyDataSourceExceptionInfo, ITestDataSourceUnfoldingCapability { private readonly string _dynamicDataSourceName; private readonly DynamicDataSourceType _dynamicDataSourceType; @@ -84,6 +84,9 @@ public DynamicDataAttribute(string dynamicDataSourceName, Type dynamicDataDeclar /// public Type? DynamicDataDisplayNameDeclaringType { get; set; } + /// + public TestDataSourceUnfoldingStrategy UnfoldingStrategy { get; set; } = TestDataSourceUnfoldingStrategy.Auto; + /// public IEnumerable GetData(MethodInfo methodInfo) => DynamicDataProvider.Instance.GetData(_dynamicDataDeclaringType, _dynamicDataSourceType, _dynamicDataSourceName, methodInfo); diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryAttribute.cs index 9d7bd1f1db..660735c263 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryAttribute.cs @@ -7,6 +7,11 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// Specifies how to discover tests. /// [AttributeUsage(AttributeTargets.Assembly)] +#if NET6_0_OR_GREATER +[Obsolete("Attribute is obsolete and will be removed in v4, instead use 'TestDataSourceOptionsAttribute'.", DiagnosticId = "MSTESTOBS")] +#else +[Obsolete("Attribute is obsolete and will be removed in v4, instead use 'TestDataSourceOptionsAttribute'.")] +#endif public class TestDataSourceDiscoveryAttribute : Attribute { /// @@ -15,7 +20,8 @@ public class TestDataSourceDiscoveryAttribute : Attribute /// /// The to use when discovering tests. /// - public TestDataSourceDiscoveryAttribute(TestDataSourceDiscoveryOption discoveryOption) => DiscoveryOption = discoveryOption; + public TestDataSourceDiscoveryAttribute(TestDataSourceDiscoveryOption discoveryOption) + => DiscoveryOption = discoveryOption; /// /// Gets the discovery option. diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryOption.cs b/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryOption.cs index 46c3be787b..25b9c9b32e 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryOption.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryOption.cs @@ -6,6 +6,11 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// /// The supported discovery modes for tests. /// +#if NET6_0_OR_GREATER +[Obsolete("Type is obsolete and will be removed in v4, instead use 'TestDataSourceUnfoldingStrategy'.", DiagnosticId = "MSTESTOBS")] +#else +[Obsolete("Type is obsolete and will be removed in v4, instead use 'TestDataSourceUnfoldingStrategy'.")] +#endif public enum TestDataSourceDiscoveryOption { /// diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceOptionsAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceOptionsAttribute.cs new file mode 100644 index 0000000000..6550f28093 --- /dev/null +++ b/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceOptionsAttribute.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestTools.UnitTesting; + +/// +/// Specifies options for all of the current assembly. +/// +/// +/// These options can be override by individual attribute. +[AttributeUsage(AttributeTargets.Assembly, Inherited = false)] +public sealed class TestDataSourceOptionsAttribute : Attribute +{ + /// + /// Initializes a new instance of the class. + /// + /// + /// The to use when executing parameterized tests. + /// + public TestDataSourceOptionsAttribute(TestDataSourceUnfoldingStrategy unfoldingStrategy) + => UnfoldingStrategy = unfoldingStrategy; + + /// + /// Gets the test unfolding strategy. + /// + public TestDataSourceUnfoldingStrategy UnfoldingStrategy { get; } +} diff --git a/src/TestFramework/TestFramework/Interfaces/ITestDataSourceUnfoldingCapability.cs b/src/TestFramework/TestFramework/Interfaces/ITestDataSourceUnfoldingCapability.cs new file mode 100644 index 0000000000..2f5ced8910 --- /dev/null +++ b/src/TestFramework/TestFramework/Interfaces/ITestDataSourceUnfoldingCapability.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestTools.UnitTesting; + +/// +/// Specifies the capability of a test data source to define how parameterized tests should be executed, either as +/// individual test cases for each data row or as a single test case. This affects the test results and the UI +/// representation of the tests. +/// +public interface ITestDataSourceUnfoldingCapability +{ + TestDataSourceUnfoldingStrategy UnfoldingStrategy { get; } +} + +/// +/// Specifies how parameterized tests should be executed, either as individual test cases for each data row or as a +/// single test case. This affects the test results and the UI representation of the tests. +/// +public enum TestDataSourceUnfoldingStrategy : byte +{ + /// + /// MSTest will decide whether to unfold the parameterized test based on value from the assembly level attribute + /// . If no assembly level attribute is specified, then the default + /// configuration is to unfold. + /// + Auto, + + /// + /// Each data row is treated as a separate test case. + /// + Unfold, + + /// + /// The parameterized test is not unfolded; all data rows are treated as a single test case. + /// + Fold, +} diff --git a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt index ab058de62d..d3d4ae8281 100644 --- a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt @@ -1 +1,14 @@ #nullable enable +Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.UnfoldingStrategy.set -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.UnfoldingStrategy.set -> void +Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSourceUnfoldingCapability +Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSourceUnfoldingCapability.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceOptionsAttribute +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceOptionsAttribute.TestDataSourceOptionsAttribute(Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy unfoldingStrategy) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceOptionsAttribute.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy.Auto = 0 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy.Fold = 2 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy.Unfold = 1 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy diff --git a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DataExtensibilityTests.cs b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DataExtensibilityTests.cs index e36a2f78ef..636ac3737e 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DataExtensibilityTests.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DataExtensibilityTests.cs @@ -1,7 +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 System.Collections.Immutable; + using Microsoft.MSTestV2.CLIAutomation; +using Microsoft.VisualStudio.TestPlatform.ObjectModel; namespace MSTest.IntegrationTests; @@ -21,24 +24,36 @@ public void CustomTestDataSourceTests() string assemblyPath = GetAssetFullPath(TestAssetName); // Act - System.Collections.Immutable.ImmutableArray testCases = DiscoverTests(assemblyPath, "CustomTestDataSourceTestMethod1"); - System.Collections.Immutable.ImmutableArray testResults = RunTests(testCases); + ImmutableArray testCases = DiscoverTests(assemblyPath, "CustomTestDataSourceTestMethod1"); + ImmutableArray testResults = RunTests(testCases); // Assert VerifyE2E.ContainsTestsPassed(testResults, "CustomTestDataSourceTestMethod1 (1,2,3)", "CustomTestDataSourceTestMethod1 (4,5,6)"); } + public void CustomEmptyTestDataSourceTests() + { + // Arrange + string assemblyPath = GetAssetFullPath(TestAssetName); + + // Act + ImmutableArray testCases = DiscoverTests(assemblyPath, "CustomEmptyTestDataSourceTestMethod"); + ImmutableArray testResults = RunTests(testCases); + + // Assert + VerifyE2E.ContainsTestsFailed(testResults, new string[] { null }); + } + public void AssertExtensibilityTests() { // Arrange string assemblyPath = GetAssetFullPath(TestAssetName); // Act - System.Collections.Immutable.ImmutableArray testCases = DiscoverTests(assemblyPath, "FxExtensibilityTestProject.AssertExTest"); - System.Collections.Immutable.ImmutableArray testResults = RunTests(testCases); + ImmutableArray testCases = DiscoverTests(assemblyPath, "FxExtensibilityTestProject.AssertExTest"); + ImmutableArray testResults = RunTests(testCases); // Assert - VerifyE2E.ContainsTestsPassed(testResults, "BasicAssertExtensionTest", "ChainedAssertExtensionTest"); VerifyE2E.ContainsTestsFailed(testResults, "BasicFailingAssertExtensionTest", "ChainedFailingAssertExtensionTest"); } @@ -48,8 +63,8 @@ public void ExecuteCustomTestExtensibilityTests() string assemblyPath = GetAssetFullPath(TestAssetName); // Act - System.Collections.Immutable.ImmutableArray testCases = DiscoverTests(assemblyPath, "(Name~CustomTestMethod1)|(Name~CustomTestClass1)"); - System.Collections.Immutable.ImmutableArray testResults = RunTests(testCases); + ImmutableArray testCases = DiscoverTests(assemblyPath, "(Name~CustomTestMethod1)|(Name~CustomTestClass1)"); + ImmutableArray testResults = RunTests(testCases); // Assert VerifyE2E.ContainsTestsPassed( @@ -75,8 +90,8 @@ public void ExecuteCustomTestExtensibilityWithTestDataTests() string assemblyPath = GetAssetFullPath(TestAssetName); // Act - System.Collections.Immutable.ImmutableArray testCases = DiscoverTests(assemblyPath, "Name~CustomTestMethod2"); - System.Collections.Immutable.ImmutableArray testResults = RunTests(testCases); + ImmutableArray testCases = DiscoverTests(assemblyPath, "Name~CustomTestMethod2"); + ImmutableArray testResults = RunTests(testCases); // Assert VerifyE2E.TestsPassed( @@ -94,4 +109,24 @@ public void ExecuteCustomTestExtensibilityWithTestDataTests() "CustomTestMethod2 (\"C\")", "CustomTestMethod2 (\"C\")"); } + + public void WhenUsingCustomITestDataSourceWithExpansionDisabled_RespectSetting() + { + // Arrange + string assemblyPath = GetAssetFullPath(TestAssetName); + + // Act + ImmutableArray testCases = DiscoverTests(assemblyPath, "CustomDisableExpansionTestDataSourceTestMethod1"); + ImmutableArray testResults = RunTests(testCases); + + // Assert + Verify(testCases.Length == 1); + + VerifyE2E.TestsPassed( + testResults, + "CustomDisableExpansionTestDataSourceTestMethod1 (1,2,3)", + "CustomDisableExpansionTestDataSourceTestMethod1 (4,5,6)"); + + VerifyE2E.TestsFailed(testResults); + } } diff --git a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs index 952119a8bb..a370027ea9 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs @@ -1,7 +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 System.Collections.Immutable; + using Microsoft.MSTestV2.CLIAutomation; +using Microsoft.VisualStudio.TestPlatform.ObjectModel; namespace MSTest.IntegrationTests; @@ -15,8 +18,8 @@ public void ExecuteDynamicDataTests() string assemblyPath = GetAssetFullPath(TestAssetName); // Act - System.Collections.Immutable.ImmutableArray testCases = DiscoverTests(assemblyPath); - System.Collections.Immutable.ImmutableArray testResults = RunTests(testCases); + ImmutableArray testCases = DiscoverTests(assemblyPath, testCaseFilter: "ClassName~DynamicDataTests"); + ImmutableArray testResults = RunTests(testCases); // Assert VerifyE2E.TestsPassed( @@ -62,8 +65,8 @@ public void ExecuteDynamicDataTestsWithCategoryFilter() string assemblyPath = GetAssetFullPath(TestAssetName); // Act - System.Collections.Immutable.ImmutableArray testCases = DiscoverTests(assemblyPath, "TestCategory~DynamicDataWithCategory"); - System.Collections.Immutable.ImmutableArray testResults = RunTests(testCases); + ImmutableArray testCases = DiscoverTests(assemblyPath, "TestCategory~DynamicDataWithCategory"); + ImmutableArray testResults = RunTests(testCases); // Assert VerifyE2E.ContainsTestsPassed( @@ -73,4 +76,37 @@ public void ExecuteDynamicDataTestsWithCategoryFilter() VerifyE2E.FailedTestCount(testResults, 0); } + + public void ExecuteNonExpandableDynamicDataTests() + { + // Arrange + string assemblyPath = GetAssetFullPath(TestAssetName); + + // Act + ImmutableArray testCases = DiscoverTests(assemblyPath, testCaseFilter: "ClassName~DisableExpansionTests"); + ImmutableArray testResults = RunTests(testCases); + + // Assert + Verify(testCases.Length == 6); + + VerifyE2E.TestsPassed( + testResults, + "TestPropertySourceOnCurrentType (1,a)", + "TestPropertySourceOnCurrentType (2,b)", + "TestPropertySourceOnDifferentType (3,c)", + "TestPropertySourceOnDifferentType (4,d)", + "TestPropertyWithTwoSourcesAndSecondDisablesExpansion (1,a)", + "TestPropertyWithTwoSourcesAndSecondDisablesExpansion (2,b)", + "TestPropertyWithTwoSourcesAndSecondDisablesExpansion (3,c)", + "TestPropertyWithTwoSourcesAndSecondDisablesExpansion (4,d)", + "TestMethodSourceOnDifferentType (3,c)", + "TestMethodSourceOnDifferentType (4,d)", + "TestPropertyWithTwoSourcesAndFirstDisablesExpansion (1,a)", + "TestPropertyWithTwoSourcesAndFirstDisablesExpansion (2,b)", + "TestPropertyWithTwoSourcesAndFirstDisablesExpansion (3,c)", + "TestPropertyWithTwoSourcesAndFirstDisablesExpansion (4,d)", + "TestMethodSourceOnCurrentType (1,a)", + "TestMethodSourceOnCurrentType (2,b)"); + VerifyE2E.FailedTestCount(testResults, 0); + } } diff --git a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DataExtensibilityTests.cs b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DataExtensibilityTests.cs index 14ba3ffaf2..44f953da41 100644 --- a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DataExtensibilityTests.cs +++ b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DataExtensibilityTests.cs @@ -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() diff --git a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs index 8cebe74926..a9e134080f 100644 --- a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs +++ b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs @@ -14,7 +14,7 @@ public void ExecuteDynamicDataTests() // Arrange & Act InvokeVsTestForExecution( [TestAssetName], - testCaseFilter: "DynamicDataTest"); + testCaseFilter: "ClassName=DataSourceTestProject.DynamicDataTests"); // Assert ValidatePassedTests( diff --git a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DisableExpansionTests.cs b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DisableExpansionTests.cs new file mode 100644 index 0000000000..c22a047e3f --- /dev/null +++ b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DisableExpansionTests.cs @@ -0,0 +1,67 @@ +// 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.VisualStudio.TestTools.UnitTesting; + +namespace DynamicDataTestProject; + +[TestClass] +public sealed class DisableExpansionTests +{ + [TestMethod] + [DynamicData(nameof(PropertySource), UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)] + public void TestPropertySourceOnCurrentType(int a, string s) + { + } + + [TestMethod] + [DynamicData(nameof(MethodSource), DynamicDataSourceType.Method, UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)] + public void TestMethodSourceOnCurrentType(int a, string s) + { + } + + [TestMethod] + [DynamicData(nameof(PropertySource), typeof(DataSourceHelper), UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)] + public void TestPropertySourceOnDifferentType(int a, string s) + { + } + + [TestMethod] + [DynamicData(nameof(MethodSource), typeof(DataSourceHelper), DynamicDataSourceType.Method, UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)] + public void TestMethodSourceOnDifferentType(int a, string s) + { + } + + [TestMethod] + [DynamicData(nameof(PropertySource), UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)] + [DynamicData(nameof(PropertySource), typeof(DataSourceHelper))] + public void TestPropertyWithTwoSourcesAndFirstDisablesExpansion(int a, string s) + { + } + + [TestMethod] + [DynamicData(nameof(PropertySource))] + [DynamicData(nameof(PropertySource), typeof(DataSourceHelper), UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)] + public void TestPropertyWithTwoSourcesAndSecondDisablesExpansion(int a, string s) + { + } + + private static IEnumerable PropertySource => MethodSource(); + + private static IEnumerable MethodSource() + { + yield return new object[] { 1, "a" }; + yield return new object[] { 2, "b" }; + } +} + +public class DataSourceHelper +{ + public static IEnumerable PropertySource => MethodSource(); + + public static IEnumerable MethodSource() + { + yield return new object[] { 3, "c" }; + yield return new object[] { 4, "d" }; + } +} diff --git a/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/TestDataSourceExTests.cs b/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/TestDataSourceExTests.cs index b9a171c4b1..a040957911 100644 --- a/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/TestDataSourceExTests.cs +++ b/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/TestDataSourceExTests.cs @@ -13,13 +13,27 @@ public class TestDataSourceExTests { [TestMethod] [CustomTestDataSource] - [CustomEmptyTestDataSource] public void CustomTestDataSourceTestMethod1(int a, int b, int c) { Assert.AreEqual(1, a % 3); Assert.AreEqual(2, b % 3); Assert.AreEqual(0, c % 3); } + + [TestMethod] + [CustomDisableExpansionTestDataSource] + 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)] @@ -37,3 +51,13 @@ public class CustomEmptyTestDataSourceAttribute : Attribute, ITestDataSource public string GetDisplayName(MethodInfo methodInfo, object[] data) => data != null ? string.Format(CultureInfo.CurrentCulture, "{0} ({1})", methodInfo.Name, string.Join(",", data)) : null; } + +[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] +public class CustomDisableExpansionTestDataSourceAttribute : Attribute, ITestDataSource, ITestDataSourceUnfoldingCapability +{ + public TestDataSourceUnfoldingStrategy UnfoldingStrategy => TestDataSourceUnfoldingStrategy.Fold; + + public IEnumerable GetData(MethodInfo methodInfo) => [[1, 2, 3], [4, 5, 6]]; + + public string GetDisplayName(MethodInfo methodInfo, object[] data) => data != null ? string.Format(CultureInfo.CurrentCulture, "{0} ({1})", methodInfo.Name, string.Join(",", data)) : null; +} diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs index d09607fabc..b98e465b0c 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs @@ -396,7 +396,15 @@ private static Mock CreateMockTestableAssembly() mockAssembly .Setup(a => a.GetCustomAttributes( + typeof(TestDataSourceOptionsAttribute), + true)) + .Returns(Array.Empty()); + + mockAssembly + .Setup(a => a.GetCustomAttributes( +#pragma warning disable CS0618 // Type or member is obsolete typeof(TestDataSourceDiscoveryAttribute), +#pragma warning restore CS0618 // Type or member is obsolete true)) .Returns(Array.Empty()); @@ -429,14 +437,12 @@ internal TestableAssemblyEnumerator() reflectHelper.Object, typeValidator.Object, testMethodValidator.Object, - TestDataSourceDiscoveryOption.DuringExecution, TestIdGenerationStrategy.FullyQualified); } internal Mock MockTypeEnumerator { get; set; } - internal override TypeEnumerator GetTypeEnumerator(Type type, string assemblyFileName, bool discoverInternals, - TestDataSourceDiscoveryOption discoveryOption, TestIdGenerationStrategy testIdGenerationStrategy) + internal override TypeEnumerator GetTypeEnumerator(Type type, string assemblyFileName, bool discoverInternals, TestIdGenerationStrategy testIdGenerationStrategy) => MockTypeEnumerator.Object; } diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs index 3e2e123c22..12ef295dc1 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs @@ -575,16 +575,13 @@ private void SetupTestClassAndTestMethods(bool isValidTestClass, bool isValidTes rh => rh.IsMethodDeclaredInSameAssemblyAsType(It.IsAny(), It.IsAny())).Returns(isMethodFromSameAssembly); } - private TypeEnumerator GetTypeEnumeratorInstance(Type type, string assemblyName, - TestDataSourceDiscoveryOption discoveryOption = TestDataSourceDiscoveryOption.DuringExecution, - TestIdGenerationStrategy idGenerationStrategy = TestIdGenerationStrategy.FullyQualified) + private TypeEnumerator GetTypeEnumeratorInstance(Type type, string assemblyName, TestIdGenerationStrategy idGenerationStrategy = TestIdGenerationStrategy.FullyQualified) => new( type, assemblyName, _mockReflectHelper.Object, _mockTypeValidator.Object, _mockTestMethodValidator.Object, - discoveryOption, idGenerationStrategy); #endregion From 0e55e431e003277b56ffc6926dd2fe3cf0cfb40b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 12 Dec 2024 10:47:49 +0100 Subject: [PATCH 103/273] Move main to MSTest 3.8 and MTP 1.6 (#4323) --- eng/Versions.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Versions.props b/eng/Versions.props index 8da454c658..d7804ec652 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -1,9 +1,9 @@ - 3.7.0 + 3.8.0 - 1.5.0 + 1.6.0 preview From b097a45ee686e7daa4884b2a8c05fa8e4e5b24ee Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 12 Dec 2024 15:15:14 +0100 Subject: [PATCH 104/273] Display an error when '--maximum-failed-tests' is used with a framework not implementing the required capability (#4321) --- .../CommandLine/CommandLineManager.cs | 14 ++++++++--- .../CommandLine/ICommandLineManager.cs | 9 +++++++ ...axFailedTestsCommandLineOptionsProvider.cs | 11 ++++++-- .../TestApplicationBuilderExtensions.cs | 2 +- .../Hosts/TestHostBuilder.cs | 8 +++--- .../PublicAPI/PublicAPI.Unshipped.txt | 1 + .../Resources/PlatformResources.resx | 5 +++- .../Resources/xlf/PlatformResources.cs.xlf | 5 ++++ .../Resources/xlf/PlatformResources.de.xlf | 5 ++++ .../Resources/xlf/PlatformResources.es.xlf | 5 ++++ .../Resources/xlf/PlatformResources.fr.xlf | 5 ++++ .../Resources/xlf/PlatformResources.it.xlf | 5 ++++ .../Resources/xlf/PlatformResources.ja.xlf | 5 ++++ .../Resources/xlf/PlatformResources.ko.xlf | 5 ++++ .../Resources/xlf/PlatformResources.pl.xlf | 5 ++++ .../Resources/xlf/PlatformResources.pt-BR.xlf | 5 ++++ .../Resources/xlf/PlatformResources.ru.xlf | 5 ++++ .../Resources/xlf/PlatformResources.tr.xlf | 5 ++++ .../xlf/PlatformResources.zh-Hans.xlf | 5 ++++ .../xlf/PlatformResources.zh-Hant.xlf | 5 ++++ .../MaxFailedTestsExtensionTests.cs | 25 ++++++++++++++++++- 21 files changed, 127 insertions(+), 13 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineManager.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineManager.cs index 8729bdba2c..796a345413 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineManager.cs @@ -11,22 +11,28 @@ namespace Microsoft.Testing.Platform.CommandLine; internal sealed class CommandLineManager(IRuntimeFeature runtimeFeature, ITestApplicationModuleInfo testApplicationModuleInfo) : ICommandLineManager { - private readonly List> _commandLineProviderFactory = []; + private readonly List> _commandLineProviderFactory = []; private readonly IRuntimeFeature _runtimeFeature = runtimeFeature; private readonly ITestApplicationModuleInfo _testApplicationModuleInfo = testApplicationModuleInfo; public void AddProvider(Func commandLineProviderFactory) + { + Guard.NotNull(commandLineProviderFactory); + _commandLineProviderFactory.Add(_ => commandLineProviderFactory()); + } + + public void AddProvider(Func commandLineProviderFactory) { Guard.NotNull(commandLineProviderFactory); _commandLineProviderFactory.Add(commandLineProviderFactory); } - internal async Task BuildAsync(CommandLineParseResult parseResult) + internal async Task BuildAsync(CommandLineParseResult parseResult, IServiceProvider serviceProvider) { List commandLineOptionsProviders = []; - foreach (Func commandLineProviderFactory in _commandLineProviderFactory) + foreach (Func commandLineProviderFactory in _commandLineProviderFactory) { - ICommandLineOptionsProvider commandLineOptionsProvider = commandLineProviderFactory(); + ICommandLineOptionsProvider commandLineOptionsProvider = commandLineProviderFactory(serviceProvider); if (!await commandLineOptionsProvider.IsEnabledAsync()) { continue; diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineManager.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineManager.cs index 3155669676..9865b5e69f 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineManager.cs @@ -1,6 +1,8 @@ // 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.Diagnostics.CodeAnalysis; + using Microsoft.Testing.Platform.Extensions.CommandLine; namespace Microsoft.Testing.Platform.CommandLine; @@ -15,4 +17,11 @@ public interface ICommandLineManager /// /// The factory method for creating the command line options provider. void AddProvider(Func commandLineProviderFactory); + + /// + /// Adds a command line options provider. + /// + /// The factory method for creating the command line options provider, given a service provider. + [Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")] + void AddProvider(Func commandLineProviderFactory); } diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs index e81cc907b7..bf8842c405 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs @@ -3,14 +3,16 @@ using System.Globalization; +using Microsoft.Testing.Platform.Capabilities.TestFramework; using Microsoft.Testing.Platform.Extensions; using Microsoft.Testing.Platform.Extensions.CommandLine; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Resources; +using Microsoft.Testing.Platform.Services; namespace Microsoft.Testing.Platform.CommandLine; -internal sealed class MaxFailedTestsCommandLineOptionsProvider(IExtension extension) : ICommandLineOptionsProvider +internal sealed class MaxFailedTestsCommandLineOptionsProvider(IExtension extension, IServiceProvider serviceProvider) : ICommandLineOptionsProvider { internal const string MaxFailedTestsOptionKey = "maximum-failed-tests"; @@ -44,10 +46,15 @@ public Task ValidateOptionArgumentsAsync(CommandLineOption com // The idea is that we stop the execution when we *reach* the max failed tests, not when *exceed*. // So the value 1 means, stop execution on the first failure. return int.TryParse(arg, out int maxFailedTestsResult) && maxFailedTestsResult > 0 - ? ValidationResult.ValidTask + ? ValidateCapabilityAsync() : ValidationResult.InvalidTask(string.Format(CultureInfo.InvariantCulture, PlatformResources.MaxFailedTestsMustBePositive, arg)); } throw ApplicationStateGuard.Unreachable(); } + + private Task ValidateCapabilityAsync() + => serviceProvider.GetTestFrameworkCapabilities().Capabilities.OfType().Any() + ? ValidationResult.ValidTask + : ValidationResult.InvalidTask(PlatformResources.AbortForMaxFailedTestsCapabilityNotAvailable); } diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs index bae0af6c00..247c72a156 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs @@ -22,5 +22,5 @@ public static void AddTreeNodeFilterService(this ITestApplicationBuilder testApp /// The test application builder. [Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")] public static void AddMaximumFailedTestsService(this ITestApplicationBuilder builder, IExtension extension) - => builder.CommandLine.AddProvider(() => new MaxFailedTestsCommandLineOptionsProvider(extension)); + => builder.CommandLine.AddProvider(serviceProvider => new MaxFailedTestsCommandLineOptionsProvider(extension, serviceProvider)); } diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs index b071f4fb9f..5f27a72103 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs @@ -201,7 +201,7 @@ public async Task BuildAsync( // Build the command line service - we need special treatment because is possible that an extension query it during the creation. // Add Retry default argument commandlines - CommandLineHandler commandLineHandler = await ((CommandLineManager)CommandLine).BuildAsync(loggingState.CommandLineParseResult); + CommandLineHandler commandLineHandler = await ((CommandLineManager)CommandLine).BuildAsync(loggingState.CommandLineParseResult, serviceProvider); // Set the concrete command line options to the proxy. commandLineOptionsProxy.SetCommandLineOptions(commandLineHandler); @@ -247,6 +247,9 @@ public async Task BuildAsync( await testFrameworkCapabilitiesAsyncInitializable.InitializeAsync(); } + // Register the test framework capabilities to be used by services + serviceProvider.AddService(testFrameworkCapabilities); + // If command line is not valid we return immediately. ValidationResult commandLineValidationResult = await CommandLineOptionsValidator.ValidateAsync( loggingState.CommandLineParseResult, @@ -254,9 +257,6 @@ public async Task BuildAsync( commandLineHandler.ExtensionsCommandLineOptionsProviders, commandLineHandler); - // Register the test framework capabilities to be used by services - serviceProvider.AddService(testFrameworkCapabilities); - if (!loggingState.CommandLineParseResult.HasTool && !commandLineValidationResult.IsValid) { await DisplayBannerIfEnabledAsync(loggingState, proxyOutputDevice, testFrameworkCapabilities); diff --git a/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt b/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt index 1d1c2b5ca1..6b57520132 100644 --- a/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt @@ -8,6 +8,7 @@ Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData.Message.g Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData.WarningMessageOutputDeviceData(string! message) -> void [TPEXP]Microsoft.Testing.Platform.Capabilities.TestFramework.IGracefulStopTestExecutionCapability [TPEXP]Microsoft.Testing.Platform.Capabilities.TestFramework.IGracefulStopTestExecutionCapability.StopTestExecutionAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! +[TPEXP]Microsoft.Testing.Platform.CommandLine.ICommandLineManager.AddProvider(System.Func! commandLineProviderFactory) -> void [TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty [TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutput.get -> string! [TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutput.init -> void diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx index 4047fa6895..4ca08c4751 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx +++ b/src/Platform/Microsoft.Testing.Platform/Resources/PlatformResources.resx @@ -713,4 +713,7 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. {0} is the number of max failed tests. - + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index 95c3be44f2..ca36bd9618 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index 5ad7e52816..cfc90b90b2 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index 58c731750f..574d5a6100 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index 6529f58252..db05b6bf0f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index 15d86d4003..88f67644df 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index 18e1d555d3..1a1153b17d 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index c8b3cbeb40..6cdc2939a2 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index 010f80b6d0..76988a0949 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index 6046c82389..f7bc2cd692 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index 59ba762b05..3d61daf175 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index bbaf34f0ff..8fdc73e97e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 1e6719edca..78ea6cc7c5 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index 5d8b20aad0..99c5b7b0c9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -2,6 +2,11 @@ + + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + + Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs index 1f9883dbec..7456dea256 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs @@ -26,6 +26,18 @@ public async Task TestMaxFailedTestsShouldCallStopTestExecutionAsync() testHostResult.AssertOutputContainsSummary(failed: 3, passed: 3, skipped: 0); } + public async Task WhenCapabilityIsMissingShouldFail() + { + var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, TargetFrameworks.NetCurrent.Arguments); + TestHostResult testHostResult = await testHost.ExecuteAsync("--maximum-failed-tests 2", environmentVariables: new() + { + ["DO_NOT_ADD_CAPABILITY"] = "1", + }); + + testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); + testHostResult.AssertOutputContains("The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature."); + } + [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) { @@ -127,7 +139,18 @@ public async Task ExecuteRequestAsync(ExecuteRequestContext context) internal class Capabilities : ITestFrameworkCapabilities { - IReadOnlyCollection ICapabilities.Capabilities => [GracefulStop.Instance]; + IReadOnlyCollection ICapabilities.Capabilities + { + get + { + if (Environment.GetEnvironmentVariable("DO_NOT_ADD_CAPABILITY") == "1") + { + return []; + } + + return [GracefulStop.Instance]; + } + } } #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. From 5628f5f7c451abcf53e44ccde9d2ae1b9d25d396 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 12 Dec 2024 06:31:43 -0800 Subject: [PATCH 105/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2600379 --- .../Resources/xlf/PlatformResources.cs.xlf | 10 +++++----- .../Resources/xlf/PlatformResources.de.xlf | 10 +++++----- .../Resources/xlf/PlatformResources.es.xlf | 8 ++++---- .../Resources/xlf/PlatformResources.fr.xlf | 8 ++++---- .../Resources/xlf/PlatformResources.it.xlf | 10 +++++----- .../Resources/xlf/PlatformResources.ja.xlf | 8 ++++---- .../Resources/xlf/PlatformResources.ko.xlf | 10 +++++----- .../Resources/xlf/PlatformResources.pl.xlf | 10 +++++----- .../Resources/xlf/PlatformResources.pt-BR.xlf | 8 ++++---- .../Resources/xlf/PlatformResources.ru.xlf | 8 ++++---- .../Resources/xlf/PlatformResources.tr.xlf | 10 +++++----- .../Resources/xlf/PlatformResources.zh-Hans.xlf | 8 ++++---- .../Resources/xlf/PlatformResources.zh-Hant.xlf | 8 ++++---- 13 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index ca36bd9618..dd8647cf1b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Rozšíření, které podporuje --maximum-failed-tests Když se dosáhne prahové hodnoty pro dané chyby, testovací běh se přeruší. @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + Možnost --maximum-failed-tests musí být kladné celé číslo. Hodnota '{0}' není platná. @@ -403,7 +403,7 @@ and {0} more - and {0} more + a ještě {0} @@ -552,7 +552,7 @@ Dostupné hodnoty jsou Trace, Debug, Information, Warning, Error a Critical. Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Určuje maximální počet neúspěšných testů, které při překročení přeruší testovací běh. @@ -645,7 +645,7 @@ Může mít jenom jeden argument jako řetězec ve formátu <value>[h|m|s] Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Testovací relace se přerušuje, protože se dosáhlo chyb ('{0}') zadaných možností --maximum-failed-tests. {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index cfc90b90b2..a14a2a4f57 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Erweiterung zur Unterstützung von "--maximum-failed-tests". Wenn ein angegebener Schwellenwert für Fehler erreicht ist, wird der Testlauf abgebrochen. @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + Die Option "--maximum-failed-tests" muss eine positive ganze Zahl sein. Der Wert '{0}' ist ungültig. @@ -403,7 +403,7 @@ and {0} more - and {0} more + und {0} weitere @@ -552,7 +552,7 @@ Die verfügbaren Werte sind "Trace", "Debug", "Information", "Warning", "Error" Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Gibt die maximale Anzahl von Testfehlern an, bei deren Überschreiten der Testlauf abgebrochen wird. @@ -645,7 +645,7 @@ Nimmt ein Argument als Zeichenfolge im Format <value>[h|m|s], wobei "value Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Die Testsitzung wird aufgrund von Erreichensfehlern ('{0}') abgebrochen, die durch die Option "--maximum-failed-tests" angegeben wurden. {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index 574d5a6100..934de6ec87 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extensión usada para admitir "--maximum-failed-tests". Cuando se alcance un umbral de errores determinado, se anulará la serie de pruebas. @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + La opción '--maximum-failed-tests' debe ser un entero positivo. El valor '{0}' no es válido. @@ -552,7 +552,7 @@ Los valores disponibles son 'Seguimiento', 'Depurar', 'Información', 'Advertenc Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Especifica un número máximo de errores de prueba que, si se superan, anularán la serie de pruebas. @@ -645,7 +645,7 @@ Toma un argumento como cadena con el formato <value>[h|m|s] donde 'value' Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + La sesión de prueba se está anulando debido a errores ('{0}') especificados por la opción "--maximum-failed-tests". {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index db05b6bf0f..4637ed0d88 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extension utilisée pour prendre en charge '--maximum-failed-tests'. Quand un seuil d’échecs donné est atteint, la série de tests est abandonnée. @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + L’option '--maximum-failed-tests' doit être un entier positif. La valeur '{0}' n’est pas valide. @@ -552,7 +552,7 @@ Les valeurs disponibles sont « Trace », « Debug », « Information », Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Spécifie le nombre maximal d’échecs de tests qui, lorsqu’ils sont dépassés, abandonnent la série de tests. @@ -645,7 +645,7 @@ Prend un argument sous forme de chaîne au format <value>[h|m|s] où « v Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + La session de test est en cours d’abandon en raison d’échecs ('{0}') spécifiés par l’option '--maximum-failed-tests'. {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index 88f67644df..c2d8296fd9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Estensione usata per supportare '--maximum-failed-tests'. Quando viene raggiunta una soglia di errori specificata, l'esecuzione dei test verrà interrotta. @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + L'opzione '--maximum-failed-tests' deve essere un numero intero positivo. Il valore '{0}' non è valido. @@ -403,7 +403,7 @@ and {0} more - and {0} more + e altri {0} @@ -552,7 +552,7 @@ I valori disponibili sono 'Trace', 'Debug', 'Information', 'Warning', 'Error' e Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Specifica un numero massimo di errori di test che, se superati, interromperanno l'esecuzione dei test. @@ -645,7 +645,7 @@ Acquisisce un argomento come stringa nel formato <value>[h|m|s] dove 'valu Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + La sessione di test verrà interrotta perché sono stati individuati errori ('{0}') specificati dall'opzione '--maximum-failed-tests'. {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index 1a1153b17d..573ec36499 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + '--maximum-failed-tests' をサポートするために使用される拡張機能。指定されたエラーのしきい値に達すると、テストの実行が中止されます。 @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + オプション '--maximum-failed-tests' は正の整数である必要があります。'{0}' 値が無効です。 @@ -553,7 +553,7 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + テストの実行を中止するテスト エラーの最大数を指定します。 @@ -646,7 +646,7 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + '--maximum-failed-tests' オプションで指定されたエラー ('{0}') に達したため、テスト セッションを中止しています。 {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index 6cdc2939a2..d90a919159 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + '--maximum-failed-tests'를 지원하는 데 사용되는 확장입니다. 지정된 실패 임계값에 도달하면 테스트 실행이 중단됩니다. @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + '--maximum-failed-tests' 옵션은 양의 정수여야 합니다. '{0}' 값이 잘못되었습니다. @@ -403,7 +403,7 @@ and {0} more - and {0} more + 외 {0}개 @@ -552,7 +552,7 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + 테스트 실행을 중단하는 최대 테스트 실패 수를 지정합니다. @@ -645,7 +645,7 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + '--maximum-failed-tests' 옵션에 지정된 실패('{0}')에 도달하여 테스트 세션이 중단됩니다. {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index 76988a0949..b65260f0e7 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Rozszerzenie używane do obsługi "--maximum-failed-tests". Po osiągnięciu podanego progu niepowodzeń przebieg testu zostanie przerwany. @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + Opcja "--maximum-failed-tests" musi być dodatnią liczbą całkowitą. Wartość '{0}' jest nieprawidłowa. @@ -403,7 +403,7 @@ and {0} more - and {0} more + i {0} więcej @@ -552,7 +552,7 @@ Dostępne wartości to „Trace”, „Debug”, „Information”, „Warning Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Określa maksymalną liczbę niepowodzeń testów, które po przekroczeniu spowoduje przerwanie przebiegu testu. @@ -645,7 +645,7 @@ Pobiera jeden argument jako ciąg w formacie <value>[h|m|s], gdzie element Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Sesja testowa jest przerywana z powodu błędów ('{0}') określonych przez opcję "--maximum-failed-tests". {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index f7bc2cd692..1230bc1a6f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Extensão usada para dar suporte a '--maximum-failed-tests'. Quando um determinado limite de falhas for atingido, a execução de teste será anulada. @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + A opção '--maximum-failed-tests' deve ser um inteiro positivo. O valor '{0}' é inválido. @@ -552,7 +552,7 @@ Os valores disponíveis são 'Rastreamento', 'Depuração', 'Informação', 'Avi Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Especifica um número máximo de falhas de teste que, quando excedido, anularão a execução de teste. @@ -645,7 +645,7 @@ Recebe um argumento como cadeia de caracteres no formato <valor>[h|m|s] em Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + A sessão de teste está sendo anulada devido a falhas ('{0}') especificadas pela opção '--maximum-failed-tests'. {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index 3d61daf175..4530a36896 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + Расширение, используемое для поддержки "--maximum-failed-tests". При превышении заданного порогового значения сбоев тестовый запуск будет прерван. @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + Параметр "--maximum-failed-tests" должен быть положительным целым числом. Недопустимое '{0}' значение. @@ -552,7 +552,7 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Указывает максимальное число сбоев тестов, которые при превышении прервют тестовый запуск. @@ -645,7 +645,7 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + Тестовый сеанс прерывается из-за сбоев ('{0}'), указанных параметром "--maximum-failed-tests". {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index 8fdc73e97e..c3c720d6a1 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + '--maximum-failed-tests' desteği için kullanılan uzantı. Belirtilen hatalar eşiğine ulaşıldığında test çalıştırması durdurulacak. @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + '--maximum-failed-tests' seçeneği pozitif bir tamsayı olmalıdır. Belirtilen '{0}' geçerli değil. @@ -403,7 +403,7 @@ and {0} more - and {0} more + ve {0} tane daha @@ -552,7 +552,7 @@ Kullanılabilir değerler: 'Trace', 'Debug', 'Information', 'Warning', 'Error' v Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + Aşıldığında test çalıştırmasını durduracak en fazla test hatası sayısını belirtir. @@ -645,7 +645,7 @@ Bir bağımsız değişkeni, 'value' değerinin kayan olduğu <value>[h|m| Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + '--maximum-failed-tests' seçeneği tarafından belirtilen hatalara ('{0}') ulaşılamama nedeniyle test oturumu iptal edildi. {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 78ea6cc7c5..148ac2f744 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + 用于支持 “--maximum-failed-tests” 的扩展。达到给定失败阈值时,将中止测试运行。 @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + 选项 “--maximum-failed-tests” 必须是正整数。值 '{0}' 无效。 @@ -552,7 +552,7 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + 指定超过测试失败数后将中止测试运行的最大数目。 @@ -645,7 +645,7 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + 由于达到“--maximum-failed-tests”选项指定的失败 ('{0}'),测试会话正在中止。 {0} is the number of max failed tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index 99c5b7b0c9..874ce23cfc 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -9,7 +9,7 @@ Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. - Extension used to support '--maximum-failed-tests'. When a given failures threshold is reached, the test run will be aborted. + 用來支援 『--maximum-failed-tests』 的延伸模組。達到指定的失敗閾值時,測試回合將會中止。 @@ -383,7 +383,7 @@ The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. - The option '--maximum-failed-tests' must be a positive integer. The value '{0}' is not valid. + 選項 '--maximum-failed-tests' 必須是正整數。值 '{0}' 無效。 @@ -552,7 +552,7 @@ The available values are 'Trace', 'Debug', 'Information', 'Warning', 'Error', an Specifies a maximum number of test failures that, when exceeded, will abort the test run. - Specifies a maximum number of test failures that, when exceeded, will abort the test run. + 指定超過此數目時,測試失敗次數上限會中止測試回合。 @@ -645,7 +645,7 @@ Takes one argument as string in the format <value>[h|m|s] where 'value' is Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. - Test session is aborting due to reaching failures ('{0}') specified by the '--maximum-failed-tests' option. + 測試會話正在中止,因為達到失敗 ('{0}') 『--maximum-failed-tests』 選項指定。 {0} is the number of max failed tests. From bf1ab51834af086ceaad373372311b74524032c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 12 Dec 2024 16:46:38 +0100 Subject: [PATCH 106/273] Upload test results for all OSes (#4327) --- azure-pipelines-official.yml | 11 ++++++++++- azure-pipelines.yml | 36 +++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index c1c6ae1765..92e6a3d3f8 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -159,7 +159,7 @@ extends: displayName: 'Publish Test Results folders' inputs: PathtoPublish: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - ArtifactName: TestResults + ArtifactName: TestResults_Windows condition: failed() - task: NuGetAuthenticate@1 @@ -196,6 +196,15 @@ extends: name: Test displayName: Tests + # This step is only helpful for diagnosing some issues with vstest/test host that would not appear + # through the console or trx + - task: 1ES.PublishBuildArtifacts@1 + displayName: 'Publish Test Results folders' + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + ArtifactName: TestResults_Linux + condition: failed() + - ${{ if eq(variables['Build.SourceBranchName'], 'main') }}: - template: /eng/common/templates-official/job/onelocbuild.yml@self parameters: diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 224aee03bd..f5d636894e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -104,23 +104,23 @@ stages: name: Test displayName: Test - # Upload code coverage to codecov.io - - script: $(Build.SourcesDirectory)/.dotnet/dotnet msbuild -restore - eng/CodeCoverage.proj - /p:Configuration=$(_BuildConfig) - /bl:$(BUILD.SOURCESDIRECTORY)\artifacts\log\$(_BuildConfig)\CodeCoverage.binlog - displayName: Upload coverage to codecov.io - condition: and(succeeded(), eq(variables._BuildConfig, 'Debug')) - # This step is only helpful for diagnosing some issues with vstest/test host that would not appear # through the console or trx - task: PublishBuildArtifacts@1 displayName: 'Publish Test Results folders' inputs: PathtoPublish: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' - ArtifactName: TestResults + ArtifactName: TestResults_Windows_$(_BuildConfig) condition: failed() + # Upload code coverage to codecov.io + - script: $(Build.SourcesDirectory)/.dotnet/dotnet msbuild -restore + eng/CodeCoverage.proj + /p:Configuration=$(_BuildConfig) + /bl:$(BUILD.SOURCESDIRECTORY)\artifacts\log\$(_BuildConfig)\CodeCoverage.binlog + displayName: Upload coverage to codecov.io + condition: and(succeeded(), eq(variables._BuildConfig, 'Debug')) + - job: Linux timeoutInMinutes: 90 pool: @@ -150,6 +150,15 @@ stages: name: Test displayName: Tests + # This step is only helpful for diagnosing some issues with vstest/test host that would not appear + # through the console or trx + - task: PublishBuildArtifacts@1 + displayName: 'Publish Test Results folders' + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + ArtifactName: TestResults_Linux_$(_BuildConfig) + condition: failed() + - job: MacOS timeoutInMinutes: 90 pool: @@ -179,3 +188,12 @@ stages: ./test.sh --configuration $(_BuildConfig) --ci --test --integrationTest --nobl name: Test displayName: Tests + + # This step is only helpful for diagnosing some issues with vstest/test host that would not appear + # through the console or trx + - task: PublishBuildArtifacts@1 + displayName: 'Publish Test Results folders' + inputs: + PathtoPublish: '$(Build.SourcesDirectory)/artifacts/TestResults/$(_BuildConfig)' + ArtifactName: TestResults_MacOs_$(_BuildConfig) + condition: failed() From 1a4d2a3320108423601f5d7b73f59e5b84d0eafb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Thu, 12 Dec 2024 16:59:20 +0100 Subject: [PATCH 107/273] Add source build to official build (#4329) --- azure-pipelines-official.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/azure-pipelines-official.yml b/azure-pipelines-official.yml index 92e6a3d3f8..56f4ea0895 100644 --- a/azure-pipelines-official.yml +++ b/azure-pipelines-official.yml @@ -92,6 +92,7 @@ extends: enablePublishBuildAssets: true enablePublishUsingPipelines: true enableTelemetry: true + enableSourceBuild: true jobs: - job: Windows timeoutInMinutes: 90 From 86956611a0fedbe80de4a31cebae27acd658e259 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 13 Dec 2024 08:02:26 +0100 Subject: [PATCH 108/273] Improve doc comment (#4335) --- src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index c576d3b6bd..32b0071fb5 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -36,6 +36,9 @@ internal class ReflectHelper : MarshalByRefObject /// /// Checks to see if a member or type is decorated with the given attribute. The type is checked exactly. If attribute is derived (inherits from) a class, e.g. [MyTestClass] from [TestClass] it won't match if you look for [TestClass]. The inherit parameter does not impact this checking. /// + /// + /// Note that because derived attribute types are not considered, should be sealed. + /// /// Attribute to search for by fully qualified name. /// Member/Type to test. /// Inspect inheritance chain of the member or class. E.g. if parent class has this attribute defined. From c1651d5562227f28a9c8081a5c87b50f971b929a Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 13 Dec 2024 08:04:50 +0100 Subject: [PATCH 109/273] Fix incorrect doc comment (#4334) --- src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index 32b0071fb5..a17a0bbaf2 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -161,7 +161,7 @@ public virtual bool IsDerivedAttributeDefined(Type type, bool inheri public override object InitializeLifetimeService() => null!; /// - /// Gets first attribute that matches the type (but is not derived from it). Use this together with attribute that does not allow multiple. + /// Gets first attribute that matches the type (but is not derived from it). Use this together with attribute that is both sealed and does not allow multiple. /// In such case there cannot be more attributes, and this will avoid the cost of /// checking for more than one attribute. /// @@ -169,7 +169,6 @@ public virtual bool IsDerivedAttributeDefined(Type type, bool inheri /// The type, assembly or method. /// If we should inspect parents of this type. /// The attribute that is found or null. - /// Throws when multiple attributes are found (the attribute must allow multiple). public TAttribute? GetFirstNonDerivedAttributeOrDefault(ICustomAttributeProvider attributeProvider, bool inherit) where TAttribute : Attribute { From c416216024f123628851eaeea140337fce533470 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 13 Dec 2024 08:05:12 +0100 Subject: [PATCH 110/273] Remove unnecessary overloads in ReflectHelper (#4336) --- .../Helpers/ReflectHelper.cs | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index a17a0bbaf2..4f5abb5076 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -62,28 +62,6 @@ public virtual bool IsNonDerivedAttributeDefined(MemberInfo memberIn return false; } - /// - /// Checks to see if a member or type is decorated with the given attribute. The type is checked exactly. If attribute is derived (inherits from) a class, e.g. [MyTestClass] from [TestClass] it won't match if you look for [TestClass]. The inherit parameter does not impact this checking. - /// - /// Attribute to search for by fully qualified name. - /// Type to test. - /// Inspect inheritance chain of the member or class. E.g. if parent class has this attribute defined. - /// True if the attribute of the specified type is defined on this member or a class. - public virtual bool IsNonDerivedAttributeDefined(Type type, bool inherit) - where TAttribute : Attribute - => IsNonDerivedAttributeDefined((MemberInfo)type, inherit); - - /// - /// Checks to see if a member or type is decorated with the given attribute, or an attribute that derives from it. e.g. [MyTestClass] from [TestClass] will match if you look for [TestClass]. The inherit parameter does not impact this checking. - /// - /// Attribute to search for. - /// Type to test. - /// Inspect inheritance chain of the member or class. E.g. if parent class has this attribute defined. - /// True if the attribute of the specified type is defined on this member or a class. - public virtual bool IsDerivedAttributeDefined(Type type, bool inherit) - where TAttribute : Attribute - => IsDerivedAttributeDefined((MemberInfo)type, inherit); - /// /// Checks to see if a member or type is decorated with the given attribute, or an attribute that derives from it. e.g. [MyTestClass] from [TestClass] will match if you look for [TestClass]. The inherit parameter does not impact this checking. /// From 7c34a4dd410ab4525335b377ecd9ac7631a955fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Fri, 13 Dec 2024 12:43:58 +0100 Subject: [PATCH 111/273] Mark analyzers as released (#4342) --- .../MSTest.Analyzers/AnalyzerReleases.Shipped.md | 10 +++++++++- .../MSTest.Analyzers/AnalyzerReleases.Unshipped.md | 6 ------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Shipped.md b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Shipped.md index 5ce49d10bb..b794b7364a 100644 --- a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Shipped.md +++ b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Shipped.md @@ -1,4 +1,12 @@ -## Release 3.6.0 +## Release 3.7.0 + +### New Rules + +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +MSTEST0037 | `Usage` | Info | UseProperAssertMethodsAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0037) + +## Release 3.6.0 ### New Rules diff --git a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md index 1f7da0db71..6eea619003 100644 --- a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md +++ b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md @@ -1,8 +1,2 @@ ; Unshipped analyzer release ; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md - -### New Rules - -Rule ID | Category | Severity | Notes ---------|----------|----------|------- -MSTEST0037 | `Usage` | Info | UseProperAssertMethodsAnalyzer From 44c7ba2193093a018cc3b88040ca203227b6cb62 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Fri, 13 Dec 2024 04:02:00 -0800 Subject: [PATCH 112/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2601024 --- .../Resources/xlf/PlatformResources.cs.xlf | 2 +- .../Resources/xlf/PlatformResources.de.xlf | 2 +- .../Resources/xlf/PlatformResources.es.xlf | 2 +- .../Resources/xlf/PlatformResources.fr.xlf | 2 +- .../Resources/xlf/PlatformResources.it.xlf | 2 +- .../Resources/xlf/PlatformResources.ja.xlf | 2 +- .../Resources/xlf/PlatformResources.ko.xlf | 2 +- .../Resources/xlf/PlatformResources.pl.xlf | 2 +- .../Resources/xlf/PlatformResources.pt-BR.xlf | 2 +- .../Resources/xlf/PlatformResources.ru.xlf | 2 +- .../Resources/xlf/PlatformResources.tr.xlf | 2 +- .../Resources/xlf/PlatformResources.zh-Hans.xlf | 2 +- .../Resources/xlf/PlatformResources.zh-Hant.xlf | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf index dd8647cf1b..f0e1018a73 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.cs.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + Aktuální testovací architektura neimplementuje rozhraní IGracefulStopTestExecutionCapability, které je vyžadováno pro funkci --maximum-failed-tests. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf index a14a2a4f57..fc9812f0da 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.de.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + Das aktuelle Testframework implementiert nicht "IGracefulStopTestExecutionCapability", das für das Feature "--maximum-failed-tests" erforderlich ist. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf index 934de6ec87..5b85dc2400 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.es.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + El marco de pruebas actual no implementa "IGracefulStopTestExecutionCapability", que es necesario para la característica "--maximum-failed-tests". diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf index 4637ed0d88..6f1b8156b4 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.fr.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + Le framework de tests actuel n’implémente pas 'IGracefulStopTestExecutionCapability', qui est requis pour la fonctionnalité '--maximum-failed-tests'. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf index c2d8296fd9..948448d251 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.it.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + Il framework di test corrente non implementa 'IGracefulStopTestExecutionCapability', necessario per la funzionalità '--maximum-failed-tests'. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf index 573ec36499..bc90b57f6c 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ja.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + 現在のテスト フレームワークは、'--maximum-failed-tests' 機能に必要な 'IGracefulStopTestExecutionCapability' を実装していません。 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf index d90a919159..b066867ba1 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ko.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + 현재 테스트 프레임워크는 '--maximum-failed-tests' 기능에 필요한 'IGracefulStopTestExecutionCapability'를 구현하지 않습니다. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf index b65260f0e7..7445602a49 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pl.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + Bieżąca platforma testowa nie implementuje interfejsu "IGracefulStopTestExecutionCapability", który jest wymagany dla funkcji "--maximum-failed-tests". diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf index 1230bc1a6f..5dd751afdc 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.pt-BR.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + A estrutura de teste atual não implementa 'IGracefulStopTestExecutionCapability', que é necessário para o recurso '--maximum-failed-tests'. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf index 4530a36896..a1cd0e69ec 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.ru.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + Текущая платформа тестирования не реализует параметр "IGracefulStopTestExecutionCapability", необходимый для функции "--maximum-failed-tests". diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf index c3c720d6a1..e4be9f7978 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.tr.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + Geçerli test çerçevesi, '--maximum-failed-tests' özelliği için gerekli olan 'IGracefulStopTestExecutionCapability' gerçekleştiremiyor. diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf index 148ac2f744..bad8bc0553 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hans.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + 当前测试框架未实现 “--maximum-failed-tests” 功能所需的 “IGracefulStopTestExecutionCapability”。 diff --git a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf index 874ce23cfc..7af1c56826 100644 --- a/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Platform/Resources/xlf/PlatformResources.zh-Hant.xlf @@ -4,7 +4,7 @@ The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. - The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature. + 目前的測試架構未實作 '--maximum-failed-tests' 功能所需的 'IGracefulStopTestExecutionCapability'。 From 1415e6e6cc6c968f5e59e90043494175d4daa418 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 13 Dec 2024 14:18:33 +0100 Subject: [PATCH 113/273] Don't consider TestClassAttribute for inheritance when calculating assembly initialize/cleanup (#4318) --- .../MSTest.TestAdapter/Execution/TypeCache.cs | 2 +- .../TestMethod/STATestClassAttribute.cs | 2 +- .../TestMethod/TestClassAttribute.cs | 2 +- .../Execution/TypeCacheTests.cs | 28 +++++++++---------- 4 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index 676b4ce83b..76fb7e3c4c 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -445,7 +445,7 @@ private TestAssemblyInfo GetAssemblyInfo(Type type) try { // Only examine classes which are TestClass or derives from TestClass attribute - if (!_reflectionHelper.IsDerivedAttributeDefined(t, inherit: true)) + if (!_reflectionHelper.IsDerivedAttributeDefined(t, inherit: false)) { continue; } diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/STATestClassAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/STATestClassAttribute.cs index 958cd4358e..c78a974fbd 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/STATestClassAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/STATestClassAttribute.cs @@ -6,7 +6,7 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// /// The test class attribute. /// -[AttributeUsage(AttributeTargets.Class)] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] public class STATestClassAttribute : TestClassAttribute { } diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs index 9c7bb5745d..da57c79550 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs @@ -14,7 +14,7 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// not generic /// /// -[AttributeUsage(AttributeTargets.Class)] +[AttributeUsage(AttributeTargets.Class, Inherited = false)] public class TestClassAttribute : Attribute { /// diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs index 7aee7107a5..1e0af49510 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs @@ -236,7 +236,7 @@ public void GetTestMethodInfoShouldCacheAssemblyInitializeAttribute() var testMethod = new TestMethod("TestInit", type.FullName, "A", isAsync: false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(type.GetMethod("AssemblyInit"), false)).Returns(true); @@ -256,7 +256,7 @@ public void GetTestMethodInfoShouldCacheAssemblyCleanupAttribute() var testMethod = new TestMethod("TestCleanup", type.FullName, "A", isAsync: false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(type.GetMethod("AssemblyCleanup"), false)).Returns(true); @@ -276,7 +276,7 @@ public void GetTestMethodInfoShouldCacheAssemblyInitAndCleanupAttribute() var testMethod = new TestMethod("TestInitOrCleanup", type.FullName, "A", isAsync: false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(type.GetMethod("AssemblyInit"), false)).Returns(true); @@ -299,7 +299,7 @@ public void GetTestMethodInfoShouldThrowIfAssemblyInitHasIncorrectSignature() var testMethod = new TestMethod("M", type.FullName, "A", isAsync: false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(type.GetMethod("AssemblyInit"), false)).Returns(true); @@ -329,7 +329,7 @@ public void GetTestMethodInfoShouldThrowIfAssemblyCleanupHasIncorrectSignature() var testMethod = new TestMethod("M", type.FullName, "A", isAsync: false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(type.GetMethod("AssemblyCleanup"), false)).Returns(true); @@ -360,7 +360,7 @@ public void GetTestMethodInfoShouldCacheAssemblyInfoInstanceAndReuseTheCache() var testMethod = new TestMethod(methodInfo.Name, type.FullName, "A", isAsync: false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _typeCache.GetTestMethodInfo( testMethod, @@ -372,7 +372,7 @@ public void GetTestMethodInfoShouldCacheAssemblyInfoInstanceAndReuseTheCache() new TestContextImplementation(testMethod, new ThreadSafeStringWriter(null, "test"), new Dictionary()), false); - _mockReflectHelper.Verify(rh => rh.IsDerivedAttributeDefined(type, true), Times.Once); + _mockReflectHelper.Verify(rh => rh.IsDerivedAttributeDefined(type, false), Times.Once); Verify(_typeCache.AssemblyInfoCache.Count == 1); } @@ -477,7 +477,7 @@ public void GetTestMethodInfoShouldCacheBaseClassCleanupAttributes() var testMethod = new TestMethod("TestMethod", type.FullName, "A", false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(baseType.GetMethod("AssemblyCleanup"), false)).Returns(true); _mockReflectHelper.Setup( @@ -526,7 +526,7 @@ public void GetTestMethodInfoShouldCacheBaseClassInitAndCleanupAttributes() MethodInfo baseCleanupMethod = baseType.GetMethod("ClassCleanup"); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(baseInitializeMethod, false)).Returns(true); @@ -626,7 +626,7 @@ public void GetTestMethodInfoShouldThrowIfClassInitHasIncorrectSignature() var testMethod = new TestMethod("M", type.FullName, "A", isAsync: false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(type.GetMethod("AssemblyInit"), false)).Returns(true); @@ -656,7 +656,7 @@ public void GetTestMethodInfoShouldThrowIfClassCleanupHasIncorrectSignature() var testMethod = new TestMethod("M", type.FullName, "A", isAsync: false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(type.GetMethod("AssemblyCleanup"), false)).Returns(true); @@ -726,7 +726,7 @@ public void GetTestMethodInfoShouldThrowIfTestInitOrCleanupHasIncorrectSignature var testMethod = new TestMethod("M", type.FullName, "A", isAsync: false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(type.GetMethod("TestInit"), false)).Returns(true); @@ -1280,7 +1280,7 @@ public void AssemblyInfoListWithExecutableCleanupMethodsShouldReturnEmptyListWhe var testMethod = new TestMethod(methodInfo.Name, type.FullName, "A", isAsync: false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(type.GetMethod("AssemblyCleanup"), false)).Returns(false); @@ -1302,7 +1302,7 @@ public void AssemblyInfoListWithExecutableCleanupMethodsShouldReturnAssemblyInfo var testMethod = new TestMethod(methodInfo.Name, type.FullName, "A", isAsync: false); _mockReflectHelper.Setup( - rh => rh.IsDerivedAttributeDefined(type, true)).Returns(true); + rh => rh.IsDerivedAttributeDefined(type, false)).Returns(true); _mockReflectHelper.Setup( rh => rh.IsNonDerivedAttributeDefined(type.GetMethod("AssemblyCleanup"), false)).Returns(true); From 39832f5d84a939ddbb2d1b907544b86877cdfc78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Fri, 13 Dec 2024 15:36:08 +0100 Subject: [PATCH 114/273] Mark public API as shipped (#4341) Co-authored-by: Youssef Victor --- eng/mark-shipped.ps1 | 36 +++ .../PublicAPI/PublicAPI.Shipped.txt | 42 ++- .../PublicAPI/PublicAPI.Unshipped.txt | 42 +-- .../uap10.0.16299/PublicAPI.Shipped.txt | 2 +- .../uap10.0.16299/PublicAPI.Unshipped.txt | 2 +- .../PublicAPI/PublicAPI.Shipped.txt | 8 +- .../PublicAPI/PublicAPI.Unshipped.txt | 8 +- .../PublicAPI/net462/PublicAPI.Shipped.txt | 2 +- .../PublicAPI.Shipped.txt | 2 +- .../PublicAPI/net6.0/PublicAPI.Shipped.txt | 2 +- .../PublicAPI/net7.0/PublicAPI.Shipped.txt | 2 +- .../PublicAPI/net8.0/PublicAPI.Shipped.txt | 2 +- .../PublicAPI/net9.0/PublicAPI.Shipped.txt | 2 +- .../netcoreapp3.1/PublicAPI.Shipped.txt | 2 +- .../netstandard2.0/PublicAPI.Shipped.txt | 2 +- .../uap10.0.16299/PublicAPI.Shipped.txt | 2 +- .../uap10.0.16299/PublicAPI.Unshipped.txt | 2 +- .../MSTest.Analyzers/PublicAPI.Shipped.txt | 2 +- .../MSTest.Analyzers/PublicAPI.Unshipped.txt | 2 +- .../PublicAPI/PublicAPI.Shipped.txt | 2 +- .../PublicAPI.Shipped.txt | 1 + .../PublicAPI.Unshipped.txt | 1 - .../PublicAPI/PublicAPI.Shipped.txt | 50 +++- .../PublicAPI/PublicAPI.Unshipped.txt | 40 --- .../netstandard2.0/PublicAPI.Shipped.txt | 12 +- .../PublicAPI/PublicAPI.Shipped.txt | 10 +- .../PublicAPI/PublicAPI.Unshipped.txt | 8 +- .../PublicAPI/net462/PublicAPI.Shipped.txt | 22 +- .../PublicAPI/net462/PublicAPI.Unshipped.txt | 2 +- .../PublicAPI.Shipped.txt | 2 +- .../PublicAPI.Unshipped.txt | 2 +- .../PublicAPI/net6.0/PublicAPI.Shipped.txt | 4 +- .../PublicAPI/net6.0/PublicAPI.Unshipped.txt | 2 +- .../PublicAPI/net7.0/PublicAPI.Shipped.txt | 4 +- .../PublicAPI/net7.0/PublicAPI.Unshipped.txt | 2 +- .../PublicAPI/net8.0/PublicAPI.Shipped.txt | 4 +- .../PublicAPI/net8.0/PublicAPI.Unshipped.txt | 2 +- .../PublicAPI/net9.0/PublicAPI.Shipped.txt | 4 +- .../PublicAPI/net9.0/PublicAPI.Unshipped.txt | 2 +- .../netcoreapp3.1/PublicAPI.Shipped.txt | 2 +- .../netcoreapp3.1/PublicAPI.Unshipped.txt | 2 +- .../netstandard2.0/PublicAPI.Shipped.txt | 4 +- .../netstandard2.0/PublicAPI.Unshipped.txt | 2 +- .../uap10.0.16299/PublicAPI.Shipped.txt | 2 +- .../uap10.0.16299/PublicAPI.Unshipped.txt | 2 +- .../PublicAPI/PublicAPI.Shipped.txt | 249 +++++++++--------- .../PublicAPI/PublicAPI.Unshipped.txt | 15 +- 47 files changed, 327 insertions(+), 291 deletions(-) create mode 100644 eng/mark-shipped.ps1 diff --git a/eng/mark-shipped.ps1 b/eng/mark-shipped.ps1 new file mode 100644 index 0000000000..63dadd65a2 --- /dev/null +++ b/eng/mark-shipped.ps1 @@ -0,0 +1,36 @@ +Set-StrictMode -version 2.0 +$ErrorActionPreference = "Stop" + +function Set-AsShipped([Parameter(Mandatory)][string]$Directory) { + $shippedFilePath = "$Directory/PublicAPI.Shipped.txt" + $shipped = Get-Content $shippedFilePath -Encoding utf8 + if ($null -eq $shipped) { + $shipped = @() + } + + $unshippedFilePath = "$Directory/PublicAPI.Unshipped.txt" + $unshipped = Get-Content $unshippedFilePath + $removed = @() + $removedPrefix = "*REMOVED*"; + Write-Host "Processing $Directory" + + foreach ($item in $unshipped) { + if ($item.Length -gt 0) { + if ($item.StartsWith($removedPrefix)) { + $item = $item.Substring($removedPrefix.Length) + $removed += $item + } + elseif ($item -ne "#nullable enable") { + $shipped += $item + } + } + } + + $shipped | Sort-Object | Where-Object { $_ -notin $removed } | Out-File $shippedFilePath -Encoding utf8 + "#nullable enable" | Out-File $unshippedFilePath -Encoding utf8 +} + +foreach ($file in Get-ChildItem "$PSScriptRoot\..\src" -Recurse -Include "PublicApi.Shipped.txt") { + $Directory = Split-Path -parent $file + Set-AsShipped $Directory +} diff --git a/src/Adapter/MSTest.TestAdapter/PublicAPI/PublicAPI.Shipped.txt b/src/Adapter/MSTest.TestAdapter/PublicAPI/PublicAPI.Shipped.txt index 0d05196024..9de3e651d7 100644 --- a/src/Adapter/MSTest.TestAdapter/PublicAPI/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTest.TestAdapter/PublicAPI/PublicAPI.Shipped.txt @@ -1,4 +1,4 @@ -#nullable enable +#nullable enable const Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo.TimeoutWhenNotSet = 0 -> int const Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings.SettingsName = "MSTest" -> string! const Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings.SettingsNameAlias = "MSTestV2" -> string! @@ -132,6 +132,45 @@ Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestResul Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.RunConfigurationSettings Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.RunConfigurationSettings.CollectSourceInformation.get -> bool Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.RunConfigurationSettings.RunConfigurationSettings() -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.ReflectionMetadataHook +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.Assembly.get -> System.Reflection.Assembly! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.Assembly.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.AssemblyAttributes.get -> object![]! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.AssemblyAttributes.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.AssemblyName.get -> string! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.AssemblyName.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.MyConstructorInfo +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.MyConstructorInfo.Invoker.get -> System.Func! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.MyConstructorInfo.MyConstructorInfo() -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.MyConstructorInfo.Parameters.get -> System.Type![]! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.SourceGeneratedReflectionDataProvider() -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeAttributes.get -> System.Collections.Generic.Dictionary! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeAttributes.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeConstructors.get -> System.Collections.Generic.Dictionary! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeConstructors.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeConstructorsInvoker.get -> System.Collections.Generic.Dictionary! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeConstructorsInvoker.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation.FileName.get -> string! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation.FileName.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation.MethodLocations.get -> System.Collections.Generic.Dictionary! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation.MethodLocations.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation.TypeLocation() -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethodAttributes.get -> System.Collections.Generic.Dictionary!>! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethodAttributes.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethodLocations.get -> System.Collections.Generic.Dictionary! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethodLocations.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethods.get -> System.Collections.Generic.Dictionary! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethods.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeProperties.get -> System.Collections.Generic.Dictionary! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeProperties.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypePropertiesByName.get -> System.Collections.Generic.Dictionary!>! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypePropertiesByName.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.Types.get -> System.Type![]! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.Types.init -> void +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypesByName.get -> System.Collections.Generic.Dictionary! +Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypesByName.init -> void Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.TestRunCancellationToken Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.TestRunCancellationToken.Cancel() -> void Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.TestRunCancellationToken.Canceled.get -> bool @@ -148,6 +187,7 @@ static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings.Pop static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings.PopulateSettings(Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IDiscoveryContext? context) -> void static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings.RunConfigurationSettings.get -> Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.RunConfigurationSettings! static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.RunConfigurationSettings.PopulateSettings(Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter.IDiscoveryContext? context) -> Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.RunConfigurationSettings! +static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.ReflectionMetadataHook.SetMetadata(Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider! metadata) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.TestApplicationBuilderExtensions.AddMSTest(this Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! testApplicationBuilder, System.Func!>! getTestAssemblies) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.TestingPlatformBuilderHook.AddExtensions(Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! testApplicationBuilder, string![]! arguments) -> void virtual Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo.Invoke(object?[]? arguments) -> Microsoft.VisualStudio.TestTools.UnitTesting.TestResult! diff --git a/src/Adapter/MSTest.TestAdapter/PublicAPI/PublicAPI.Unshipped.txt b/src/Adapter/MSTest.TestAdapter/PublicAPI/PublicAPI.Unshipped.txt index d2691b0382..7dc5c58110 100644 --- a/src/Adapter/MSTest.TestAdapter/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Adapter/MSTest.TestAdapter/PublicAPI/PublicAPI.Unshipped.txt @@ -1,41 +1 @@ -#nullable enable -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.ReflectionMetadataHook -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.Assembly.get -> System.Reflection.Assembly! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.Assembly.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.AssemblyAttributes.get -> object![]! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.AssemblyAttributes.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.AssemblyName.get -> string! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.AssemblyName.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.MyConstructorInfo -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.MyConstructorInfo.Invoker.get -> System.Func! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.MyConstructorInfo.MyConstructorInfo() -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.MyConstructorInfo.Parameters.get -> System.Type![]! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.SourceGeneratedReflectionDataProvider() -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeAttributes.get -> System.Collections.Generic.Dictionary! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeAttributes.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeConstructors.get -> System.Collections.Generic.Dictionary! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeConstructors.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeConstructorsInvoker.get -> System.Collections.Generic.Dictionary! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeConstructorsInvoker.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation.FileName.get -> string! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation.FileName.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation.MethodLocations.get -> System.Collections.Generic.Dictionary! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation.MethodLocations.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeLocation.TypeLocation() -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethodAttributes.get -> System.Collections.Generic.Dictionary!>! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethodAttributes.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethodLocations.get -> System.Collections.Generic.Dictionary! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethodLocations.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethods.get -> System.Collections.Generic.Dictionary! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeMethods.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeProperties.get -> System.Collections.Generic.Dictionary! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypeProperties.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypePropertiesByName.get -> System.Collections.Generic.Dictionary!>! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypePropertiesByName.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.Types.get -> System.Type![]! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.Types.init -> void -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypesByName.get -> System.Collections.Generic.Dictionary! -Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider.TypesByName.init -> void -static Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.ReflectionMetadataHook.SetMetadata(Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration.SourceGeneratedReflectionDataProvider! metadata) -> void +#nullable enable diff --git a/src/Adapter/MSTest.TestAdapter/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt b/src/Adapter/MSTest.TestAdapter/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt index 5e6042d103..9e97765492 100644 --- a/src/Adapter/MSTest.TestAdapter/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTest.TestAdapter/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt @@ -1,4 +1,4 @@ -#nullable enable +#nullable enable const Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution.TestMethodInfo.TimeoutWhenNotSet = 0 -> int const Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings.SettingsName = "MSTest" -> string! const Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.MSTestSettings.SettingsNameAlias = "MSTestV2" -> string! diff --git a/src/Adapter/MSTest.TestAdapter/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt b/src/Adapter/MSTest.TestAdapter/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt index ab058de62d..7dc5c58110 100644 --- a/src/Adapter/MSTest.TestAdapter/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt +++ b/src/Adapter/MSTest.TestAdapter/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable +#nullable enable diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Shipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Shipped.txt index 0c08630cca..5acee6d2bc 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Shipped.txt @@ -1,4 +1,4 @@ -#nullable enable +#nullable enable Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.AdapterTraceLogger Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.AdapterTraceLogger.AdapterTraceLogger() -> void Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.AdapterTraceLogger.LogError(string! format, params object?[]! args) -> void @@ -40,7 +40,10 @@ Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITe Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.GetResultFiles() -> System.Collections.Generic.IList? Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.SetDataConnection(object? dbConnection) -> void Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.SetDataRow(object? dataRow) -> void +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.SetDisplayName(string? displayName) -> void +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.SetException(System.Exception? exception) -> void Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.SetOutcome(Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome outcome) -> void +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.SetTestData(object?[]? data) -> void Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.TryGetPropertyValue(string! propertyName, out object? propertyValue) -> bool Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestDataSource Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestDataSource.GetData(Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod! testMethodInfo, Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext! testContext) -> System.Collections.Generic.IEnumerable? @@ -93,7 +96,10 @@ Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextIm Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.GetResultFiles() -> System.Collections.Generic.IList? Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.SetDataConnection(object? dbConnection) -> void Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.SetDataRow(object? dataRow) -> void +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.SetDisplayName(string? displayName) -> void +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.SetException(System.Exception? exception) -> void Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.SetOutcome(Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome outcome) -> void +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.SetTestData(object?[]? data) -> void Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.TestContextImplementation(Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel.ITestMethod! testMethod, System.IO.StringWriter! stringWriter, System.Collections.Generic.IDictionary! properties) -> void Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.TryGetPropertyValue(string! propertyName, out object? propertyValue) -> bool Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestDataSource diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt index 04a7900759..7dc5c58110 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt @@ -1,7 +1 @@ -#nullable enable -Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.SetDisplayName(string? displayName) -> void -Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.SetException(System.Exception? exception) -> void -Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.SetTestData(object?[]? data) -> void -Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.SetDisplayName(string? displayName) -> void -Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.SetException(System.Exception? exception) -> void -Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.SetTestData(object?[]? data) -> void +#nullable enable diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net462/PublicAPI.Shipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net462/PublicAPI.Shipped.txt index 7bb31399b1..163eb68518 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net462/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net462/PublicAPI.Shipped.txt @@ -82,4 +82,4 @@ virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Assem virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.AssemblyResolver.ReflectionOnlyLoadAssemblyFrom(string! path) -> System.Reflection.Assembly! virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.AssemblyResolver.SearchAssembly(System.Collections.Generic.List! searchDirectorypaths, string! name, bool isReflectionOnly) -> System.Reflection.Assembly? virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DoesDirectoryExist(string! path) -> bool -virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! \ No newline at end of file +virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Shipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Shipped.txt index 0e08282b9a..2dd69c993e 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Shipped.txt @@ -33,4 +33,4 @@ System.SerializableAttribute (forwarded, contained in System.Runtime) System.SerializableAttribute.SerializableAttribute() -> void (forwarded, contained in System.Runtime) virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DoesDirectoryExist(string! path) -> bool virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! -virtual System.MarshalByRefObject.InitializeLifetimeService() -> object! (forwarded, contained in System.Runtime) \ No newline at end of file +virtual System.MarshalByRefObject.InitializeLifetimeService() -> object! (forwarded, contained in System.Runtime) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net6.0/PublicAPI.Shipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net6.0/PublicAPI.Shipped.txt index b5ff64abc0..f4783138ee 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net6.0/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net6.0/PublicAPI.Shipped.txt @@ -30,4 +30,4 @@ static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTest static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Reset() -> void static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Settings.get -> Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings! virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DoesDirectoryExist(string! path) -> bool -virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! \ No newline at end of file +virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net7.0/PublicAPI.Shipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net7.0/PublicAPI.Shipped.txt index b5ff64abc0..f4783138ee 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net7.0/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net7.0/PublicAPI.Shipped.txt @@ -30,4 +30,4 @@ static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTest static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Reset() -> void static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Settings.get -> Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings! virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DoesDirectoryExist(string! path) -> bool -virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! \ No newline at end of file +virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net8.0/PublicAPI.Shipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net8.0/PublicAPI.Shipped.txt index b5ff64abc0..f4783138ee 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net8.0/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net8.0/PublicAPI.Shipped.txt @@ -30,4 +30,4 @@ static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTest static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Reset() -> void static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Settings.get -> Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings! virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DoesDirectoryExist(string! path) -> bool -virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! \ No newline at end of file +virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Shipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Shipped.txt index b5ff64abc0..f4783138ee 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/net9.0/PublicAPI.Shipped.txt @@ -30,4 +30,4 @@ static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTest static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Reset() -> void static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Settings.get -> Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings! virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DoesDirectoryExist(string! path) -> bool -virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! \ No newline at end of file +virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/netcoreapp3.1/PublicAPI.Shipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/netcoreapp3.1/PublicAPI.Shipped.txt index b5ff64abc0..f4783138ee 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/netcoreapp3.1/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/netcoreapp3.1/PublicAPI.Shipped.txt @@ -30,4 +30,4 @@ static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTest static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Reset() -> void static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Settings.get -> Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings! virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DoesDirectoryExist(string! path) -> bool -virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! \ No newline at end of file +virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt index b5ff64abc0..f4783138ee 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt @@ -30,4 +30,4 @@ static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTest static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Reset() -> void static Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestSettingsProvider.Settings.get -> Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings! virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.DoesDirectoryExist(string! path) -> bool -virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! \ No newline at end of file +virtual Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.MSTestAdapterSettings.ExpandEnvironmentVariables(string! path) -> string! diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt index 0f2adb28da..24625c1ccf 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt @@ -1,4 +1,4 @@ #nullable enable Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TraceListenerManager.Close(Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITraceListener! traceListener) -> void Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TraceListenerWrapper.Close() -> void -Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TraceListenerWrapper.Dispose() -> void \ No newline at end of file +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TraceListenerWrapper.Dispose() -> void diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt index 815c92006a..7dc5c58110 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable \ No newline at end of file +#nullable enable diff --git a/src/Analyzers/MSTest.Analyzers/PublicAPI.Shipped.txt b/src/Analyzers/MSTest.Analyzers/PublicAPI.Shipped.txt index 681365b958..ff8980d5af 100644 --- a/src/Analyzers/MSTest.Analyzers/PublicAPI.Shipped.txt +++ b/src/Analyzers/MSTest.Analyzers/PublicAPI.Shipped.txt @@ -1,4 +1,4 @@ -#nullable enable +#nullable enable Analyzer.Utilities.WellKnownTypeProvider Analyzer.Utilities.WellKnownTypeProvider.Compilation.get -> Microsoft.CodeAnalysis.Compilation! Analyzer.Utilities.WellKnownTypeProvider.GetOrCreateTypeByMetadataName(string! fullTypeName) -> Microsoft.CodeAnalysis.INamedTypeSymbol? diff --git a/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt b/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt index ab058de62d..7dc5c58110 100644 --- a/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt +++ b/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable +#nullable enable diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/PublicAPI/PublicAPI.Shipped.txt b/src/Platform/Microsoft.Testing.Extensions.HangDump/PublicAPI/PublicAPI.Shipped.txt index 9a6866965b..7ae28f89cb 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HangDump/PublicAPI/PublicAPI.Shipped.txt +++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/PublicAPI/PublicAPI.Shipped.txt @@ -1,5 +1,5 @@ #nullable enable -Microsoft.Testing.Extensions.HangDumpExtensions Microsoft.Testing.Extensions.HangDump.TestingPlatformBuilderHook +Microsoft.Testing.Extensions.HangDumpExtensions static Microsoft.Testing.Extensions.HangDump.TestingPlatformBuilderHook.AddExtensions(Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! testApplicationBuilder, string![]! _) -> void static Microsoft.Testing.Extensions.HangDumpExtensions.AddHangDumpProvider(this Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! builder) -> void diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/PublicAPI.Shipped.txt b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/PublicAPI.Shipped.txt index b9a8f88f8d..16d6e94640 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/PublicAPI.Shipped.txt +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/PublicAPI.Shipped.txt @@ -50,6 +50,7 @@ override sealed Microsoft.Testing.Extensions.VSTestBridge.SynchronizedSingleSess override sealed Microsoft.Testing.Extensions.VSTestBridge.SynchronizedSingleSessionVSTestBridgedTestFramework.RunTestsAsync(Microsoft.Testing.Extensions.VSTestBridge.Requests.VSTestRunTestExecutionRequest! request, Microsoft.Testing.Platform.Messages.IMessageBus! messageBus, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! override sealed Microsoft.Testing.Extensions.VSTestBridge.SynchronizedSingleSessionVSTestBridgedTestFramework.Uid.get -> string! override sealed Microsoft.Testing.Extensions.VSTestBridge.SynchronizedSingleSessionVSTestBridgedTestFramework.Version.get -> string! +static Microsoft.Testing.Extensions.VSTestBridge.Helpers.TestApplicationBuilderExtensions.AddRunSettingsEnvironmentVariableProvider(this Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! builder, Microsoft.Testing.Platform.Extensions.IExtension! extension) -> void static Microsoft.Testing.Extensions.VSTestBridge.Helpers.TestApplicationBuilderExtensions.AddRunSettingsService(this Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! builder, Microsoft.Testing.Platform.Extensions.IExtension! extension) -> void static Microsoft.Testing.Extensions.VSTestBridge.Helpers.TestApplicationBuilderExtensions.AddTestCaseFilterService(this Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! builder, Microsoft.Testing.Platform.Extensions.IExtension! extension) -> void static Microsoft.Testing.Extensions.VSTestBridge.Helpers.TestApplicationBuilderExtensions.AddTestRunParametersService(this Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! builder, Microsoft.Testing.Platform.Extensions.IExtension! extension) -> void diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/PublicAPI.Unshipped.txt b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/PublicAPI.Unshipped.txt index c27c99f4e5..7dc5c58110 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/PublicAPI.Unshipped.txt +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/PublicAPI.Unshipped.txt @@ -1,2 +1 @@ #nullable enable -static Microsoft.Testing.Extensions.VSTestBridge.Helpers.TestApplicationBuilderExtensions.AddRunSettingsEnvironmentVariableProvider(this Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! builder, Microsoft.Testing.Platform.Extensions.IExtension! extension) -> void diff --git a/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Shipped.txt b/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Shipped.txt index ec952b1b5f..76bbf25eb7 100644 --- a/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Shipped.txt +++ b/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Shipped.txt @@ -1,7 +1,22 @@ #nullable enable [TPEXP]Microsoft.Testing.Platform.Capabilities.TestFramework.IBannerMessageOwnerCapability [TPEXP]Microsoft.Testing.Platform.Capabilities.TestFramework.IBannerMessageOwnerCapability.GetBannerMessageAsync() -> System.Threading.Tasks.Task! +[TPEXP]Microsoft.Testing.Platform.Capabilities.TestFramework.IGracefulStopTestExecutionCapability +[TPEXP]Microsoft.Testing.Platform.Capabilities.TestFramework.IGracefulStopTestExecutionCapability.StopTestExecutionAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! [TPEXP]Microsoft.Testing.Platform.Capabilities.TestFramework.TestFrameworkCapabilitiesExtensions +[TPEXP]Microsoft.Testing.Platform.CommandLine.ICommandLineManager.AddProvider(System.Func! commandLineProviderFactory) -> void +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.Deconstruct(out string! StandardError) -> void +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.StandardError.get -> string! +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.StandardError.init -> void +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.StandardErrorProperty(Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty! original) -> void +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.StandardErrorProperty(string! StandardError) -> void +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.Deconstruct(out string! StandardOutput) -> void +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutput.get -> string! +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutput.init -> void +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutputProperty(Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty! original) -> void +[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutputProperty(string! StandardOutput) -> void [TPEXP]Microsoft.Testing.Platform.Requests.IExecuteRequestCompletionNotifier [TPEXP]Microsoft.Testing.Platform.Requests.IExecuteRequestCompletionNotifier.Complete() -> void [TPEXP]Microsoft.Testing.Platform.Services.IClientInfo @@ -12,9 +27,27 @@ [TPEXP]Microsoft.Testing.Platform.Services.IPlatformInformation.CommitHash.get -> string? [TPEXP]Microsoft.Testing.Platform.Services.IPlatformInformation.Name.get -> string! [TPEXP]Microsoft.Testing.Platform.Services.IPlatformInformation.Version.get -> string? +[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.Equals(object? obj) -> bool +[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.GetHashCode() -> int +[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.ToString() -> string! +[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.Equals(object? obj) -> bool +[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.GetHashCode() -> int +[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.ToString() -> string! [TPEXP]static Microsoft.Testing.Platform.Capabilities.TestFramework.TestFrameworkCapabilitiesExtensions.GetCapability(this Microsoft.Testing.Platform.Capabilities.TestFramework.ITestFrameworkCapabilities! capabilities) -> T? [TPEXP]static Microsoft.Testing.Platform.Capabilities.TestFramework.TestFrameworkCapabilitiesExtensions.HasCapability(this Microsoft.Testing.Platform.Capabilities.TestFramework.ITestFrameworkCapabilities! capabilities) -> bool +[TPEXP]static Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.operator !=(Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty? left, Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty? right) -> bool +[TPEXP]static Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.operator ==(Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty? left, Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty? right) -> bool +[TPEXP]static Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.operator !=(Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty? left, Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty? right) -> bool +[TPEXP]static Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.operator ==(Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty? left, Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty? right) -> bool [TPEXP]static Microsoft.Testing.Platform.Services.ServiceProviderExtensions.GetClientInfo(this System.IServiceProvider! serviceProvider) -> Microsoft.Testing.Platform.Services.IClientInfo! +[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.$() -> Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty! +[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.EqualityContract.get -> System.Type! +[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.Equals(Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty? other) -> bool +[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.PrintMembers(System.Text.StringBuilder! builder) -> bool +[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.$() -> Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty! +[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.EqualityContract.get -> System.Type! +[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.Equals(Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty? other) -> bool +[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.PrintMembers(System.Text.StringBuilder! builder) -> bool Microsoft.Testing.Platform.Builder.ConfigurationOptions Microsoft.Testing.Platform.Builder.ConfigurationOptions.ConfigurationOptions() -> void Microsoft.Testing.Platform.Builder.ConfigurationOptions.ConfigurationSources.get -> Microsoft.Testing.Platform.Builder.ConfigurationSourcesOptions! @@ -180,6 +213,7 @@ Microsoft.Testing.Platform.Extensions.Messages.TestMetadataProperty Microsoft.Testing.Platform.Extensions.Messages.TestMetadataProperty.Key.get -> string! Microsoft.Testing.Platform.Extensions.Messages.TestMetadataProperty.Key.init -> void Microsoft.Testing.Platform.Extensions.Messages.TestMetadataProperty.TestMetadataProperty(string! Key, string! Value) -> void +Microsoft.Testing.Platform.Extensions.Messages.TestMetadataProperty.TestMetadataProperty(string! key) -> void Microsoft.Testing.Platform.Extensions.Messages.TestMetadataProperty.Value.get -> string! Microsoft.Testing.Platform.Extensions.Messages.TestMetadataProperty.Value.init -> void Microsoft.Testing.Platform.Extensions.Messages.TestMethodIdentifierProperty @@ -239,8 +273,8 @@ Microsoft.Testing.Platform.Extensions.Messages.TimingInfo.TimingInfo(System.Date Microsoft.Testing.Platform.Extensions.Messages.TimingProperty Microsoft.Testing.Platform.Extensions.Messages.TimingProperty.GlobalTiming.get -> Microsoft.Testing.Platform.Extensions.Messages.TimingInfo Microsoft.Testing.Platform.Extensions.Messages.TimingProperty.StepTimings.get -> Microsoft.Testing.Platform.Extensions.Messages.StepTimingInfo![]! -Microsoft.Testing.Platform.Extensions.Messages.TimingProperty.TimingProperty(Microsoft.Testing.Platform.Extensions.Messages.TimingInfo globalTiming) -> void Microsoft.Testing.Platform.Extensions.Messages.TimingProperty.TimingProperty(Microsoft.Testing.Platform.Extensions.Messages.TimingInfo globalTiming, Microsoft.Testing.Platform.Extensions.Messages.StepTimingInfo![]! stepTimings) -> void +Microsoft.Testing.Platform.Extensions.Messages.TimingProperty.TimingProperty(Microsoft.Testing.Platform.Extensions.Messages.TimingInfo globalTiming) -> void Microsoft.Testing.Platform.Extensions.OutputDevice.IOutputDeviceDataProducer Microsoft.Testing.Platform.Extensions.TestFramework.CloseTestSessionContext Microsoft.Testing.Platform.Extensions.TestFramework.CloseTestSessionContext.CancellationToken.get -> System.Threading.CancellationToken @@ -330,6 +364,9 @@ Microsoft.Testing.Platform.Logging.LogLevel.Trace = 0 -> Microsoft.Testing.Platf Microsoft.Testing.Platform.Logging.LogLevel.Warning = 3 -> Microsoft.Testing.Platform.Logging.LogLevel Microsoft.Testing.Platform.Messages.IMessageBus Microsoft.Testing.Platform.Messages.IMessageBus.PublishAsync(Microsoft.Testing.Platform.Extensions.Messages.IDataProducer! dataProducer, Microsoft.Testing.Platform.Extensions.Messages.IData! data) -> System.Threading.Tasks.Task! +Microsoft.Testing.Platform.OutputDevice.ErrorMessageOutputDeviceData +Microsoft.Testing.Platform.OutputDevice.ErrorMessageOutputDeviceData.ErrorMessageOutputDeviceData(string! message) -> void +Microsoft.Testing.Platform.OutputDevice.ErrorMessageOutputDeviceData.Message.get -> string! Microsoft.Testing.Platform.OutputDevice.ExceptionOutputDeviceData Microsoft.Testing.Platform.OutputDevice.ExceptionOutputDeviceData.Exception.get -> System.Exception! Microsoft.Testing.Platform.OutputDevice.ExceptionOutputDeviceData.ExceptionOutputDeviceData(System.Exception! exception) -> void @@ -352,15 +389,18 @@ Microsoft.Testing.Platform.OutputDevice.SystemConsoleColor.SystemConsoleColor() Microsoft.Testing.Platform.OutputDevice.TextOutputDeviceData Microsoft.Testing.Platform.OutputDevice.TextOutputDeviceData.Text.get -> string! Microsoft.Testing.Platform.OutputDevice.TextOutputDeviceData.TextOutputDeviceData(string! text) -> void +Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData +Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData.Message.get -> string! +Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData.WarningMessageOutputDeviceData(string! message) -> void Microsoft.Testing.Platform.Requests.DiscoverTestExecutionRequest -Microsoft.Testing.Platform.Requests.DiscoverTestExecutionRequest.DiscoverTestExecutionRequest(Microsoft.Testing.Platform.TestHost.TestSessionContext! session) -> void Microsoft.Testing.Platform.Requests.DiscoverTestExecutionRequest.DiscoverTestExecutionRequest(Microsoft.Testing.Platform.TestHost.TestSessionContext! session, Microsoft.Testing.Platform.Requests.ITestExecutionFilter! executionFilter) -> void +Microsoft.Testing.Platform.Requests.DiscoverTestExecutionRequest.DiscoverTestExecutionRequest(Microsoft.Testing.Platform.TestHost.TestSessionContext! session) -> void Microsoft.Testing.Platform.Requests.IRequest Microsoft.Testing.Platform.Requests.IRequest.Session.get -> Microsoft.Testing.Platform.TestHost.TestSessionContext! Microsoft.Testing.Platform.Requests.ITestExecutionFilter Microsoft.Testing.Platform.Requests.RunTestExecutionRequest -Microsoft.Testing.Platform.Requests.RunTestExecutionRequest.RunTestExecutionRequest(Microsoft.Testing.Platform.TestHost.TestSessionContext! session) -> void Microsoft.Testing.Platform.Requests.RunTestExecutionRequest.RunTestExecutionRequest(Microsoft.Testing.Platform.TestHost.TestSessionContext! session, Microsoft.Testing.Platform.Requests.ITestExecutionFilter! executionFilter) -> void +Microsoft.Testing.Platform.Requests.RunTestExecutionRequest.RunTestExecutionRequest(Microsoft.Testing.Platform.TestHost.TestSessionContext! session) -> void Microsoft.Testing.Platform.Requests.TestExecutionRequest Microsoft.Testing.Platform.Requests.TestExecutionRequest.Filter.get -> Microsoft.Testing.Platform.Requests.ITestExecutionFilter! Microsoft.Testing.Platform.Requests.TestExecutionRequest.Session.get -> Microsoft.Testing.Platform.TestHost.TestSessionContext! @@ -430,11 +470,11 @@ static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogCritical(this Mic static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogCriticalAsync(this Microsoft.Testing.Platform.Logging.ILogger! logger, string! message) -> System.Threading.Tasks.Task! static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogDebug(this Microsoft.Testing.Platform.Logging.ILogger! logger, string! message) -> void static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogDebugAsync(this Microsoft.Testing.Platform.Logging.ILogger! logger, string! message) -> System.Threading.Tasks.Task! -static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogError(this Microsoft.Testing.Platform.Logging.ILogger! logger, string! message) -> void static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogError(this Microsoft.Testing.Platform.Logging.ILogger! logger, string! message, System.Exception! ex) -> void +static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogError(this Microsoft.Testing.Platform.Logging.ILogger! logger, string! message) -> void static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogError(this Microsoft.Testing.Platform.Logging.ILogger! logger, System.Exception! ex) -> void -static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogErrorAsync(this Microsoft.Testing.Platform.Logging.ILogger! logger, string! message) -> System.Threading.Tasks.Task! static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogErrorAsync(this Microsoft.Testing.Platform.Logging.ILogger! logger, string! message, System.Exception! ex) -> System.Threading.Tasks.Task! +static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogErrorAsync(this Microsoft.Testing.Platform.Logging.ILogger! logger, string! message) -> System.Threading.Tasks.Task! static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogErrorAsync(this Microsoft.Testing.Platform.Logging.ILogger! logger, System.Exception! ex) -> System.Threading.Tasks.Task! static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogInformation(this Microsoft.Testing.Platform.Logging.ILogger! logger, string! message) -> void static Microsoft.Testing.Platform.Logging.LoggingExtensions.LogInformationAsync(this Microsoft.Testing.Platform.Logging.ILogger! logger, string! message) -> System.Threading.Tasks.Task! diff --git a/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt b/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt index 6b57520132..7dc5c58110 100644 --- a/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Platform/Microsoft.Testing.Platform/PublicAPI/PublicAPI.Unshipped.txt @@ -1,41 +1 @@ #nullable enable -Microsoft.Testing.Platform.Extensions.Messages.TestMetadataProperty.TestMetadataProperty(string! key) -> void -Microsoft.Testing.Platform.OutputDevice.ErrorMessageOutputDeviceData -Microsoft.Testing.Platform.OutputDevice.ErrorMessageOutputDeviceData.ErrorMessageOutputDeviceData(string! message) -> void -Microsoft.Testing.Platform.OutputDevice.ErrorMessageOutputDeviceData.Message.get -> string! -Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData -Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData.Message.get -> string! -Microsoft.Testing.Platform.OutputDevice.WarningMessageOutputDeviceData.WarningMessageOutputDeviceData(string! message) -> void -[TPEXP]Microsoft.Testing.Platform.Capabilities.TestFramework.IGracefulStopTestExecutionCapability -[TPEXP]Microsoft.Testing.Platform.Capabilities.TestFramework.IGracefulStopTestExecutionCapability.StopTestExecutionAsync(System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.Task! -[TPEXP]Microsoft.Testing.Platform.CommandLine.ICommandLineManager.AddProvider(System.Func! commandLineProviderFactory) -> void -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutput.get -> string! -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutput.init -> void -[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.EqualityContract.get -> System.Type! -[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.ToString() -> string! -[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.PrintMembers(System.Text.StringBuilder! builder) -> bool -[TPEXP]static Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.operator !=(Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty? left, Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty? right) -> bool -[TPEXP]static Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.operator ==(Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty? left, Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty? right) -> bool -[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.GetHashCode() -> int -[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.Equals(object? obj) -> bool -[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.$() -> Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty! -[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.Equals(Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty? other) -> bool -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutputProperty(Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty! original) -> void -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.Deconstruct(out string! StandardOutput) -> void -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardOutputProperty.StandardOutputProperty(string! StandardOutput) -> void -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.StandardError.get -> string! -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.StandardError.init -> void -[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.EqualityContract.get -> System.Type! -[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.ToString() -> string! -[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.PrintMembers(System.Text.StringBuilder! builder) -> bool -[TPEXP]static Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.operator !=(Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty? left, Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty? right) -> bool -[TPEXP]static Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.operator ==(Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty? left, Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty? right) -> bool -[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.GetHashCode() -> int -[TPEXP]override Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.Equals(object? obj) -> bool -[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.$() -> Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty! -[TPEXP]virtual Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.Equals(Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty? other) -> bool -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.StandardErrorProperty(Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty! original) -> void -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.Deconstruct(out string! StandardError) -> void -[TPEXP]Microsoft.Testing.Platform.Extensions.Messages.StandardErrorProperty.StandardErrorProperty(string! StandardError) -> void diff --git a/src/Platform/Microsoft.Testing.Platform/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt b/src/Platform/Microsoft.Testing.Platform/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt index 2a894256ed..0b25149d85 100644 --- a/src/Platform/Microsoft.Testing.Platform/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/Platform/Microsoft.Testing.Platform/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt @@ -1,4 +1,10 @@ #nullable enable +~override Microsoft.Testing.Platform.Extensions.Messages.LinePosition.Equals(object obj) -> bool +~override Microsoft.Testing.Platform.Extensions.Messages.LinePosition.ToString() -> string +~override Microsoft.Testing.Platform.Extensions.Messages.LinePositionSpan.Equals(object obj) -> bool +~override Microsoft.Testing.Platform.Extensions.Messages.LinePositionSpan.ToString() -> string +~override Microsoft.Testing.Platform.Extensions.Messages.TimingInfo.Equals(object obj) -> bool +~override Microsoft.Testing.Platform.Extensions.Messages.TimingInfo.ToString() -> string abstract Microsoft.Testing.Platform.Extensions.Messages.FileLocationProperty.$() -> Microsoft.Testing.Platform.Extensions.Messages.FileLocationProperty! abstract Microsoft.Testing.Platform.Extensions.Messages.TestNodeStateProperty.$() -> Microsoft.Testing.Platform.Extensions.Messages.TestNodeStateProperty! Microsoft.Testing.Platform.Extensions.Messages.CancelledTestNodeStateProperty.Equals(Microsoft.Testing.Platform.Extensions.Messages.CancelledTestNodeStateProperty? other) -> bool @@ -155,9 +161,3 @@ virtual Microsoft.Testing.Platform.Extensions.Messages.KeyValuePairStringPropert virtual Microsoft.Testing.Platform.Extensions.Messages.TestNodeStateProperty.EqualityContract.get -> System.Type! virtual Microsoft.Testing.Platform.Extensions.Messages.TestNodeStateProperty.Equals(Microsoft.Testing.Platform.Extensions.Messages.TestNodeStateProperty? other) -> bool virtual Microsoft.Testing.Platform.Extensions.Messages.TestNodeStateProperty.PrintMembers(System.Text.StringBuilder! builder) -> bool -~override Microsoft.Testing.Platform.Extensions.Messages.LinePosition.Equals(object obj) -> bool -~override Microsoft.Testing.Platform.Extensions.Messages.LinePosition.ToString() -> string -~override Microsoft.Testing.Platform.Extensions.Messages.LinePositionSpan.Equals(object obj) -> bool -~override Microsoft.Testing.Platform.Extensions.Messages.LinePositionSpan.ToString() -> string -~override Microsoft.Testing.Platform.Extensions.Messages.TimingInfo.Equals(object obj) -> bool -~override Microsoft.Testing.Platform.Extensions.Messages.TimingInfo.ToString() -> string diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Shipped.txt index 171e5fe5e8..a6d5027834 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Shipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Shipped.txt @@ -1,4 +1,4 @@ -#nullable enable +#nullable enable abstract Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.AddResultFile(string! fileName) -> void abstract Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.Properties.get -> System.Collections.IDictionary! abstract Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.Write(string! format, params object?[]! args) -> void @@ -7,10 +7,16 @@ abstract Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.WriteLine(stri abstract Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.WriteLine(string? message) -> void Microsoft.VisualStudio.TestTools.UnitTesting.TestContext Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestContext() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestData.get -> object?[]? +Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestData.set -> void +Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDisplayName.get -> string? +Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDisplayName.set -> void +Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestException.get -> System.Exception? +Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestException.set -> void virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.CancellationTokenSource.get -> System.Threading.CancellationTokenSource! virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.CancellationTokenSource.set -> void virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.CurrentTestOutcome.get -> Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.FullyQualifiedTestClassName.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.ManagedMethod.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.ManagedType.get -> string? -virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestName.get -> string? \ No newline at end of file +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestName.get -> string? diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt index c45dd334cb..7dc5c58110 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt @@ -1,7 +1 @@ -#nullable enable -Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDisplayName.get -> string? -Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDisplayName.set -> void -Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestData.get -> object?[]? -Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestData.set -> void -Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestException.get -> System.Exception? -Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestException.set -> void +#nullable enable diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net462/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net462/PublicAPI.Shipped.txt index db3836f496..4858a49c17 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net462/PublicAPI.Shipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net462/PublicAPI.Shipped.txt @@ -21,17 +21,17 @@ Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceElementCollection.this[in Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceElementCollection.this[int index].set -> void Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceElementCollection.this[string! name].get -> Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceElement! Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute -Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path, string? outputDirectory) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.OutputDirectory.get -> string? Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.Path.get -> string? Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.GetArrayElement(string! name, params int[]! indices) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.GetArrayElement(string! name, System.Reflection.BindingFlags bindingFlags, params int[]! indices) -> object! -Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.GetField(string! name) -> object? Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.GetField(string! name, System.Reflection.BindingFlags bindingFlags) -> object? -Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.GetFieldOrProperty(string! name) -> object? +Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.GetField(string! name) -> object? Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.GetFieldOrProperty(string! name, System.Reflection.BindingFlags bindingFlags) -> object? +Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.GetFieldOrProperty(string! name) -> object? Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.GetProperty(string! name, params object?[]? args) -> object? Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.GetProperty(string! name, System.Reflection.BindingFlags bindingFlags, params object?[]? args) -> object? Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.GetProperty(string! name, System.Reflection.BindingFlags bindingFlags, System.Type![]? parameterTypes, object?[]? args) -> object? @@ -43,12 +43,12 @@ Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.Invoke(string! name, Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.Invoke(string! name, System.Reflection.BindingFlags bindingFlags, System.Type![]! parameterTypes, object?[]? args) -> object? Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.Invoke(string! name, System.Reflection.BindingFlags bindingFlags, System.Type![]? parameterTypes, object?[]? args, System.Globalization.CultureInfo! culture) -> object? Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.Invoke(string! name, System.Reflection.BindingFlags bindingFlags, System.Type![]? parameterTypes, object?[]? args, System.Globalization.CultureInfo? culture, System.Type![]? typeArguments) -> object? -Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.Invoke(string! name, System.Type![]! parameterTypes, object?[]? args) -> object? Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.Invoke(string! name, System.Type![]! parameterTypes, object?[]? args, System.Type![]! typeArguments) -> object? +Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.Invoke(string! name, System.Type![]! parameterTypes, object?[]? args) -> object? Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.Invoke(string! name, System.Type![]? parameterTypes, object?[]? args, System.Globalization.CultureInfo! culture) -> object? -Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.PrivateObject(object! obj) -> void Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.PrivateObject(object! obj, Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType! type) -> void Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.PrivateObject(object! obj, string! memberToAccess) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.PrivateObject(object! obj) -> void Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.PrivateObject(string! assemblyName, string! typeName, params object?[]? args) -> void Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.PrivateObject(string! assemblyName, string! typeName, System.Type![]? parameterTypes, object?[]? args) -> void Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.PrivateObject(System.Type! type, params object?[]? args) -> void @@ -69,10 +69,10 @@ Microsoft.VisualStudio.TestTools.UnitTesting.PrivateObject.Target.set -> void Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.GetStaticArrayElement(string! name, params int[]! indices) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.GetStaticArrayElement(string! name, System.Reflection.BindingFlags bindingFlags, params int[]! indices) -> object! -Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.GetStaticField(string! name) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.GetStaticField(string! name, System.Reflection.BindingFlags bindingFlags) -> object! -Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.GetStaticFieldOrProperty(string! name) -> object! +Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.GetStaticField(string! name) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.GetStaticFieldOrProperty(string! name, System.Reflection.BindingFlags bindingFlags) -> object! +Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.GetStaticFieldOrProperty(string! name) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.GetStaticProperty(string! name, params object?[]? args) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.GetStaticProperty(string! name, System.Reflection.BindingFlags bindingFlags, params object?[]? args) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.GetStaticProperty(string! name, System.Reflection.BindingFlags bindingFlags, System.Type![]? parameterTypes, object?[]? args) -> object! @@ -80,12 +80,12 @@ Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! na Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, params object?[]? args) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, System.Reflection.BindingFlags bindingFlags, object?[]? args, System.Globalization.CultureInfo? culture) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, System.Reflection.BindingFlags bindingFlags, params object?[]? args) -> object! -Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, System.Reflection.BindingFlags bindingFlags, System.Type![]? parameterTypes, object?[]? args) -> object! -Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, System.Reflection.BindingFlags bindingFlags, System.Type![]? parameterTypes, object?[]? args, System.Globalization.CultureInfo? culture) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, System.Reflection.BindingFlags bindingFlags, System.Type![]? parameterTypes, object?[]? args, System.Globalization.CultureInfo? culture, System.Type![]? typeArguments) -> object! -Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, System.Type![]? parameterTypes, object?[]? args) -> object! +Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, System.Reflection.BindingFlags bindingFlags, System.Type![]? parameterTypes, object?[]? args, System.Globalization.CultureInfo? culture) -> object! +Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, System.Reflection.BindingFlags bindingFlags, System.Type![]? parameterTypes, object?[]? args) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, System.Type![]? parameterTypes, object?[]? args, System.Globalization.CultureInfo? culture) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, System.Type![]? parameterTypes, object?[]? args, System.Type![]! typeArguments) -> object! +Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.InvokeStatic(string! name, System.Type![]? parameterTypes, object?[]? args) -> object! Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.PrivateType(string! assemblyName, string! typeName) -> void Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.PrivateType(System.Type! type) -> void Microsoft.VisualStudio.TestTools.UnitTesting.PrivateType.ReferencedType.get -> System.Type! @@ -113,4 +113,4 @@ virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDir.get -> virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestLogsDir.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestResultsDirectory.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunDirectory.get -> string? -virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? \ No newline at end of file +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net462/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net462/PublicAPI.Unshipped.txt index 815c92006a..7dc5c58110 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net462/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net462/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable \ No newline at end of file +#nullable enable diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Shipped.txt index e713c74671..e9b28f1b28 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Shipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Shipped.txt @@ -7,4 +7,4 @@ Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer.WinUITestTargetAttribu Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer.WinUITestTargetAttribute.WinUITestTargetAttribute(System.Type! applicationType) -> void override Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer.UITestMethodAttribute.Execute(Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod! testMethod) -> Microsoft.VisualStudio.TestTools.UnitTesting.TestResult![]! static Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer.UITestMethodAttribute.DispatcherQueue.get -> Microsoft.UI.Dispatching.DispatcherQueue? -static Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer.UITestMethodAttribute.DispatcherQueue.set -> void \ No newline at end of file +static Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer.UITestMethodAttribute.DispatcherQueue.set -> void diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Unshipped.txt index 815c92006a..7dc5c58110 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0-windows10.0.18362.0/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable \ No newline at end of file +#nullable enable diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0/PublicAPI.Shipped.txt index f9d5205b2e..3b3aac1df0 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0/PublicAPI.Shipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0/PublicAPI.Shipped.txt @@ -1,7 +1,7 @@ #nullable enable Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute -Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path, string? outputDirectory) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.OutputDirectory.get -> string? Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.Path.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.DeploymentDirectory.get -> string? @@ -11,4 +11,4 @@ virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDir.get -> virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestLogsDir.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestResultsDirectory.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunDirectory.get -> string? -virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? \ No newline at end of file +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0/PublicAPI.Unshipped.txt index 815c92006a..7dc5c58110 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net6.0/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable \ No newline at end of file +#nullable enable diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net7.0/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net7.0/PublicAPI.Shipped.txt index f9d5205b2e..3b3aac1df0 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net7.0/PublicAPI.Shipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net7.0/PublicAPI.Shipped.txt @@ -1,7 +1,7 @@ #nullable enable Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute -Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path, string? outputDirectory) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.OutputDirectory.get -> string? Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.Path.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.DeploymentDirectory.get -> string? @@ -11,4 +11,4 @@ virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDir.get -> virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestLogsDir.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestResultsDirectory.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunDirectory.get -> string? -virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? \ No newline at end of file +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net7.0/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net7.0/PublicAPI.Unshipped.txt index 815c92006a..7dc5c58110 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net7.0/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net7.0/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable \ No newline at end of file +#nullable enable diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net8.0/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net8.0/PublicAPI.Shipped.txt index f9d5205b2e..3b3aac1df0 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net8.0/PublicAPI.Shipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net8.0/PublicAPI.Shipped.txt @@ -1,7 +1,7 @@ #nullable enable Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute -Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path, string? outputDirectory) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.OutputDirectory.get -> string? Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.Path.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.DeploymentDirectory.get -> string? @@ -11,4 +11,4 @@ virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDir.get -> virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestLogsDir.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestResultsDirectory.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunDirectory.get -> string? -virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? \ No newline at end of file +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net8.0/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net8.0/PublicAPI.Unshipped.txt index 815c92006a..7dc5c58110 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net8.0/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net8.0/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable \ No newline at end of file +#nullable enable diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Shipped.txt index f9d5205b2e..3b3aac1df0 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Shipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Shipped.txt @@ -1,7 +1,7 @@ #nullable enable Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute -Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path, string? outputDirectory) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.OutputDirectory.get -> string? Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.Path.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.DeploymentDirectory.get -> string? @@ -11,4 +11,4 @@ virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDir.get -> virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestLogsDir.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestResultsDirectory.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunDirectory.get -> string? -virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? \ No newline at end of file +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Unshipped.txt index 815c92006a..7dc5c58110 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/net9.0/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable \ No newline at end of file +#nullable enable diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/netcoreapp3.1/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/netcoreapp3.1/PublicAPI.Shipped.txt index e6913a4006..3b3aac1df0 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/netcoreapp3.1/PublicAPI.Shipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/netcoreapp3.1/PublicAPI.Shipped.txt @@ -1,7 +1,7 @@ #nullable enable Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute -Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path, string? outputDirectory) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.OutputDirectory.get -> string? Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.Path.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.DeploymentDirectory.get -> string? diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt index 815c92006a..7dc5c58110 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/netcoreapp3.1/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable \ No newline at end of file +#nullable enable diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt index f9d5205b2e..3b3aac1df0 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/netstandard2.0/PublicAPI.Shipped.txt @@ -1,7 +1,7 @@ #nullable enable Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute -Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path, string? outputDirectory) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.DeploymentItemAttribute(string? path) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.OutputDirectory.get -> string? Microsoft.VisualStudio.TestTools.UnitTesting.DeploymentItemAttribute.Path.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.DeploymentDirectory.get -> string? @@ -11,4 +11,4 @@ virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestDir.get -> virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestLogsDir.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestResultsDirectory.get -> string? virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunDirectory.get -> string? -virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? \ No newline at end of file +virtual Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.TestRunResultsDirectory.get -> string? diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt index 815c92006a..7dc5c58110 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/netstandard2.0/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable \ No newline at end of file +#nullable enable diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt index f78acd369f..63494b4a7a 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/uap10.0.16299/PublicAPI.Shipped.txt @@ -1,4 +1,4 @@ #nullable enable Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer.UITestMethodAttribute Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer.UITestMethodAttribute.UITestMethodAttribute() -> void -override Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer.UITestMethodAttribute.Execute(Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod! testMethod) -> Microsoft.VisualStudio.TestTools.UnitTesting.TestResult![]! \ No newline at end of file +override Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer.UITestMethodAttribute.Execute(Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod! testMethod) -> Microsoft.VisualStudio.TestTools.UnitTesting.TestResult![]! diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt index 815c92006a..7dc5c58110 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/uap10.0.16299/PublicAPI.Unshipped.txt @@ -1 +1 @@ -#nullable enable \ No newline at end of file +#nullable enable diff --git a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Shipped.txt index 23ce9ae2e1..d2f9fb2434 100644 --- a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Shipped.txt +++ b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Shipped.txt @@ -1,4 +1,4 @@ -#nullable enable +#nullable enable abstract Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionBaseAttribute.Verify(System.Exception! exception) -> void abstract Microsoft.VisualStudio.TestTools.UnitTesting.TestCategoryBaseAttribute.TestCategories.get -> System.Collections.Generic.IList! Microsoft.VisualStudio.TestTools.UnitTesting.AssemblyCleanupAttribute @@ -8,17 +8,17 @@ Microsoft.VisualStudio.TestTools.UnitTesting.AssemblyInitializeAttribute.Assembl Microsoft.VisualStudio.TestTools.UnitTesting.Assert Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException.AssertFailedException() -> void -Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException.AssertFailedException(string! msg) -> void Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException.AssertFailedException(string! msg, System.Exception! ex) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.AssertFailedException.AssertFailedException(string! msg) -> void Microsoft.VisualStudio.TestTools.UnitTesting.AssertInconclusiveException Microsoft.VisualStudio.TestTools.UnitTesting.AssertInconclusiveException.AssertInconclusiveException() -> void -Microsoft.VisualStudio.TestTools.UnitTesting.AssertInconclusiveException.AssertInconclusiveException(string! msg) -> void Microsoft.VisualStudio.TestTools.UnitTesting.AssertInconclusiveException.AssertInconclusiveException(string! msg, System.Exception! ex) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.AssertInconclusiveException.AssertInconclusiveException(string! msg) -> void Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute.ClassCleanupAttribute() -> void Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute.ClassCleanupAttribute(Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupBehavior cleanupBehavior) -> void -Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute.ClassCleanupAttribute(Microsoft.VisualStudio.TestTools.UnitTesting.InheritanceBehavior inheritanceBehavior) -> void Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute.ClassCleanupAttribute(Microsoft.VisualStudio.TestTools.UnitTesting.InheritanceBehavior inheritanceBehavior, Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupBehavior cleanupBehavior) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute.ClassCleanupAttribute(Microsoft.VisualStudio.TestTools.UnitTesting.InheritanceBehavior inheritanceBehavior) -> void Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute.CleanupBehavior.get -> Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupBehavior? Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute.InheritanceBehavior.get -> Microsoft.VisualStudio.TestTools.UnitTesting.InheritanceBehavior Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupBehavior @@ -51,6 +51,8 @@ Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.DataRowAttribute(s Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.DisplayName.get -> string? Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.DisplayName.set -> void Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.GetData(System.Reflection.MethodInfo! methodInfo) -> System.Collections.Generic.IEnumerable! +Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.UnfoldingStrategy.set -> void Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceAttribute Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceAttribute.ConnectionString.get -> string? Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceAttribute.DataAccessMethod.get -> Microsoft.VisualStudio.TestTools.UnitTesting.DataAccessMethod @@ -79,6 +81,8 @@ Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataDis Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataDisplayNameDeclaringType.set -> void Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.GetData(System.Reflection.MethodInfo! methodInfo) -> System.Collections.Generic.IEnumerable! Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.GetDisplayName(System.Reflection.MethodInfo! methodInfo, object?[]? data) -> string? +Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.UnfoldingStrategy.set -> void Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Method = 1 -> Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Property = 0 -> Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType @@ -89,8 +93,8 @@ Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionAttribute Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionAttribute.AllowDerivedTypes.get -> bool Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionAttribute.AllowDerivedTypes.set -> void Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionAttribute.ExceptionType.get -> System.Type! -Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionAttribute.ExpectedExceptionAttribute(System.Type! exceptionType) -> void Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionAttribute.ExpectedExceptionAttribute(System.Type! exceptionType, string! noExceptionMessage) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionAttribute.ExpectedExceptionAttribute(System.Type! exceptionType) -> void Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionBaseAttribute Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionBaseAttribute.ExpectedExceptionBaseAttribute() -> void Microsoft.VisualStudio.TestTools.UnitTesting.ExpectedExceptionBaseAttribute.ExpectedExceptionBaseAttribute(string? noExceptionMessage) -> void @@ -113,11 +117,13 @@ Microsoft.VisualStudio.TestTools.UnitTesting.InheritanceBehavior.BeforeEachDeriv Microsoft.VisualStudio.TestTools.UnitTesting.InheritanceBehavior.None = 0 -> Microsoft.VisualStudio.TestTools.UnitTesting.InheritanceBehavior Microsoft.VisualStudio.TestTools.UnitTesting.InternalTestFailureException Microsoft.VisualStudio.TestTools.UnitTesting.InternalTestFailureException.InternalTestFailureException() -> void -Microsoft.VisualStudio.TestTools.UnitTesting.InternalTestFailureException.InternalTestFailureException(string! msg) -> void Microsoft.VisualStudio.TestTools.UnitTesting.InternalTestFailureException.InternalTestFailureException(string! msg, System.Exception! ex) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.InternalTestFailureException.InternalTestFailureException(string! msg) -> void Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSource Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSource.GetData(System.Reflection.MethodInfo! methodInfo) -> System.Collections.Generic.IEnumerable! Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSource.GetDisplayName(System.Reflection.MethodInfo! methodInfo, object?[]? data) -> string? +Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSourceUnfoldingCapability +Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSourceUnfoldingCapability.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod.Arguments.get -> object?[]? Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod.GetAllAttributes(bool inherit) -> System.Attribute![]? @@ -163,6 +169,13 @@ Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceDiscoveryAttribute.Te Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceDiscoveryOption Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceDiscoveryOption.DuringDiscovery = 2 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceDiscoveryOption Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceDiscoveryOption.DuringExecution = 1 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceDiscoveryOption +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceOptionsAttribute +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceOptionsAttribute.TestDataSourceOptionsAttribute(Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy unfoldingStrategy) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceOptionsAttribute.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy.Auto = 0 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy.Fold = 2 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy.Unfold = 1 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy Microsoft.VisualStudio.TestTools.UnitTesting.TestIdGenerationStrategy Microsoft.VisualStudio.TestTools.UnitTesting.TestIdGenerationStrategy.DisplayName = 1 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestIdGenerationStrategy Microsoft.VisualStudio.TestTools.UnitTesting.TestIdGenerationStrategy.FullyQualified = 2 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestIdGenerationStrategy @@ -220,8 +233,8 @@ Microsoft.VisualStudio.TestTools.UnitTesting.TimeoutAttribute.TimeoutAttribute(i Microsoft.VisualStudio.TestTools.UnitTesting.TimeoutAttribute.TimeoutAttribute(Microsoft.VisualStudio.TestTools.UnitTesting.TestTimeout timeout) -> void Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestAssertException Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestAssertException.UnitTestAssertException() -> void -Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestAssertException.UnitTestAssertException(string! msg) -> void Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestAssertException.UnitTestAssertException(string! msg, System.Exception! ex) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestAssertException.UnitTestAssertException(string! msg) -> void Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome.Aborted = 6 -> Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome.Error = 4 -> Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome @@ -239,187 +252,187 @@ Microsoft.VisualStudio.TestTools.UnitTesting.WorkItemAttribute.WorkItemAttribute override Microsoft.VisualStudio.TestTools.UnitTesting.GenericParameterHelper.Equals(object? obj) -> bool override Microsoft.VisualStudio.TestTools.UnitTesting.GenericParameterHelper.GetHashCode() -> int override Microsoft.VisualStudio.TestTools.UnitTesting.TestCategoryAttribute.TestCategories.get -> System.Collections.Generic.IList! -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(decimal expected, decimal actual, decimal delta) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(decimal expected, decimal actual, decimal delta, string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(decimal expected, decimal actual, decimal delta, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(double expected, double actual, double delta) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(double expected, double actual, double delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(decimal expected, decimal actual, decimal delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(decimal expected, decimal actual, decimal delta) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(double expected, double actual, double delta, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(float expected, float actual, float delta) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(float expected, float actual, float delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(double expected, double actual, double delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(double expected, double actual, double delta) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(float expected, float actual, float delta, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(long expected, long actual, long delta) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(long expected, long actual, long delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(float expected, float actual, float delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(float expected, float actual, float delta) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(long expected, long actual, long delta, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(long expected, long actual, long delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(long expected, long actual, long delta) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase, string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(System.IEquatable? expected, System.IEquatable? actual) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(System.IEquatable? expected, System.IEquatable? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(System.IEquatable? expected, System.IEquatable? actual, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(System.IEquatable? expected, System.IEquatable? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(System.IEquatable? expected, System.IEquatable? actual) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual, System.Collections.Generic.IEqualityComparer? comparer) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual, string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(decimal notExpected, decimal actual, decimal delta) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(decimal notExpected, decimal actual, decimal delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual, System.Collections.Generic.IEqualityComparer? comparer) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(decimal notExpected, decimal actual, decimal delta, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(double notExpected, double actual, double delta) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(double notExpected, double actual, double delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(decimal notExpected, decimal actual, decimal delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(decimal notExpected, decimal actual, decimal delta) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(double notExpected, double actual, double delta, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(float notExpected, float actual, float delta) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(float notExpected, float actual, float delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(double notExpected, double actual, double delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(double notExpected, double actual, double delta) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(float notExpected, float actual, float delta, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(long notExpected, long actual, long delta) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(long notExpected, long actual, long delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(float notExpected, float actual, float delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(float notExpected, float actual, float delta) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(long notExpected, long actual, long delta, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(long notExpected, long actual, long delta, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(long notExpected, long actual, long delta) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase, string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual, System.Collections.Generic.IEqualityComparer? comparer) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual, string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotSame(T? notExpected, T? actual) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotSame(T? notExpected, T? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual, System.Collections.Generic.IEqualityComparer? comparer) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotSame(T? notExpected, T? actual, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreSame(T? expected, T? actual) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreSame(T? expected, T? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotSame(T? notExpected, T? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotSame(T? notExpected, T? actual) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreSame(T? expected, T? actual, string? message, params object?[]? parameters) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreSame(T? expected, T? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreSame(T? expected, T? actual) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Equals(object? objA, object? objB) -> bool static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail() -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail(string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail(string? message, params object?[]? parameters) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Fail(string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Inconclusive() -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Inconclusive(string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Inconclusive(string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool condition) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool condition, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Inconclusive(string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool condition, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool? condition) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool? condition, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool condition, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool condition) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool? condition, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, System.Type? expectedType) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, System.Type? expectedType, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool? condition, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool? condition) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, System.Type? expectedType, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, out T instance) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, out T instance, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, System.Type? expectedType, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, System.Type? expectedType) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, out T instance, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, out T instance, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, out T instance) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value, System.Type? wrongType) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value, System.Type? wrongType, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value, System.Type? wrongType, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value, System.Type? wrongType, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value, System.Type? wrongType) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(object? value) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(object? value, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(object? value, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNull(object? value) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNull(object? value, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(object? value, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(object? value) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNull(object? value, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool condition) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool condition, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNull(object? value, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNull(object? value) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool condition, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool? condition) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool? condition, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool condition, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool condition) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool? condition, string? message, params object?[]? parameters) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool? condition, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool? condition) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ReplaceNullChars(string? input) -> string? static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.That.get -> Microsoft.VisualStudio.TestTools.UnitTesting.Assert! -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException(System.Action! action) -> T! -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException(System.Action! action, string! message) -> T! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException(System.Action! action, string! message, params object?[]? parameters) -> T! -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException(System.Func! action) -> T! -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException(System.Func! action, string! message) -> T! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException(System.Action! action, string! message) -> T! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException(System.Action! action) -> T! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException(System.Func! action, string! message, params object?[]? parameters) -> T! -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExceptionAsync(System.Func! action) -> System.Threading.Tasks.Task! -static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExceptionAsync(System.Func! action, string! message) -> System.Threading.Tasks.Task! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException(System.Func! action, string! message) -> T! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsException(System.Func! action) -> T! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExceptionAsync(System.Func! action, string! message, params object?[]? parameters) -> System.Threading.Tasks.Task! -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreInstancesOfType(System.Collections.ICollection? collection, System.Type? expectedType) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreInstancesOfType(System.Collections.ICollection? collection, System.Type? expectedType, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExceptionAsync(System.Func! action, string! message) -> System.Threading.Tasks.Task! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExceptionAsync(System.Func! action) -> System.Threading.Tasks.Task! static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreInstancesOfType(System.Collections.ICollection? collection, System.Type? expectedType, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreNotNull(System.Collections.ICollection? collection) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreNotNull(System.Collections.ICollection? collection, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreInstancesOfType(System.Collections.ICollection? collection, System.Type? expectedType, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreInstancesOfType(System.Collections.ICollection? collection, System.Type? expectedType) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreNotNull(System.Collections.ICollection? collection, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreUnique(System.Collections.ICollection? collection) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreUnique(System.Collections.ICollection? collection, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreNotNull(System.Collections.ICollection? collection, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreNotNull(System.Collections.ICollection? collection) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreUnique(System.Collections.ICollection? collection, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEqual(System.Collections.ICollection? expected, System.Collections.ICollection? actual) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEqual(System.Collections.ICollection? expected, System.Collections.ICollection? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreUnique(System.Collections.ICollection? collection, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AllItemsAreUnique(System.Collections.ICollection? collection) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEqual(System.Collections.ICollection? expected, System.Collections.ICollection? actual, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEqual(System.Collections.ICollection? expected, System.Collections.ICollection? actual, System.Collections.IComparer? comparer) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEqual(System.Collections.ICollection? expected, System.Collections.ICollection? actual, System.Collections.IComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEqual(System.Collections.ICollection? expected, System.Collections.ICollection? actual, string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEqual(System.Collections.ICollection? expected, System.Collections.ICollection? actual, System.Collections.IComparer? comparer, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEquivalent(System.Collections.ICollection? expected, System.Collections.ICollection? actual) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEquivalent(System.Collections.ICollection? expected, System.Collections.ICollection? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEqual(System.Collections.ICollection? expected, System.Collections.ICollection? actual, System.Collections.IComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEqual(System.Collections.ICollection? expected, System.Collections.ICollection? actual, System.Collections.IComparer? comparer) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEqual(System.Collections.ICollection? expected, System.Collections.ICollection? actual) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEquivalent(System.Collections.ICollection? expected, System.Collections.ICollection? actual, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEquivalent(System.Collections.Generic.IEnumerable? expected, System.Collections.Generic.IEnumerable? actual, System.Collections.Generic.IEqualityComparer? comparer) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEquivalent(System.Collections.Generic.IEnumerable? expected, System.Collections.Generic.IEnumerable? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEquivalent(System.Collections.ICollection? expected, System.Collections.ICollection? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEquivalent(System.Collections.ICollection? expected, System.Collections.ICollection? actual) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEquivalent(System.Collections.Generic.IEnumerable? expected, System.Collections.Generic.IEnumerable? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEqual(System.Collections.ICollection? notExpected, System.Collections.ICollection? actual) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEqual(System.Collections.ICollection? notExpected, System.Collections.ICollection? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEquivalent(System.Collections.Generic.IEnumerable? expected, System.Collections.Generic.IEnumerable? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreEquivalent(System.Collections.Generic.IEnumerable? expected, System.Collections.Generic.IEnumerable? actual, System.Collections.Generic.IEqualityComparer? comparer) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEqual(System.Collections.ICollection? notExpected, System.Collections.ICollection? actual, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEqual(System.Collections.ICollection? notExpected, System.Collections.ICollection? actual, System.Collections.IComparer? comparer) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEqual(System.Collections.ICollection? notExpected, System.Collections.ICollection? actual, System.Collections.IComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEqual(System.Collections.ICollection? notExpected, System.Collections.ICollection? actual, string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEqual(System.Collections.ICollection? notExpected, System.Collections.ICollection? actual, System.Collections.IComparer? comparer, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEquivalent(System.Collections.ICollection? expected, System.Collections.ICollection? actual) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEquivalent(System.Collections.ICollection? expected, System.Collections.ICollection? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEqual(System.Collections.ICollection? notExpected, System.Collections.ICollection? actual, System.Collections.IComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEqual(System.Collections.ICollection? notExpected, System.Collections.ICollection? actual, System.Collections.IComparer? comparer) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEqual(System.Collections.ICollection? notExpected, System.Collections.ICollection? actual) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEquivalent(System.Collections.ICollection? expected, System.Collections.ICollection? actual, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEquivalent(System.Collections.Generic.IEnumerable? expected, System.Collections.Generic.IEnumerable? actual, System.Collections.Generic.IEqualityComparer? comparer) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEquivalent(System.Collections.Generic.IEnumerable? expected, System.Collections.Generic.IEnumerable? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEquivalent(System.Collections.ICollection? expected, System.Collections.ICollection? actual, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEquivalent(System.Collections.ICollection? expected, System.Collections.ICollection? actual) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEquivalent(System.Collections.Generic.IEnumerable? expected, System.Collections.Generic.IEnumerable? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.Contains(System.Collections.ICollection? collection, object? element) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.Contains(System.Collections.ICollection? collection, object? element, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEquivalent(System.Collections.Generic.IEnumerable? expected, System.Collections.Generic.IEnumerable? actual, System.Collections.Generic.IEqualityComparer? comparer, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.AreNotEquivalent(System.Collections.Generic.IEnumerable? expected, System.Collections.Generic.IEnumerable? actual, System.Collections.Generic.IEqualityComparer? comparer) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.Contains(System.Collections.ICollection? collection, object? element, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.DoesNotContain(System.Collections.ICollection? collection, object? element) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.DoesNotContain(System.Collections.ICollection? collection, object? element, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.Contains(System.Collections.ICollection? collection, object? element, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.Contains(System.Collections.ICollection? collection, object? element) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.DoesNotContain(System.Collections.ICollection? collection, object? element, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.IsNotSubsetOf(System.Collections.ICollection? subset, System.Collections.ICollection? superset) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.IsNotSubsetOf(System.Collections.ICollection? subset, System.Collections.ICollection? superset, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.DoesNotContain(System.Collections.ICollection? collection, object? element, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.DoesNotContain(System.Collections.ICollection? collection, object? element) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.IsNotSubsetOf(System.Collections.ICollection? subset, System.Collections.ICollection? superset, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.IsSubsetOf(System.Collections.ICollection? subset, System.Collections.ICollection? superset) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.IsSubsetOf(System.Collections.ICollection? subset, System.Collections.ICollection? superset, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.IsNotSubsetOf(System.Collections.ICollection? subset, System.Collections.ICollection? superset, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.IsNotSubsetOf(System.Collections.ICollection? subset, System.Collections.ICollection? superset) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.IsSubsetOf(System.Collections.ICollection? subset, System.Collections.ICollection? superset, string? message, params object?[]? parameters) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.IsSubsetOf(System.Collections.ICollection? subset, System.Collections.ICollection? superset, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.IsSubsetOf(System.Collections.ICollection? subset, System.Collections.ICollection? superset) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert.That.get -> Microsoft.VisualStudio.TestTools.UnitTesting.CollectionAssert! static Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.TestIdGenerationStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestIdGenerationStrategy static Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessage(string! format, params object?[]! args) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.OnLogMessage -> Microsoft.VisualStudio.TestTools.UnitTesting.Logging.Logger.LogMessageHandler? -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains(string? value, string? substring) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains(string? value, string? substring, string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains(string? value, string? substring, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains(string? value, string? substring, string? message, System.StringComparison comparisonType) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains(string? value, string? substring, string? message, System.StringComparison comparisonType, params object?[]? parameters) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains(string? value, string? substring, string? message, System.StringComparison comparisonType) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains(string? value, string? substring, string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains(string? value, string? substring, System.StringComparison comparisonType) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.DoesNotMatch(string? value, System.Text.RegularExpressions.Regex? pattern) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.DoesNotMatch(string? value, System.Text.RegularExpressions.Regex? pattern, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Contains(string? value, string? substring) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.DoesNotMatch(string? value, System.Text.RegularExpressions.Regex? pattern, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.EndsWith(string? value, string? substring) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.EndsWith(string? value, string? substring, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.DoesNotMatch(string? value, System.Text.RegularExpressions.Regex? pattern, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.DoesNotMatch(string? value, System.Text.RegularExpressions.Regex? pattern) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.EndsWith(string? value, string? substring, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.EndsWith(string? value, string? substring, string? message, System.StringComparison comparisonType) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.EndsWith(string? value, string? substring, string? message, System.StringComparison comparisonType, params object?[]? parameters) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.EndsWith(string? value, string? substring, string? message, System.StringComparison comparisonType) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.EndsWith(string? value, string? substring, string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.EndsWith(string? value, string? substring, System.StringComparison comparisonType) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Matches(string? value, System.Text.RegularExpressions.Regex? pattern) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Matches(string? value, System.Text.RegularExpressions.Regex? pattern, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.EndsWith(string? value, string? substring) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Matches(string? value, System.Text.RegularExpressions.Regex? pattern, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.StartsWith(string? value, string? substring) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.StartsWith(string? value, string? substring, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Matches(string? value, System.Text.RegularExpressions.Regex? pattern, string? message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.Matches(string? value, System.Text.RegularExpressions.Regex? pattern) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.StartsWith(string? value, string? substring, string? message, params object?[]? parameters) -> void -static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.StartsWith(string? value, string? substring, string? message, System.StringComparison comparisonType) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.StartsWith(string? value, string? substring, string? message, System.StringComparison comparisonType, params object?[]? parameters) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.StartsWith(string? value, string? substring, string? message, System.StringComparison comparisonType) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.StartsWith(string? value, string? substring, string? message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.StartsWith(string? value, string? substring, System.StringComparison comparisonType) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.StartsWith(string? value, string? substring) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert.That.get -> Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert! static readonly Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupExecutionAttribute.DefaultClassCleanupLifecycle -> Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupBehavior static readonly Microsoft.VisualStudio.TestTools.UnitTesting.DataSourceAttribute.DefaultDataAccessMethod -> Microsoft.VisualStudio.TestTools.UnitTesting.DataAccessMethod diff --git a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt index d3d4ae8281..7dc5c58110 100644 --- a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt @@ -1,14 +1 @@ -#nullable enable -Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy -Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.UnfoldingStrategy.set -> void -Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy -Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.UnfoldingStrategy.set -> void -Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSourceUnfoldingCapability -Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSourceUnfoldingCapability.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy -Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceOptionsAttribute -Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceOptionsAttribute.TestDataSourceOptionsAttribute(Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy unfoldingStrategy) -> void -Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceOptionsAttribute.UnfoldingStrategy.get -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy -Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy -Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy.Auto = 0 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy -Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy.Fold = 2 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy -Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy.Unfold = 1 -> Microsoft.VisualStudio.TestTools.UnitTesting.TestDataSourceUnfoldingStrategy +#nullable enable From 2a2646663a5eff319df82ef014ac99918d20fa82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sat, 14 Dec 2024 00:49:11 +0100 Subject: [PATCH 115/273] Make MSTest.TestFramework depends upon MSTest.Analyzers (#4351) --- .../MSTest.TestFramework.NonWindows.nuspec | 24 ++++++++++---- .../MSTest.TestFramework.nuspec | 32 ++++++++++++++----- 2 files changed, 42 insertions(+), 14 deletions(-) diff --git a/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.NonWindows.nuspec b/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.NonWindows.nuspec index 0ec5da8496..db5be825a8 100644 --- a/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.NonWindows.nuspec +++ b/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.NonWindows.nuspec @@ -3,12 +3,24 @@ $CommonMetadataElements$ - - - - - - + + + + + + + + + + + + + + + + + + PACKAGE.md diff --git a/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.nuspec b/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.nuspec index 9e9a3ce8a3..39c53e3c29 100644 --- a/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.nuspec +++ b/src/TestFramework/TestFramework.Extensions/MSTest.TestFramework.nuspec @@ -3,14 +3,30 @@ $CommonMetadataElements$ - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + PACKAGE.md From 47cda79f758ee8c93acd90275946b0fb61819925 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sat, 14 Dec 2024 20:35:10 +0100 Subject: [PATCH 116/273] Make obsolete only on release (#4353) --- .../Execution/LogMessageListener.cs | 2 ++ .../Execution/TestAssemblyInfo.cs | 2 ++ .../Execution/TestClassInfo.cs | 2 ++ .../Execution/TestExecutionManager.cs | 2 ++ .../Execution/TestMethodInfo.cs | 2 ++ .../Execution/TestRunCancellationToken.cs | 2 ++ .../Extensions/UnitTestOutcomeExtensions.cs | 2 ++ .../MSTest.TestAdapter/MSTestSettings.cs | 2 ++ .../ObjectModel/TestMethod.cs | 2 ++ .../ObjectModel/UnitTestOutcome.cs | 2 ++ .../ObjectModel/UnitTestResult.cs | 2 ++ .../RunConfigurationSettings.cs | 2 ++ .../VSTestAdapter/MSTestDiscoverer.cs | 2 ++ .../VSTestAdapter/MSTestExecutor.cs | 2 ++ .../AssemblyResolver.cs | 2 ++ .../Deployment/TestRunDirectories.cs | 2 ++ .../Interfaces/IAdapterTraceLogger.cs | 2 ++ .../Interfaces/IFileOperations.cs | 2 ++ .../Interfaces/IReflectionOperations.cs | 2 ++ .../Interfaces/ISettingsProvider.cs | 2 ++ .../Interfaces/ITestDeployment.cs | 2 ++ .../Interfaces/ITestSource.cs | 2 ++ .../Interfaces/ITestSourceHost.cs | 2 ++ .../Interfaces/IThreadOperations.cs | 2 ++ .../Interfaces/ITraceListener.cs | 2 ++ .../Interfaces/ITraceListenerManager.cs | 2 ++ .../RecursiveDirectoryPath.cs | 2 ++ .../Services/FileOperations.cs | 2 ++ .../Services/MSTestAdapterSettings.cs | 2 ++ .../Services/ReflectionOperations.cs | 2 ++ .../Services/SettingsProvider.cs | 2 ++ .../Services/TestContextImplementation.cs | 2 ++ .../Services/TestDataSource.cs | 2 ++ .../Services/TestDeployment.cs | 2 ++ .../Services/TestSource.cs | 2 ++ .../Services/TestSourceHost.cs | 2 ++ .../Services/ThreadOperations.cs | 2 ++ .../Services/ThreadSafeStringWriter.cs | 2 ++ .../Services/TraceListener.cs | 2 ++ .../Services/TraceListenerManager.cs | 2 ++ .../Services/TraceLogger.cs | 2 ++ .../Utilities/VSInstallationUtilities.cs | 2 ++ .../Services/MSTestAdapterSettingsTests.cs | 20 +++++++++---------- 43 files changed, 94 insertions(+), 10 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs b/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs index 41df65ebee..b574bd1f15 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs @@ -14,11 +14,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// Listens for log messages and Debug.WriteLine /// Note that this class is not thread-safe and thus should only be used when unit tests are being run serially. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class LogMessageListener : IDisposable { private static readonly Lock TraceLock = new(); diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs index c89657609d..2af076c1a9 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs @@ -18,11 +18,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// Defines TestAssembly Info object. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TestAssemblyInfo { private readonly Lock _assemblyInfoExecuteSyncObject = new(); diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index fe29c5998e..7fb4dd3131 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -20,11 +20,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// Defines the TestClassInfo object. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TestClassInfo { private readonly Lock _testClassExecuteSyncObject = new(); diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs index b8af1f04b5..e05a6e1b02 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs @@ -19,11 +19,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// Class responsible for execution of tests at assembly level and sending tests via framework handle. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TestExecutionManager { /// diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs index b6d05a1b25..259903d3d4 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs @@ -21,11 +21,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// /// Defines the TestMethod Info object. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TestMethodInfo : ITestMethod { /// diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs index fb380b6bb2..436e5791ad 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs @@ -8,11 +8,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// /// Cancellation token supporting cancellation of a test run. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TestRunCancellationToken { /// diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs index 0e05bd2bb0..947f9b77a7 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs @@ -7,11 +7,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public static class UnitTestOutcomeExtensions { /// diff --git a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs index 2574a2b81d..1870ce1d62 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs +++ b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs @@ -20,11 +20,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// Adapter Settings for the run. /// [Serializable] +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class MSTestSettings { /// diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs index e245e2bc3c..e24df2d56c 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs @@ -16,11 +16,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; /// /// TestMethod contains information about a unit test method that needs to be executed. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif [Serializable] public sealed class TestMethod : ITestMethod { diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestOutcome.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestOutcome.cs index a519c454eb..8aff354865 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestOutcome.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestOutcome.cs @@ -6,11 +6,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; /// /// Outcome of a test. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public enum UnitTestOutcome : int { /// diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs index 38975edd70..57f2ec8e28 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs @@ -14,11 +14,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; [Serializable] [DebuggerDisplay("{DisplayName} ({Outcome})")] +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class UnitTestResult { /// diff --git a/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs b/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs index 2f6613ffe4..d7009797eb 100644 --- a/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs +++ b/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs @@ -13,11 +13,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class RunConfigurationSettings { /// diff --git a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs index 3f3a15d2fb..c61b73aaa3 100644 --- a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs +++ b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs @@ -16,11 +16,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; [FileExtension(".appx")] [FileExtension(".dll")] [FileExtension(".exe")] +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class MSTestDiscoverer : ITestDiscoverer { /// diff --git a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs index ecdf3e498a..51f8df0a8b 100644 --- a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs +++ b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs @@ -15,11 +15,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// Contains the execution logic for this adapter. /// [ExtensionUri(Constants.ExecutorUriString)] +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class MSTestExecutor : ITestExecutor { private readonly CancellationToken _cancellationToken; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs index ba2917c1eb..6e09cd6020 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs @@ -21,11 +21,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// Since we don't want to put our assemblies to GAC and they are not in tests dir, we use custom way to resolve them. /// #if NETFRAMEWORK +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public #else internal sealed diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs index 217bc8b6b6..db0a583a89 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs @@ -12,11 +12,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Dep /// /// The test run directories. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif [Serializable] public class TestRunDirectories { diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IAdapterTraceLogger.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IAdapterTraceLogger.cs index 14d14d6337..85dff3e128 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IAdapterTraceLogger.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IAdapterTraceLogger.cs @@ -8,11 +8,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// A service to log any trace messages from the adapter that would be shown in *.TpTrace files. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public interface IAdapterTraceLogger { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs index 3ae7c05162..220384a574 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs @@ -8,11 +8,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// This service is responsible for any file based operations. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public interface IFileOperations { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs index 29a90e3033..6d45ad9137 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs @@ -9,11 +9,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// This service is responsible for platform specific reflection operations. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public interface IReflectionOperations { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs index e0939a3976..84d99b8c11 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs @@ -8,11 +8,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// To read settings from the runsettings xml for the corresponding platform service. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public interface ISettingsProvider { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs index aeeee1826a..a8cd1766ef 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs @@ -11,11 +11,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// The TestDeployment interface. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public interface ITestDeployment { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs index 3bd96ce786..ee1321c162 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs @@ -9,11 +9,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// This platform service is responsible for any data or operations to validate /// the test sources provided to the adapter. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public interface ITestSource { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs index 5f4f73b8bf..9d2f93a7b5 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs @@ -8,11 +8,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// A host that loads the test source.This can be in isolation for desktop using an AppDomain or just loading the source in the current context. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public interface ITestSourceHost : IDisposable { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IThreadOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IThreadOperations.cs index f03762ff1d..8655d44b27 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IThreadOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IThreadOperations.cs @@ -6,11 +6,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// This service is responsible for any thread operations specific to a platform. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public interface IThreadOperations { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListener.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListener.cs index 6bc98aaec5..3356a46238 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListener.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListener.cs @@ -6,11 +6,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// /// Operations on the TraceListener object that is implemented differently for each platform. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public interface ITraceListener { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListenerManager.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListenerManager.cs index 9dbe78d52e..cc0779a5f9 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListenerManager.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITraceListenerManager.cs @@ -7,11 +7,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Int /// Manager to perform operations on the TraceListener object passed as parameter. /// These operations are implemented differently for each platform service. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public interface ITraceListenerManager { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs b/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs index 7aaea3d496..93f712ca1c 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs @@ -20,11 +20,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// For each directory we need to have two info 1) path 2) includeSubDirectories. /// [Serializable] +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1603:DocumentationMustContainValidXml", Justification = "Reviewed. Suppression is ok here.")] public class RecursiveDirectoryPath : MarshalByRefObject { diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs index 04475207db..6a257ae966 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs @@ -18,11 +18,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// The file operations. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class FileOperations : IFileOperations { private readonly ConcurrentDictionary _assemblyCache = new(); diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs index 0949dec0f6..59ac48a834 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs @@ -12,11 +12,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class MSTestAdapterSettings { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs index 8663ff8570..f927fd9137 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs @@ -17,11 +17,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// This service is responsible for platform specific reflection operations. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class ReflectionOperations : IReflectionOperations { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs index baf259c3dc..618229553b 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs @@ -14,11 +14,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// Class to read settings from the runsettings xml for the desktop. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class MSTestSettingsProvider : ISettingsProvider { #if !WINDOWS_UWP diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs index 2a2823bd5e..5685895cd2 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs @@ -20,11 +20,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// The virtual string properties of the TestContext are retrieved from the property dictionary /// like GetProperty<string>("TestName") or GetProperty<string>("FullyQualifiedTestClassName"). /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TestContextImplementation : TestContext, ITestContext { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs index 24dbc96867..06ecd53fbe 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs @@ -26,11 +26,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// the tests since it can only be found at the test output directory. DO NOT call into this platform service outside of the appdomain context if you do not want to hit /// a ReflectionTypeLoadException. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TestDataSource : ITestDataSource { #if NETFRAMEWORK diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs index c8fc00c01a..142cbe85d6 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs @@ -25,11 +25,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// The test deployment. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TestDeployment : ITestDeployment { #if !WINDOWS_UWP diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs index 13d03b2955..07421a54a6 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs @@ -17,11 +17,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// This platform service is responsible for any data or operations to validate /// the test sources provided to the adapter. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TestSource : ITestSource { #if WINDOWS_UWP || WIN_UI diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs index 25e8a8e3ce..3947aae28b 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs @@ -23,11 +23,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// A host that loads the test source. This can be in isolation for desktop using an AppDomain or just loading the source in the current context. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TestSourceHost : ITestSourceHost { #if !WINDOWS_UWP diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs index c67aa5a18e..156a2e7efb 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs @@ -12,11 +12,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// This service is responsible for any Async operations specific to a platform. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class ThreadOperations : IThreadOperations { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs index 9d3efef984..af48e6c7ae 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs @@ -8,11 +8,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// AsyncContext aware, thread safe string writer that allows output writes from different threads to end up in the same async local context. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class ThreadSafeStringWriter : StringWriter { #if DEBUG diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs index d63c8e0363..25196e6784 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs @@ -16,11 +16,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// The virtual operations of the TraceListener are implemented here /// like Close(), Dispose() etc. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TraceListenerWrapper : #if !WINDOWS_UWP && !WIN_UI TextWriterTraceListener, diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs index 4c06279271..7aa3dcbd53 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs @@ -13,11 +13,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// Internal implementation of TraceListenerManager exposed to the user. /// Responsible for performing Add(), Remove(), Close(), Dispose() operations on traceListener object. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class TraceListenerManager : ITraceListenerManager { #if !WINDOWS_UWP && !WIN_UI diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceLogger.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceLogger.cs index 44baf76b71..60234199e6 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceLogger.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceLogger.cs @@ -9,11 +9,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// /// A service to log any trace messages from the adapter that would be shown in *.TpTrace files. /// +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public class AdapterTraceLogger : IAdapterTraceLogger { /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs index d2ea62d3d0..0a16f5e3f4 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs @@ -10,11 +10,13 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; +#if RELEASE #if NET6_0_OR_GREATER [Obsolete(Constants.PublicTypeObsoleteMessage, DiagnosticId = "MSTESTOBS")] #else [Obsolete(Constants.PublicTypeObsoleteMessage)] #endif +#endif public static class VSInstallationUtilities { /// diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs index 2d8df6545a..787e96b51a 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs @@ -318,16 +318,16 @@ public void ToSettings_ShouldInitializeDeploymentAndAssemblyResolutionSettingsCo { // Arrange var configDictionary = new Dictionary - { - { "mstest:deployment:enabled", "true" }, - { "mstest:deployment:deployTestSourceDependencies", "true" }, - { "mstest:deployment:deleteDeploymentDirectoryAfterTestRunIsComplete", "false" }, - { "mstest:assemblyResolution:0:path", "C:\\project\\dependencies" }, - { "mstest:assemblyResolution:0:includeSubDirectories", "true" }, - { "mstest:assemblyResolution:1:path", "C:\\project\\libs" }, - { "mstest:assemblyResolution:1:includeSubDirectories", "false" }, - { "mstest:assemblyResolution:2:path", "C:\\project\\plugins" }, - }; + { + { "mstest:deployment:enabled", "true" }, + { "mstest:deployment:deployTestSourceDependencies", "true" }, + { "mstest:deployment:deleteDeploymentDirectoryAfterTestRunIsComplete", "false" }, + { "mstest:assemblyResolution:0:path", "C:\\project\\dependencies" }, + { "mstest:assemblyResolution:0:includeSubDirectories", "true" }, + { "mstest:assemblyResolution:1:path", "C:\\project\\libs" }, + { "mstest:assemblyResolution:1:includeSubDirectories", "false" }, + { "mstest:assemblyResolution:2:path", "C:\\project\\plugins" }, + }; var mockConfig = new Mock(); mockConfig.Setup(config => config[It.IsAny()]) From b10bda33dc1682c4d6c8be903cdd9d2f52407564 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sat, 14 Dec 2024 20:35:31 +0100 Subject: [PATCH 117/273] Introduce Assert.Throws(Async) and Assert.ThrowsExactly(Async) APIs (#4350) --- .../Assertions/Assert.ThrowsException.cs | 163 ++++++++++++++++-- .../PublicAPI/PublicAPI.Unshipped.txt | 4 + .../AssertTests.ThrowsExceptionTests.cs | 54 +++++- 3 files changed, 200 insertions(+), 21 deletions(-) diff --git a/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs b/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs index 9d88e3dc0a..39658439f9 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs @@ -1,8 +1,9 @@ // 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.Diagnostics.CodeAnalysis; +using System.ComponentModel; using System.Globalization; +using System.Runtime.CompilerServices; namespace Microsoft.VisualStudio.TestTools.UnitTesting; @@ -13,6 +14,60 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// public sealed partial class Assert { + /// + /// Asserts that the delegate throws an exception of type + /// (or derived type) and throws AssertFailedException if code does not throws exception or throws + /// exception of type other than . + /// + /// + /// Delegate to code to be tested and which is expected to throw exception. + /// + /// + /// The message to include in the exception when does not throws exception of type . + /// + /// + /// An array of parameters to use when formatting . + /// + /// + /// The type of exception expected to be thrown. + /// + /// + /// Thrown if does not throws exception of type . + /// + /// + /// The exception that was thrown. + /// + public static TException Throws(Action action, string message = "", params object[] messageArgs) + where TException : Exception + => ThrowsException(action, isStrictType: false, message, parameters: messageArgs); + + /// + /// Asserts that the delegate throws an exception of type + /// (and not of derived type) and throws AssertFailedException if code does not throws exception or throws + /// exception of type other than . + /// + /// + /// Delegate to code to be tested and which is expected to throw exception. + /// + /// + /// The message to include in the exception when does not throws exception of type . + /// + /// + /// An array of parameters to use when formatting . + /// + /// + /// The type of exception expected to be thrown. + /// + /// + /// Thrown if does not throws exception of type . + /// + /// + /// The exception that was thrown. + /// + public static TException ThrowsExactly(Action action, string message = "", params object[] messageArgs) + where TException : Exception + => ThrowsException(action, isStrictType: true, message, parameters: messageArgs); + /// /// Tests whether the code specified by delegate throws exact given exception /// of type (and not of derived type) and throws AssertFailedException @@ -22,7 +77,7 @@ public sealed partial class Assert /// Delegate to code to be tested and which is expected to throw exception. /// /// - /// Type of exception expected to be thrown. + /// The exact type of exception expected to be thrown. /// /// /// Thrown if does not throws exception of type . @@ -30,6 +85,7 @@ public sealed partial class Assert /// /// The exception that was thrown. /// + [EditorBrowsable(EditorBrowsableState.Never)] public static T ThrowsException(Action action) where T : Exception => ThrowsException(action, string.Empty, null); @@ -55,6 +111,7 @@ public static T ThrowsException(Action action) /// /// The exception that was thrown. /// + [EditorBrowsable(EditorBrowsableState.Never)] public static T ThrowsException(Action action, string message) where T : Exception => ThrowsException(action, message, null); @@ -76,6 +133,7 @@ public static T ThrowsException(Action action, string message) /// /// The exception that was thrown. /// + [EditorBrowsable(EditorBrowsableState.Never)] public static T ThrowsException(Func action) where T : Exception => ThrowsException(action, string.Empty, null); @@ -101,6 +159,7 @@ public static T ThrowsException(Func action) /// /// The exception that was thrown. /// + [EditorBrowsable(EditorBrowsableState.Never)] public static T ThrowsException(Func action, string message) where T : Exception => ThrowsException(action, message, null); @@ -129,6 +188,7 @@ public static T ThrowsException(Func action, string message) /// /// The exception that was thrown. /// + [EditorBrowsable(EditorBrowsableState.Never)] public static T ThrowsException(Func action, string message, params object?[]? parameters) where T : Exception #pragma warning disable IDE0053 // Use expression body for lambda expression @@ -160,9 +220,13 @@ public static T ThrowsException(Func action, string message, params /// /// The exception that was thrown. /// - [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and format appropriately.")] + [EditorBrowsable(EditorBrowsableState.Never)] public static T ThrowsException(Action action, string message, params object?[]? parameters) where T : Exception + => ThrowsException(action, isStrictType: true, message, parameters: parameters); + + private static TException ThrowsException(Action action, bool isStrictType, string message, [CallerMemberName] string assertMethodName = "", params object?[]? parameters) + where TException : Exception { Guard.NotNull(action); Guard.NotNull(message); @@ -174,19 +238,22 @@ public static T ThrowsException(Action action, string message, params object? } catch (Exception ex) { - if (!typeof(T).Equals(ex.GetType())) + bool isExceptionOfType = isStrictType + ? typeof(TException) == ex.GetType() + : ex is TException; + if (!isExceptionOfType) { userMessage = BuildUserMessage(message, parameters); finalMessage = string.Format( CultureInfo.CurrentCulture, FrameworkMessages.WrongExceptionThrown, userMessage, - typeof(T), + typeof(TException), ex.GetType()); - ThrowAssertFailed("Assert.ThrowsException", finalMessage); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); } - return (T)ex; + return (TException)ex; } userMessage = BuildUserMessage(message, parameters); @@ -194,13 +261,67 @@ public static T ThrowsException(Action action, string message, params object? CultureInfo.CurrentCulture, FrameworkMessages.NoExceptionThrown, userMessage, - typeof(T)); - ThrowAssertFailed("Assert.ThrowsException", finalMessage); + typeof(TException)); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); // This will not hit, but need it for compiler. return null; } + /// + /// Asserts that the delegate throws an exception of type + /// (or derived type) and throws AssertFailedException if code does not throws exception or throws + /// exception of type other than . + /// + /// + /// Delegate to code to be tested and which is expected to throw exception. + /// + /// + /// The message to include in the exception when does not throws exception of type . + /// + /// + /// An array of parameters to use when formatting . + /// + /// + /// The type of exception expected to be thrown. + /// + /// + /// Thrown if does not throws exception of type . + /// + /// + /// The exception that was thrown. + /// + public static Task ThrowsAsync(Func action, string message = "", params object[] messageArgs) + where TException : Exception + => ThrowsExceptionAsync(action, isStrictType: false, message, parameters: messageArgs); + + /// + /// Asserts that the delegate throws an exception of type + /// (and not of derived type) and throws AssertFailedException if code does not throws exception or throws + /// exception of type other than . + /// + /// + /// Delegate to code to be tested and which is expected to throw exception. + /// + /// + /// The message to include in the exception when does not throws exception of type . + /// + /// + /// An array of parameters to use when formatting . + /// + /// + /// The type of exception expected to be thrown. + /// + /// + /// Thrown if does not throws exception of type . + /// + /// + /// The exception that was thrown. + /// + public static Task ThrowsExactlyAsync(Func action, string message = "", params object[] messageArgs) + where TException : Exception + => ThrowsExceptionAsync(action, isStrictType: true, message, parameters: messageArgs); + /// /// Tests whether the code specified by delegate throws exact given exception /// of type (and not of derived type) and throws AssertFailedException @@ -218,6 +339,7 @@ public static T ThrowsException(Action action, string message, params object? /// /// The executing the delegate. /// + [EditorBrowsable(EditorBrowsableState.Never)] public static async Task ThrowsExceptionAsync(Func action) where T : Exception => await ThrowsExceptionAsync(action, string.Empty, null) @@ -240,6 +362,7 @@ public static async Task ThrowsExceptionAsync(Func action) /// /// The executing the delegate. /// + [EditorBrowsable(EditorBrowsableState.Never)] public static async Task ThrowsExceptionAsync(Func action, string message) where T : Exception => await ThrowsExceptionAsync(action, message, null) @@ -265,8 +388,14 @@ public static async Task ThrowsExceptionAsync(Func action, string me /// /// The executing the delegate. /// + [EditorBrowsable(EditorBrowsableState.Never)] public static async Task ThrowsExceptionAsync(Func action, string message, params object?[]? parameters) where T : Exception + => await ThrowsExceptionAsync(action, true, message, parameters: parameters) + .ConfigureAwait(false); + + private static async Task ThrowsExceptionAsync(Func action, bool isStrictType, string message, [CallerMemberName] string assertMethodName = "", params object?[]? parameters) + where TException : Exception { Guard.NotNull(action); Guard.NotNull(message); @@ -278,19 +407,23 @@ public static async Task ThrowsExceptionAsync(Func action, string me } catch (Exception ex) { - if (!typeof(T).Equals(ex.GetType())) + bool isExceptionOfType = isStrictType + ? typeof(TException) == ex.GetType() + : ex is TException; + + if (!isExceptionOfType) { userMessage = BuildUserMessage(message, parameters); finalMessage = string.Format( CultureInfo.CurrentCulture, FrameworkMessages.WrongExceptionThrown, userMessage, - typeof(T), + typeof(TException), ex.GetType()); - ThrowAssertFailed("Assert.ThrowsException", finalMessage); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); } - return (T)ex; + return (TException)ex; } userMessage = BuildUserMessage(message, parameters); @@ -298,8 +431,8 @@ public static async Task ThrowsExceptionAsync(Func action, string me CultureInfo.CurrentCulture, FrameworkMessages.NoExceptionThrown, userMessage, - typeof(T)); - ThrowAssertFailed("Assert.ThrowsException", finalMessage); + typeof(TException)); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); // This will not hit, but need it for compiler. return null!; diff --git a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt index 7dc5c58110..7c1390e0bf 100644 --- a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt @@ -1 +1,5 @@ #nullable enable +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Throws(System.Action! action, string! message = "", params object![]! messageArgs) -> TException! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsAsync(System.Func! action, string! message = "", params object![]! messageArgs) -> System.Threading.Tasks.Task! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactly(System.Action! action, string! message = "", params object![]! messageArgs) -> TException! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactlyAsync(System.Func! action, string! message = "", params object![]! messageArgs) -> System.Threading.Tasks.Task! diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs index 459c84c165..74aa52e347 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs @@ -72,7 +72,7 @@ public void ThrowsExceptionAsyncShouldThrowAssertionOnNoException() Verify(innerException is not null); Verify(typeof(AssertFailedException) == innerException.GetType()); - Verify(innerException.Message.Equals("Assert.ThrowsException failed. Expected exception type: but no exception was thrown. ", StringComparison.Ordinal)); + Verify(innerException.Message.Equals("Assert.ThrowsExceptionAsync failed. Expected exception type: but no exception was thrown. ", StringComparison.Ordinal)); } public void ThrowsExceptionAsyncShouldThrowAssertionOnWrongException() @@ -89,7 +89,7 @@ public void ThrowsExceptionAsyncShouldThrowAssertionOnWrongException() Verify(innerException is not null); Assert.AreEqual(typeof(AssertFailedException), innerException.GetType()); - Verify(innerException.Message.Equals("Assert.ThrowsException failed. Expected exception type:. Actual exception type:. ", StringComparison.Ordinal)); + Verify(innerException.Message.Equals("Assert.ThrowsExceptionAsync failed. Expected exception type:. Actual exception type:. ", StringComparison.Ordinal)); } public void ThrowsExceptionAsyncWithMessageShouldThrowAssertionOnNoException() @@ -103,7 +103,7 @@ public void ThrowsExceptionAsyncWithMessageShouldThrowAssertionOnNoException() Verify(innerException is not null); Assert.AreEqual(typeof(AssertFailedException), innerException.GetType()); - Verify(innerException.Message.Equals("Assert.ThrowsException failed. Expected exception type: but no exception was thrown. The world is not on fire.", StringComparison.Ordinal)); + Verify(innerException.Message.Equals("Assert.ThrowsExceptionAsync failed. Expected exception type: but no exception was thrown. The world is not on fire.", StringComparison.Ordinal)); } public void ThrowsExceptionAsyncWithMessageShouldThrowAssertionOnWrongException() @@ -121,7 +121,7 @@ public void ThrowsExceptionAsyncWithMessageShouldThrowAssertionOnWrongException( Verify(innerException is not null); Assert.AreEqual(typeof(AssertFailedException), innerException.GetType()); - Verify(innerException.Message.Equals("Assert.ThrowsException failed. Expected exception type:. Actual exception type:. Happily ever after.", StringComparison.Ordinal)); + Verify(innerException.Message.Equals("Assert.ThrowsExceptionAsync failed. Expected exception type:. Actual exception type:. Happily ever after.", StringComparison.Ordinal)); } public void ThrowsExceptionAsyncWithMessageAndParamsShouldThrowOnNullAction() @@ -170,7 +170,7 @@ public void ThrowsExceptionAsyncWithMessageAndParamsShouldThrowAssertionOnNoExce Verify(innerException is not null); Assert.AreEqual(typeof(AssertFailedException), innerException.GetType()); - Verify(innerException.Message.Equals("Assert.ThrowsException failed. Expected exception type: but no exception was thrown. The world is not on fire ta.da-123.", StringComparison.Ordinal)); + Verify(innerException.Message.Equals("Assert.ThrowsExceptionAsync failed. Expected exception type: but no exception was thrown. The world is not on fire ta.da-123.", StringComparison.Ordinal)); } public void ThrowsExceptionAsyncWithMessageAndParamsShouldThrowAssertionOnWrongException() @@ -190,7 +190,49 @@ public void ThrowsExceptionAsyncWithMessageAndParamsShouldThrowAssertionOnWrongE Verify(innerException is not null); Assert.AreEqual(typeof(AssertFailedException), innerException.GetType()); - Verify(innerException.Message.Equals("Assert.ThrowsException failed. Expected exception type:. Actual exception type:. Happily ever after. The End.", StringComparison.Ordinal)); + Verify(innerException.Message.Equals("Assert.ThrowsExceptionAsync failed. Expected exception type:. Actual exception type:. Happily ever after. The End.", StringComparison.Ordinal)); } #endregion + + public void Throws_WhenExceptionIsDerivedFromExpectedType_ShouldNotThrow() + => Assert.Throws(() => throw new ArgumentNullException()); + + public void Throws_WhenExceptionIsNotExpectedType_ShouldThrow() + { + static void Action() => Assert.Throws(() => throw new Exception()); + Exception ex = VerifyThrows(Action); + Verify(ex is AssertFailedException); + } + + public void ThrowsExactly_WhenExceptionIsDerivedFromExpectedType_ShouldThrow() + { + static void Action() => Assert.ThrowsExactly(() => throw new ArgumentNullException()); + Exception ex = VerifyThrows(Action); + Verify(ex is AssertFailedException); + } + + public void ThrowsExactly_WhenExceptionExpectedType_ShouldNotThrow() + => Assert.ThrowsExactly(() => throw new ArgumentNullException()); + + public async Task ThrowsAsync_WhenExceptionIsDerivedFromExpectedType_ShouldNotThrow() + => await Assert.ThrowsAsync(() => throw new ArgumentNullException()); + + public void ThrowsAsync_WhenExceptionIsNotExpectedType_ShouldThrow() + { + Task t = Assert.ThrowsAsync(() => throw new Exception()); + Exception ex = VerifyThrows(t.Wait); + Assert.IsInstanceOfType(ex.InnerException, out AssertFailedException assertFailedException); + Assert.AreEqual("Assert.ThrowsAsync failed. Expected exception type:. Actual exception type:. ", assertFailedException.Message); + } + + public void ThrowsExactlyAsync_WhenExceptionIsDerivedFromExpectedType_ShouldThrow() + { + Task t = Assert.ThrowsExactlyAsync(() => throw new ArgumentNullException()); + Exception ex = VerifyThrows(t.Wait); + Assert.IsInstanceOfType(ex.InnerException, out AssertFailedException assertFailedException); + Assert.AreEqual("Assert.ThrowsExactlyAsync failed. Expected exception type:. Actual exception type:. ", assertFailedException.Message); + } + + public async Task ThrowsExactlyAsync_WhenExceptionExpectedType_ShouldNotThrow() + => await Assert.ThrowsExactlyAsync(() => throw new ArgumentNullException()); } From d6d6bbe9601c173a5a7dcd39c68ac46b2f2c22fa Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 16 Dec 2024 15:17:43 +0100 Subject: [PATCH 118/273] Throw exception if ExpectedExceptionBaseAttribute is applied more than once (#4358) --- .../Helpers/ReflectHelper.cs | 22 ++++++-- .../Helpers/ReflectHelperTests.cs | 51 +++++++++++++++++++ 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index 4f5abb5076..e4f3968e35 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -104,11 +104,11 @@ public virtual bool IsNonDerivedAttributeDefined(MemberInfo memberIn { DebugEx.Assert(methodInfo != null, "MethodInfo should be non-null"); - // Get the expected exception attribute - ExpectedExceptionBaseAttribute? expectedException; + IEnumerable expectedExceptions; + try { - expectedException = GetFirstDerivedAttributeOrDefault(methodInfo, inherit: true); + expectedExceptions = GetDerivedAttributes(methodInfo, inherit: true); } catch (Exception ex) { @@ -123,7 +123,21 @@ public virtual bool IsNonDerivedAttributeDefined(MemberInfo memberIn throw new TypeInspectionException(errorMessage); } - return expectedException ?? null; + // Verify that there is only one attribute (multiple attributes derived from + // ExpectedExceptionBaseAttribute are not allowed on a test method) + // This is needed EVEN IF the attribute doesn't allow multiple. + // See https://github.com/microsoft/testfx/issues/4331 + if (expectedExceptions.Count() > 1) + { + string errorMessage = string.Format( + CultureInfo.CurrentCulture, + Resource.UTA_MultipleExpectedExceptionsOnTestMethod, + testMethod.FullClassName, + testMethod.Name); + throw new TypeInspectionException(errorMessage); + } + + return expectedExceptions.FirstOrDefault(); } /// diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs index 37d3610eac..9f22447a8c 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs @@ -5,6 +5,7 @@ using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; +using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.TestableImplementations; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -284,6 +285,30 @@ public void GettingAttributesShouldNotReturnInheritedAttributesWhenAskingForNonI Verify(nonInheritedAttributes.Length == 1); } + public void ResolveExpectedExceptionShouldThrowWhenAttributeIsDefinedTwice_DifferentConcreteType() + { + MethodInfo testMethodInfo = typeof(DummyTestClass).GetMethod(nameof(DummyTestClass.DummyTestMethod1)); + + // Don't mock. Use the real ReflectionOperations2. + _testablePlatformServiceProvider.MockReflectionOperations = null; + + TypeInspectionException ex = Assert.ThrowsException( + () => ReflectHelper.Instance.ResolveExpectedExceptionHelper(testMethodInfo, new("DummyName", "DummyFullClassName", "DummyAssemblyName", isAsync: false))); + Assert.AreEqual("The test method DummyFullClassName.DummyName has multiple attributes derived from ExpectedExceptionBaseAttribute defined on it. Only one such attribute is allowed.", ex.Message); + } + + public void ResolveExpectedExceptionShouldThrowWhenAttributeIsDefinedTwice_SameConcreteType() + { + MethodInfo testMethodInfo = typeof(DummyTestClass).GetMethod(nameof(DummyTestClass.DummyTestMethod2)); + + // Don't mock. Use the real ReflectionOperations2. + _testablePlatformServiceProvider.MockReflectionOperations = null; + + TypeInspectionException ex = Assert.ThrowsException( + () => ReflectHelper.Instance.ResolveExpectedExceptionHelper(testMethodInfo, new("DummyName", "DummyFullClassName", "DummyAssemblyName", isAsync: false))); + Assert.AreEqual("The test method DummyFullClassName.DummyName has multiple attributes derived from ExpectedExceptionBaseAttribute defined on it. Only one such attribute is allowed.", ex.Message); + } + internal class AttributeMockingHelper { public AttributeMockingHelper(Mock mockReflectionOperations) => _mockReflectionOperations = mockReflectionOperations; @@ -338,4 +363,30 @@ public object[] GetCustomAttributesNotCached(ICustomAttributeProvider attributeP public class TestableExtendedTestMethod : TestMethodAttribute; +public class DummyTestClass +{ + private class MyExpectedException1Attribute : ExpectedExceptionBaseAttribute + { + protected internal override void Verify(Exception exception) => throw new NotImplementedException(); + } + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + public class MyExpectedException2Attribute : ExpectedExceptionBaseAttribute + { + protected internal override void Verify(Exception exception) => throw new NotImplementedException(); + } + + [ExpectedException(typeof(Exception))] + [MyExpectedException1] + + public void DummyTestMethod1() + { + } + + [MyExpectedException2] + [MyExpectedException2] + public void DummyTestMethod2() + { + } +} #endregion From 170ca023b919e63fb01c5962d1b72d7a4bae2459 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 16 Dec 2024 15:20:12 +0100 Subject: [PATCH 119/273] Support generic test method (#4204) --- .../Discovery/TestMethodValidator.cs | 12 +- .../Extensions/MethodInfoExtensions.cs | 97 ++++++++++- .../Resources/Resource.Designer.cs | 36 +++-- .../Resources/Resource.resx | 12 +- .../Resources/xlf/Resource.cs.xlf | 20 ++- .../Resources/xlf/Resource.de.xlf | 20 ++- .../Resources/xlf/Resource.es.xlf | 20 ++- .../Resources/xlf/Resource.fr.xlf | 20 ++- .../Resources/xlf/Resource.it.xlf | 20 ++- .../Resources/xlf/Resource.ja.xlf | 20 ++- .../Resources/xlf/Resource.ko.xlf | 20 ++- .../Resources/xlf/Resource.pl.xlf | 20 ++- .../Resources/xlf/Resource.pt-BR.xlf | 20 ++- .../Resources/xlf/Resource.ru.xlf | 20 ++- .../Resources/xlf/Resource.tr.xlf | 20 ++- .../Resources/xlf/Resource.zh-Hans.xlf | 20 ++- .../Resources/xlf/Resource.zh-Hant.xlf | 20 ++- .../DataRowShouldBeValidAnalyzer.cs | 106 ++++++++++++- .../MSTest.Analyzers/Resources.Designer.cs | 22 ++- src/Analyzers/MSTest.Analyzers/Resources.resx | 10 +- .../TestMethodShouldBeValidAnalyzer.cs | 14 +- .../MSTest.Analyzers/xlf/Resources.cs.xlf | 14 +- .../MSTest.Analyzers/xlf/Resources.de.xlf | 14 +- .../MSTest.Analyzers/xlf/Resources.es.xlf | 14 +- .../MSTest.Analyzers/xlf/Resources.fr.xlf | 14 +- .../MSTest.Analyzers/xlf/Resources.it.xlf | 14 +- .../MSTest.Analyzers/xlf/Resources.ja.xlf | 14 +- .../MSTest.Analyzers/xlf/Resources.ko.xlf | 14 +- .../MSTest.Analyzers/xlf/Resources.pl.xlf | 14 +- .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 14 +- .../MSTest.Analyzers/xlf/Resources.ru.xlf | 14 +- .../MSTest.Analyzers/xlf/Resources.tr.xlf | 14 +- .../xlf/Resources.zh-Hans.xlf | 14 +- .../xlf/Resources.zh-Hant.xlf | 14 +- .../Internal/ReflectionTestMethodInfo.cs | 12 ++ .../GenericTestMethodTests.cs | 150 ++++++++++++++++++ .../Helpers/AcceptanceAssert.cs | 10 +- .../DataRowShouldBeValidAnalyzerTests.cs | 66 ++++++++ .../TestMethodShouldBeValidAnalyzerTests.cs | 12 ++ .../Discovery/TestMethodValidatorTests.cs | 14 +- 40 files changed, 879 insertions(+), 136 deletions(-) create mode 100644 test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs index 811868b2fc..005a6f2262 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs @@ -62,22 +62,12 @@ internal virtual bool IsValidTestMethod(MethodInfo testMethodInfo, Type type, IC return false; } - // Generic method Definitions are not valid. - if (testMethodInfo.IsGenericMethodDefinition) - { - string message = string.Format(CultureInfo.CurrentCulture, Resource.UTA_ErrorGenericTestMethod, testMethodInfo.DeclaringType!.FullName, testMethodInfo.Name); - warnings.Add(message); - return false; - } - bool isAccessible = testMethodInfo.IsPublic || (_discoverInternals && testMethodInfo.IsAssembly); // Todo: Decide whether parameter count matters. - // The isGenericMethod check below id to verify that there are no closed generic methods slipping through. - // Closed generic methods being GenericMethod and open being GenericMethod. bool isValidTestMethod = isAccessible && - testMethodInfo is { IsAbstract: false, IsStatic: false, IsGenericMethod: false } && + testMethodInfo is { IsAbstract: false, IsStatic: false } && testMethodInfo.IsValidReturnType(); if (!isValidTestMethod) diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs index 8263640283..e3efef79a4 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs @@ -7,6 +7,7 @@ using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; @@ -74,7 +75,7 @@ internal static bool HasCorrectTestMethodSignature(this MethodInfo method, bool DebugEx.Assert(method != null, "method should not be null."); return - method is { IsAbstract: false, IsStatic: false, IsGenericMethod: false } && + method is { IsAbstract: false, IsStatic: false } && (method.IsPublic || (discoverInternals && method.IsAssembly)) && (method.GetParameters().Length == 0 || ignoreParameterLength) && method.IsValidReturnType(); // Match return type Task for async methods only. Else return type void. @@ -160,6 +161,11 @@ internal static void InvokeAsSynchronousTask(this MethodInfo methodInfo, object? try { + if (methodInfo.IsGenericMethod) + { + methodInfo = ConstructGenericMethod(methodInfo, arguments); + } + invokeResult = methodInfo.Invoke(classInstance, arguments); } catch (Exception ex) when (ex is TargetParameterCountException or ArgumentException) @@ -188,4 +194,93 @@ internal static void InvokeAsSynchronousTask(this MethodInfo methodInfo, object? valueTask.GetAwaiter().GetResult(); } } + + // Scenarios to test: + // + // [DataRow(null, "Hello")] + // [DataRow("Hello", null)] + // public void TestMethod(T t1, T t2) { } + // + // [DataRow(0, "Hello")] + // public void TestMethod(T2 p0, T1, p1) { } + private static MethodInfo ConstructGenericMethod(MethodInfo methodInfo, object?[]? arguments) + { + DebugEx.Assert(methodInfo.IsGenericMethod, "ConstructGenericMethod should only be called for a generic method."); + + if (arguments is null) + { + // An example where this could happen is: + // [TestMethod] + // public void MyTestMethod() { } + throw new TestFailedException(ObjectModel.UnitTestOutcome.Error, string.Format(CultureInfo.InvariantCulture, Resource.GenericParameterCantBeInferredBecauseNoArguments, methodInfo.Name)); + } + + Type[] genericDefinitions = methodInfo.GetGenericArguments(); + var map = new (Type GenericDefinition, Type? Substitution)[genericDefinitions.Length]; + for (int i = 0; i < map.Length; i++) + { + map[i] = (genericDefinitions[i], null); + } + + ParameterInfo[] parameters = methodInfo.GetParameters(); + for (int i = 0; i < parameters.Length; i++) + { + Type parameterType = parameters[i].ParameterType; + if (!parameterType.IsGenericMethodParameter() || arguments[i] is null) + { + continue; + } + + Type substitution = arguments[i]!/*Very strange nullability warning*/.GetType(); + int mapIndexForParameter = GetMapIndexForParameterType(parameterType, map); + Type? existingSubstitution = map[mapIndexForParameter].Substitution; + + if (existingSubstitution is null || substitution.IsAssignableFrom(existingSubstitution)) + { + map[mapIndexForParameter] = (parameterType, substitution); + } + else if (existingSubstitution.IsAssignableFrom(substitution)) + { + // Do nothing. We already have a good existing substitution. + } + else + { + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resource.GenericParameterConflict, parameterType.Name, existingSubstitution, substitution)); + } + } + + for (int i = 0; i < map.Length; i++) + { + // TODO: Better to throw? or tolerate and transform to typeof(object)? + // This is reachable in the following case for example: + // [DataRow(null)] + // public void TestMethod(T t) { } + Type substitution = map[i].Substitution ?? throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resource.GenericParameterCantBeInferred, map[i].GenericDefinition.Name)); + genericDefinitions[i] = substitution; + } + + try + { + return methodInfo.MakeGenericMethod(genericDefinitions); + } + catch (Exception e) + { + // The caller catches ArgumentExceptions and will lose the original exception details. + // We transform the exception to TestFailedException here to preserve its details. + throw new TestFailedException(ObjectModel.UnitTestOutcome.Error, e.TryGetMessage(), e.TryGetStackTraceInformation(), e); + } + } + + private static int GetMapIndexForParameterType(Type parameterType, (Type GenericDefinition, Type? Substitution)[] map) + { + for (int i = 0; i < map.Length; i++) + { + if (parameterType == map[i].GenericDefinition) + { + return i; + } + } + + throw ApplicationStateGuard.Unreachable(); + } } diff --git a/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs b/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs index a9c8d5711a..d486407837 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs +++ b/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs @@ -314,6 +314,33 @@ internal static string FailedToGetCustomAttribute { } } + /// + /// Looks up a localized string similar to The type of the generic parameter '{0}' could not be inferred.. + /// + internal static string GenericParameterCantBeInferred { + get { + return ResourceManager.GetString("GenericParameterCantBeInferred", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred.. + /// + internal static string GenericParameterCantBeInferredBecauseNoArguments { + get { + return ResourceManager.GetString("GenericParameterCantBeInferredBecauseNoArguments", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'.. + /// + internal static string GenericParameterConflict { + get { + return ResourceManager.GetString("GenericParameterConflict", resourceCulture); + } + } + /// /// Looks up a localized string similar to Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}.. /// @@ -603,15 +630,6 @@ internal static string UTA_EndOfInnerExceptionTrace { } } - /// - /// Looks up a localized string similar to UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature. - /// - internal static string UTA_ErrorGenericTestMethod { - get { - return ResourceManager.GetString("UTA_ErrorGenericTestMethod", resourceCulture); - } - } - /// /// Looks up a localized string similar to UTA007: Method {1} defined in class {0} does not have correct signature. Test method marked with the [TestMethod] attribute must be non-static, public, return-type as void and should not take any parameter. Example: public void Test.Class1.Test(). Additionally, if you are using async-await in test method then return-type must be 'Task' or 'ValueTask'. Example: public async Task Test.Class1.Test2(). /// diff --git a/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx b/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx index 6cdf766482..0521e091cd 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx +++ b/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx @@ -175,9 +175,6 @@ Unable to load types from the test source '{0}'. Some or all of the tests in this source may not be discovered. Error: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - File does not exist: {0} @@ -417,4 +414,13 @@ but received {4} argument(s), with types '{5}'. Both '.runsettings' and '.testconfig.json' files have been detected. Please select only one of these test configuration files. + + The type of the generic parameter '{0}' could not be inferred. + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf index 4ffa3138ca..4b5f4877b9 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf @@ -71,6 +71,21 @@ byl však přijat tento počet argumentů: {4} s typy {5}. Test {0} překročil časový limit spuštění. + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. Neplatná hodnota {0} pro položku runsettings {1}. Nastavení bude ignorováno. @@ -203,11 +218,6 @@ Error: {1} Chyba: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: Obecná metoda nemůže být testovací metodou. {0}.{1} má neplatný podpis. - - File does not exist: {0} Neexistující soubor: {0} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf index 43c7aec3be..a69a0d6c25 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf @@ -71,6 +71,21 @@ aber empfing {4} Argument(e) mit den Typen „{5}“. Der Test "{0}" hat das Ausführungstimeout überschritten. + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. Ungültiger Wert "{0}" für runsettings-Eintrag "{1}". Die Einstellung wird ignoriert. @@ -203,11 +218,6 @@ Error: {1} Fehler: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: Eine generische Methode kann keine Testmethode sein. '{0}.{1}' weist eine ungültige Signatur auf. - - File does not exist: {0} Die Datei ist nicht vorhanden: {0} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf index 31d9b13040..6c16560a28 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf @@ -71,6 +71,21 @@ pero recibió {4} argumento(s), con los tipos "{5}". La prueba '{0}' superó el tiempo de espera de ejecución. + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. Valor ''{0}'' no válido para la entrada runsettings ''{1}'', se omitirá la configuración. @@ -203,11 +218,6 @@ Error: {1} Error: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: Un método genérico no puede ser un método de prueba. {0}.{1} tiene una firma no válida - - File does not exist: {0} El archivo no existe: {0} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf index d6ea39b5be..5d160ebd04 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf @@ -71,6 +71,21 @@ mais a reçu {4} argument(s), avec les types « {5} ». Le test '{0}' a dépassé le délai d'attente de l'exécution. + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. Valeur non valide '{0}' pour l’entrée runsettings '{1}', le paramètre sera ignoré. @@ -203,11 +218,6 @@ Error: {1} Erreur : {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015 : une méthode générique ne peut pas être une méthode de test. {0}.{1} a une signature non valide - - File does not exist: {0} Fichier inexistant : {0} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf index f46eb424a9..926c193cc1 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf @@ -71,6 +71,21 @@ ma ha ricevuto {4} argomenti, con tipi "{5}". È stato superato il periodo di timeout per l'esecuzione del test '{0}'. + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. Valore non valido '{0}' per la voce runsettings '{1}'. L'impostazione verrà ignorata. @@ -203,11 +218,6 @@ Error: {1} Errore: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: un metodo generico non può essere un metodo di test. La firma di {0}.{1} non è valida - - File does not exist: {0} Il file {0} non esiste diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf index fcf792a564..fcdaef3740 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf @@ -72,6 +72,21 @@ but received {4} argument(s), with types '{5}'. テスト '{0}' は実行タイムアウトを超えました。 + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. runsettings エントリ '{1}' の値 '{0}' は無効です。設定は無視されます。 @@ -204,11 +219,6 @@ Error: {1} エラー: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: ジェネリック メソッドがテスト メソッドになることはできません。{0}.{1} のシグネチャは無効です - - File does not exist: {0} ファイルが存在しません: {0} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf index 47f6282d7a..1801e92413 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf @@ -71,6 +71,21 @@ but received {4} argument(s), with types '{5}'. '{0}' 테스트가 실행 시간 제한을 초과했습니다. + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. runsettings 항목 '{1}'에 대해 '{0}' 값이 잘못되었습니다. 설정은 무시됩니다. @@ -203,11 +218,6 @@ Error: {1} 오류: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: 제네릭 메서드는 테스트 메서드일 수 없습니다. {0}.{1}에 잘못된 서명이 있습니다. - - File does not exist: {0} 파일이 없습니다. {0} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf index 8acb03e878..2c998a9401 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf @@ -71,6 +71,21 @@ ale liczba odebranych argumentów to {4} z typami „{5}”. Test „{0}” przekroczył okres limitu czasu na wykonanie. + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. Nieprawidłowa wartość „{0}” dla wpisu runsettings „{1}”. Ustawienie zostanie zignorowane. @@ -203,11 +218,6 @@ Error: {1} Błąd: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: Metoda ogólna nie może być metodą testową. {0}{1} ma nieprawidłową sygnaturę - - File does not exist: {0} Plik nie istnieje: {0} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf index 50f9d4c703..5fd1e38263 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf @@ -71,6 +71,21 @@ mas {4} argumentos recebidos, com tipos '{5}'. Teste '{0}' ultrapassou o período de tempo limite de execução. + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. Valor inválido "{0}" para a entrada runsettings "{1}", a configuração será ignorada. @@ -203,11 +218,6 @@ Error: {1} Erro: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: um método genérico não pode ser um método de teste. {0}.{1} tem assinatura inválida - - File does not exist: {0} O arquivo não existe: {0} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf index 21c0cf85e8..81e3cdea13 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf @@ -71,6 +71,21 @@ but received {4} argument(s), with types '{5}'. Превышено время ожидания выполнения теста "{0}". + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. Недопустимое значение "{0}" для записи runsettings "{1}", параметр будет пропущен. @@ -203,11 +218,6 @@ Error: {1} Ошибка: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: универсальный метод не может быть методом теста. {0}.{1} имеет недопустимую сигнатуру - - File does not exist: {0} Файл не существует: {0} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf index d7ab817338..5b134802e5 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf @@ -71,6 +71,21 @@ ancak, '{5}' türüyle {4} argüman aldı. '{0}' testi yürütme zaman aşımı süresini aştı. + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. '{1}' çalıştırma ayarları girişi için '{0}' değeri geçersiz, ayar yoksayılacak. @@ -203,11 +218,6 @@ Error: {1} Hata: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: Genel metot bir test metodu olamaz. {0}.{1} geçersiz imzaya sahip - - File does not exist: {0} Dosya yok: {0} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf index 8ee17e2acf..f6fe41a75b 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf @@ -71,6 +71,21 @@ but received {4} argument(s), with types '{5}'. 测试“{0}”的执行超时。 + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. runsettings 项“{0}”的值“{1}”无效,将忽略设置。 @@ -203,11 +218,6 @@ Error: {1} 错误: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: 泛型方法不可为测试方法。{0}.{1} 具有无效签名 - - File does not exist: {0} 文件不存在: {0} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf index 661dc53fc6..de4b58baf4 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf @@ -71,6 +71,21 @@ but received {4} argument(s), with types '{5}'. 測試 '{0}' 超過執行逾時期限。 + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + + + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. runsettings 項目 '{1}' 的值 '{0}' 無效,將忽略設定。 @@ -203,11 +218,6 @@ Error: {1} 錯誤: {1} - - UTA015: A generic method cannot be a test method. {0}.{1} has invalid signature - UTA015: 泛型方法不可為測試方法。{0}.{1} 具有無效的簽章 - - File does not exist: {0} 檔案不存在: {0} diff --git a/src/Analyzers/MSTest.Analyzers/DataRowShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/DataRowShouldBeValidAnalyzer.cs index 3c63f35202..5c537e169f 100644 --- a/src/Analyzers/MSTest.Analyzers/DataRowShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/DataRowShouldBeValidAnalyzer.cs @@ -37,8 +37,19 @@ public sealed class DataRowShouldBeValidAnalyzer : DiagnosticAnalyzer internal static readonly DiagnosticDescriptor ArgumentTypeMismatchRule = DataRowOnTestMethodRule .WithMessage(new(nameof(Resources.DataRowShouldBeValidMessageFormat_ArgumentTypeMismatch), Resources.ResourceManager, typeof(Resources))); + internal static readonly DiagnosticDescriptor GenericTypeArgumentNotResolvedRule = DataRowOnTestMethodRule + .WithMessage(new(nameof(Resources.DataRowShouldBeValidMessageFormat_GenericTypeArgumentNotResolved), Resources.ResourceManager, typeof(Resources))); + + internal static readonly DiagnosticDescriptor GenericTypeArgumentConflictingTypesRule = DataRowOnTestMethodRule + .WithMessage(new(nameof(Resources.DataRowShouldBeValidMessageFormat_GenericTypeArgumentConflictingTypes), Resources.ResourceManager, typeof(Resources))); + public override ImmutableArray SupportedDiagnostics { get; } - = ImmutableArray.Create(DataRowOnTestMethodRule); + = ImmutableArray.Create( + DataRowOnTestMethodRule, + ArgumentCountMismatchRule, + ArgumentTypeMismatchRule, + GenericTypeArgumentNotResolvedRule, + GenericTypeArgumentConflictingTypesRule); public override void Initialize(AnalysisContext context) { @@ -168,6 +179,8 @@ private static void AnalyzeAttribute(SymbolAnalysisContext context, AttributeDat return; } + AnalyzeGenericMethod(context, dataRowSyntax, methodSymbol, constructorArguments); + // Check constructor argument types match method parameter types. List<(int ConstructorArgumentIndex, int MethodParameterIndex)> typeMismatchIndices = new(); for (int currentArgumentIndex = 0; currentArgumentIndex < constructorArguments.Length; currentArgumentIndex++) @@ -179,7 +192,13 @@ private static void AnalyzeAttribute(SymbolAnalysisContext context, AttributeDat } ITypeSymbol? argumentType = constructorArguments[currentArgumentIndex].Type; - ITypeSymbol paramType = GetParameterType(methodSymbol, currentArgumentIndex, constructorArguments.Length); + ITypeSymbol paramType = GetParameterType(methodSymbol.Parameters, currentArgumentIndex, constructorArguments.Length); + if (paramType.TypeKind == TypeKind.TypeParameter) + { + // That means the actual type cannot be determined. We should have issued a separate + // diagnostic for that in GetParameterTypeSubstitutions call above. + continue; + } if (argumentType is not null && !argumentType.IsAssignableTo(paramType, context.Compilation)) { @@ -196,11 +215,84 @@ private static void AnalyzeAttribute(SymbolAnalysisContext context, AttributeDat } } - private static ITypeSymbol GetParameterType(IMethodSymbol methodSymbol, int currentArgumentIndex, int argumentsCount) + private static void AnalyzeGenericMethod( + SymbolAnalysisContext context, + SyntaxNode dataRowSyntax, + IMethodSymbol methodSymbol, + ImmutableArray constructorArguments) + { + if (!methodSymbol.IsGenericMethod) + { + return; + } + + var parameterTypesSubstitutions = new Dictionary(SymbolEqualityComparer.Default); + foreach (IParameterSymbol parameter in methodSymbol.Parameters) + { + ITypeSymbol parameterType = parameter.Type; + if (parameterType.Kind != SymbolKind.TypeParameter) + { + continue; + } + + TypedConstant constructorArgument = constructorArguments[parameter.Ordinal]; + if (constructorArgument.Type is null) + { + // That's an error scenario. The compiler will be complaining about something already. + continue; + } + + // This happens for [DataRow(null)] which ends up being resolved + // to DataRow(string?[]? stringArrayData) constructor. + // It also happens with [DataRow((object[]?)null)] which resolves + // to the params object[] constructor + // In this case, the argument is simply "null". + if (constructorArgument.Kind == TypedConstantKind.Array && constructorArgument.IsNull) + { + continue; + } + + object? argumentValue = constructorArgument.Value; + if (argumentValue is null) + { + continue; + } + + if (parameterTypesSubstitutions.TryGetValue(parameterType, out (ITypeSymbol Symbol, Type SystemType) existingType)) + { + if (argumentValue.GetType().IsAssignableTo(existingType.SystemType)) + { + continue; + } + else if (existingType.SystemType.IsAssignableTo(argumentValue.GetType())) + { + parameterTypesSubstitutions[parameterType] = (parameterType, argumentValue.GetType()); + } + else + { + context.ReportDiagnostic(dataRowSyntax.CreateDiagnostic(GenericTypeArgumentConflictingTypesRule, parameterType.Name, existingType.Symbol.Name, constructorArgument.Type.Name)); + } + } + else + { + parameterTypesSubstitutions.Add(parameterType, (constructorArgument.Type, argumentValue.GetType())); + } + } + + foreach (ITypeParameterSymbol typeParameter in methodSymbol.TypeParameters) + { + if (!parameterTypesSubstitutions.ContainsKey(typeParameter)) + { + context.ReportDiagnostic(dataRowSyntax.CreateDiagnostic(GenericTypeArgumentNotResolvedRule, typeParameter.Name)); + } + } + } + + private static ITypeSymbol GetParameterType(ImmutableArray parameters, int currentArgumentIndex, int argumentsCount) { - if (currentArgumentIndex >= methodSymbol.Parameters.Length - 1) + if (currentArgumentIndex >= parameters.Length - 1) { - IParameterSymbol lastParameter = methodSymbol.Parameters[^1]; + IParameterSymbol lastParameter = parameters[^1]; // When last parameter is params, we want to check that the extra arguments match the type of the array if (lastParameter.IsParams) @@ -209,13 +301,13 @@ private static ITypeSymbol GetParameterType(IMethodSymbol methodSymbol, int curr } // When only parameter is array and we have more than one argument, we want to check the array type - if (argumentsCount > 1 && methodSymbol.Parameters.Length == 1 && lastParameter.Type.Kind == SymbolKind.ArrayType) + if (argumentsCount > 1 && parameters.Length == 1 && lastParameter.Type.Kind == SymbolKind.ArrayType) { return ((IArrayTypeSymbol)lastParameter.Type).ElementType; } } - return methodSymbol.Parameters[currentArgumentIndex].Type; + return parameters[currentArgumentIndex].Type; } private static bool IsArgumentCountMismatch(int constructorArgumentsLength, ImmutableArray methodParameters) diff --git a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs index f41b3eb2a8..c79c68d575 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs @@ -311,6 +311,24 @@ internal static string DataRowShouldBeValidMessageFormat_ArgumentTypeMismatch { } } + /// + /// Looks up a localized string similar to Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'.. + /// + internal static string DataRowShouldBeValidMessageFormat_GenericTypeArgumentConflictingTypes { + get { + return ResourceManager.GetString("DataRowShouldBeValidMessageFormat_GenericTypeArgumentConflictingTypes", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to The type of the generic parameter '{0}' could not be inferred.. + /// + internal static string DataRowShouldBeValidMessageFormat_GenericTypeArgumentNotResolved { + get { + return ResourceManager.GetString("DataRowShouldBeValidMessageFormat_GenericTypeArgumentNotResolved", resourceCulture); + } + } + /// /// Looks up a localized string similar to DataRow should only be set on a test method. /// @@ -852,11 +870,11 @@ internal static string TestInitializeShouldBeValidTitle { /// Looks up a localized string similar to Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: ///- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) ///- it should not be 'static' - ///- it should not be generic + ///- it should may be generic as long as type parameters can be inferred and argument types are compatible ///- it should not be 'abstract' ///- return type should be 'void', 'Task' or 'ValueTask' ///- it should not be 'async void' - ///- it should not be a special method (finalizer, operator...).. + ///- it should not be a special me [rest of string was truncated]";. /// internal static string TestMethodShouldBeValidDescription { get { diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx index c85ca03484..ca9399fdab 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.resx +++ b/src/Analyzers/MSTest.Analyzers/Resources.resx @@ -399,7 +399,7 @@ The type declaring these methods should also respect the following rules: Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' @@ -534,4 +534,10 @@ The type declaring these methods should also respect the following rules: Use 'Assert.{0}' instead of 'Assert.{1}' - \ No newline at end of file + + The type of the generic parameter '{0}' could not be inferred. + + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + diff --git a/src/Analyzers/MSTest.Analyzers/TestMethodShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/TestMethodShouldBeValidAnalyzer.cs index b99c64fe1b..7cc5fd1691 100644 --- a/src/Analyzers/MSTest.Analyzers/TestMethodShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/TestMethodShouldBeValidAnalyzer.cs @@ -69,7 +69,19 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo return; } - if (methodSymbol.IsGenericMethod || methodSymbol.IsStatic || methodSymbol.IsAbstract || methodSymbol is { ReturnsVoid: true, IsAsync: true } + if (methodSymbol.IsGenericMethod) + { + foreach (ITypeParameterSymbol typeParameter in methodSymbol.TypeParameters) + { + // If none of the parameters match the type parameter, then that generic type can't be inferred. + if (!methodSymbol.Parameters.Any(p => typeParameter.Equals(p.Type, SymbolEqualityComparer.Default))) + { + context.ReportDiagnostic(methodSymbol.CreateDiagnostic(ValidTestMethodSignatureRule, methodSymbol.Name)); + } + } + } + + if (methodSymbol.IsStatic || methodSymbol.IsAbstract || methodSymbol is { ReturnsVoid: true, IsAsync: true } || (!methodSymbol.ReturnsVoid && (taskSymbol is null || !SymbolEqualityComparer.Default.Equals(methodSymbol.ReturnType, taskSymbol)) && (valueTaskSymbol is null || !SymbolEqualityComparer.Default.Equals(methodSymbol.ReturnType, valueTaskSymbol)))) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index 5b591476a2..f5c97b3aaf 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -251,6 +251,16 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: Typ argumentu DataRow by měl odpovídat typu parametru metody. V indexech dochází k neshodě: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method Objekt DataRow by měl být nastaven pouze pro testovací metodu @@ -629,12 +639,12 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Testovací metody (metody označené atributem [TestMethod]) by měly respektovat následující rozložení, které MSTest považuje za platné: + Testovací metody (metody označené atributem [TestMethod]) by měly respektovat následující rozložení, které MSTest považuje za platné: – musí být public (nebo internal, pokud je nastaven atribut [assembly: DiscoverInternals]), – musí být static, – nesmí být obecné, diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 2ece3c50f7..b4e69b06f3 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -253,6 +253,16 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte Der DataRow-Argumenttyp muss mit dem Methodenparametertyp übereinstimmen. Nichtübereinstimmungen treten bei Indizes auf: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method DataRow darf nur für eine Testmethode festgelegt werden. @@ -631,12 +641,12 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Testmethoden, Methoden, die mit dem Attribut „[TestMethod]“ gekennzeichnet sind, sollten das folgende Layout berücksichtigen, um von MSTest als gültig angesehen zu werden: + Testmethoden, Methoden, die mit dem Attribut „[TestMethod]“ gekennzeichnet sind, sollten das folgende Layout berücksichtigen, um von MSTest als gültig angesehen zu werden: – es darf „public“ (oder „internal“ sein, wenn das Attribut „[assembly: DiscoverInternals]“ festgelegt ist) – es darf nicht „static“ sein – es darf nicht generisch sein diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index c88d16d554..c00af72a2c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -251,6 +251,16 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: El tipo de argumento DataRow debe coincidir con el tipo de parámetro de método. Se producen errores de coincidencia en los índices: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method DataRow solo debe establecerse en un método de prueba @@ -629,12 +639,12 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Los métodos de prueba, los métodos marcados con el atributo '[TestMethod]', deben respetar el siguiente diseño para que MSTest lo considere válido: + Los métodos de prueba, los métodos marcados con el atributo '[TestMethod]', deben respetar el siguiente diseño para que MSTest lo considere válido: - debe ser 'public' (o 'internal' si se establece el atributo '[assembly: DiscoverInternals]') - no debe ser 'static' - no debe ser genérico diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index ceb154ccab..a6c2eda34f 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -251,6 +251,16 @@ Le type doit être une classe Le type d’argument DataRow doit correspondre au type de paramètre de la méthode. Des incompatibilités se produisent aux index :{0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method DataRow ne doit être défini que sur une méthode de test @@ -629,12 +639,12 @@ Le type doit être une classe Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Les méthodes de test, qui sont des méthodes marquées avec l’attribut « [TestMethod] », doivent respecter la disposition suivante pour être considérées comme valides par MSTest : + Les méthodes de test, qui sont des méthodes marquées avec l’attribut « [TestMethod] », doivent respecter la disposition suivante pour être considérées comme valides par MSTest : – il doit être « public » (ou « interne » si l’attribut « [assembly : DiscoverInternals] » est défini) – le texte ne doit pas être « statique » – il ne doit pas être générique diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index d6b5460f74..7272d2c87e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -251,6 +251,16 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: Il tipo di argomento di DataRow deve corrispondere al tipo di parametro del metodo. Errori di corrispondenza in corrispondenza degli indici: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method DataRow deve essere impostato solo su un metodo di test @@ -629,12 +639,12 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - I metodi di test, metodi contrassegnati con l'attributo '[TestMethod]', dovrebbero rispettare il layout seguente per essere considerati validi da MSTest: + I metodi di test, metodi contrassegnati con l'attributo '[TestMethod]', dovrebbero rispettare il layout seguente per essere considerati validi da MSTest: - dovrebbe essere 'pubblico' (o 'interno' se l'attributo '[assembly: DiscoverInternals]' è impostato) - non dovrebbe essere 'statico' - non dovrebbe essere generico diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index c1d6a50590..187661886c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -251,6 +251,16 @@ The type declaring these methods should also respect the following rules: DataRow 引数の型は、メソッド パラメーターの型と一致させる必要があります。インデックスで不一致が発生しました: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method DataRow はテスト メソッドにのみ設定する必要があります @@ -629,12 +639,12 @@ The type declaring these methods should also respect the following rules: Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - '[TestMethod]' 属性でマークされたテスト メソッドは、MSTest によって有効と見なされるように、次のレイアウトを考慮する必要があります: + '[TestMethod]' 属性でマークされたテスト メソッドは、MSTest によって有効と見なされるように、次のレイアウトを考慮する必要があります: - 'public' である必要があります ('[assembly: DiscoverInternals]' 属性が設定されている場合は 'internal' である必要があります) - 'static' にすることはできません - ジェネリックにすることはできません diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 26033c6a6e..3cb2e0e93e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -251,6 +251,16 @@ The type declaring these methods should also respect the following rules: DataRow 인수 형식은 메서드 매개 변수 형식과 일치해야 합니다. 인덱스에서 불일치 발생: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method DataRow는 테스트 메서드에서만 설정해야 함 @@ -629,12 +639,12 @@ The type declaring these methods should also respect the following rules: Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - '[TestMethod]' 특성으로 표시된 메서드인 테스트 메서드는 MSTest에서 유효한 것으로 간주되도록 다음 레이아웃을 준수해야 합니다. + '[TestMethod]' 특성으로 표시된 메서드인 테스트 메서드는 MSTest에서 유효한 것으로 간주되도록 다음 레이아웃을 준수해야 합니다. - 'public'(혹은 '[assembly: DiscoverInternals]' 특성이 설정된 경우 'internal')이어야 합니다. - 'static'이 아니어야 합니다. - 제네릭이 아니어야 합니다. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 58ece0939a..f7a58b7b3e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -251,6 +251,16 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu Typ argumentu DataRow powinien być zgodny z typem parametru metody. W indeksach występują niezgodności: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method Element DataRow powinien być ustawiony tylko dla metody testowej @@ -629,12 +639,12 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Metody testowe, czyli metody oznaczone atrybutem „[TestMethod]”, powinny uwzględniać następujący układ, aby platforma MSTest uznała je za prawidłowe: + Metody testowe, czyli metody oznaczone atrybutem „[TestMethod]”, powinny uwzględniać następujący układ, aby platforma MSTest uznała je za prawidłowe: — powinna to być wartość „public” (lub „internal”, jeśli ustawiono atrybut „[assembly: DiscoverInternals]”) — nie powinna to być wartość „static” — nie powinna to być wartość ogólna diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 2ef8aefbc9..13f12371db 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -251,6 +251,16 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: O tipo de argumento DataRow deve corresponder ao tipo de parâmetro do método. Incompatibilidades ocorrem nos índices: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method DataRow só deve ser definido em um método de teste @@ -629,12 +639,12 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Os métodos de teste, métodos marcados com o atributo '[TestMethod]', devem respeitar o seguinte layout para que sejam considerados válidos pelo MSTest: + Os métodos de teste, métodos marcados com o atributo '[TestMethod]', devem respeitar o seguinte layout para que sejam considerados válidos pelo MSTest: - deve ser "público" (ou "interno" se o atributo "[assembly: DiscoverInternals]" estiver definido) - não pode ser ''estático'' - não pode ser genérico diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index e53eabd2a4..da5179bfe2 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -255,6 +255,16 @@ The type declaring these methods should also respect the following rules: Тип аргумента DataRow должен соответствовать типу параметра метода. Обнаружены несовпадения в следующих индексах: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method Значение DataRow следует задавать только для метода теста @@ -639,12 +649,12 @@ The type declaring these methods should also respect the following rules: Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Методы теста (методы, помеченные атрибутом "[TestMethod]") должны соблюдать следующую структуру, чтобы считаться допустимыми в MSTest: + Методы теста (методы, помеченные атрибутом "[TestMethod]") должны соблюдать следующую структуру, чтобы считаться допустимыми в MSTest: – должно быть присвоено значение "public" (или "internal", если задан атрибут "[assembly: DiscoverInternals]") – не следует присваивать значение "static" – не следует присваивать универсальное значение diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index fe3079d220..b3461aa8e9 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -251,6 +251,16 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: DataRow bağımsız değişken türü, yöntem parametresinin türüyle eşleşmelidir. Dizinler sırasında uyuşmazlıklar oluştu: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method DataRow yalnızca bir test yönteminde ayarlanmalıdır @@ -630,12 +640,12 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - '[TestMethod]' özniteliğiyle işaretlenen test yöntemleri, MSTest: + '[TestMethod]' özniteliğiyle işaretlenen test yöntemleri, MSTest: tarafından geçerli kabul edilmesi için aşağıdaki düzene göre düzenlenmelidir. - 'public' (veya '[assembly: DiscoverInternals]' özniteliği ayarlanmışsa 'internal') olmalıdır - 'static' olmamalıdır diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 8f9c7c1d0b..ac52117203 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -251,6 +251,16 @@ The type declaring these methods should also respect the following rules: DataRow 参数类型应与方法参数类型匹配。索引处出现不匹配: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method DataRow 应仅在测试方法上进行设置 @@ -629,12 +639,12 @@ The type declaring these methods should also respect the following rules: Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - 测试方法 (标记有“[TestMethod]”属性的方法) 应遵循以下布局,以供 MSTest 将其视为有效: + 测试方法 (标记有“[TestMethod]”属性的方法) 应遵循以下布局,以供 MSTest 将其视为有效: - 它应该是“public” (如果设置了“[assembly: DiscoverInternals]”属性,则应该是“internal”) - 它不应为“static” - 它不应是泛型的 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 9a4ba567c7..2025d28acb 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -251,6 +251,16 @@ The type declaring these methods should also respect the following rules: DataRow 引數類型應符合方法參數類型。索引發生不符: {0} + + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + + + The type of the generic parameter '{0}' could not be inferred. + The type of the generic parameter '{0}' could not be inferred. + + DataRow should only be set on a test method DataRow 只能在測試方法上設定 @@ -629,12 +639,12 @@ The type declaring these methods should also respect the following rules: Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: - it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) - it should not be 'static' -- it should not be generic +- it should may be generic as long as type parameters can be inferred and argument types are compatible - it should not be 'abstract' - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - 測試方法 (標示為 '[TestMethod]' 屬性的方法) 應該遵循下列配置,讓 MSTest 視為有效: + 測試方法 (標示為 '[TestMethod]' 屬性的方法) 應該遵循下列配置,讓 MSTest 視為有效: - 它應該是 'public' (如果設定 '[assembly: DiscoverInternals]' 屬性,則為 'internal') - 它應該是 'static' - 它不能是泛型 diff --git a/src/TestFramework/TestFramework/Internal/ReflectionTestMethodInfo.cs b/src/TestFramework/TestFramework/Internal/ReflectionTestMethodInfo.cs index faccb92a42..a3ce7ea801 100644 --- a/src/TestFramework/TestFramework/Internal/ReflectionTestMethodInfo.cs +++ b/src/TestFramework/TestFramework/Internal/ReflectionTestMethodInfo.cs @@ -30,6 +30,12 @@ public ReflectionTestMethodInfo(MethodInfo methodInfo, string? displayName) public override Type? ReflectedType => _methodInfo.ReflectedType; + public override bool ContainsGenericParameters => _methodInfo.ContainsGenericParameters; + + public override bool IsGenericMethod => _methodInfo.IsGenericMethod; + + public override bool IsGenericMethodDefinition => _methodInfo.IsGenericMethodDefinition; + public override MethodInfo GetBaseDefinition() => _methodInfo.GetBaseDefinition(); public override object[] GetCustomAttributes(bool inherit) => _methodInfo.GetCustomAttributes(inherit); @@ -43,4 +49,10 @@ public ReflectionTestMethodInfo(MethodInfo methodInfo, string? displayName) public override object? Invoke(object? obj, BindingFlags invokeAttr, Binder? binder, object?[]? parameters, CultureInfo? culture) => _methodInfo.Invoke(obj, invokeAttr, binder, parameters, culture); public override bool IsDefined(Type attributeType, bool inherit) => _methodInfo.IsDefined(attributeType, inherit); + + public override MethodInfo MakeGenericMethod(params Type[] typeArguments) => new ReflectionTestMethodInfo(_methodInfo.MakeGenericMethod(typeArguments), DisplayName); + + public override Type[] GetGenericArguments() => _methodInfo.GetGenericArguments(); + + public override MethodInfo GetGenericMethodDefinition() => _methodInfo.GetGenericMethodDefinition(); } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs new file mode 100644 index 0000000000..a65b1d9827 --- /dev/null +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs @@ -0,0 +1,150 @@ +// 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.Text.RegularExpressions; + +using Microsoft.Testing.Platform.Acceptance.IntegrationTests; +using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; +using Microsoft.Testing.Platform.Helpers; + +namespace MSTest.Acceptance.IntegrationTests; + +[TestGroup] +public class GenericTestMethodTests : AcceptanceTestBase +{ + private readonly TestAssetFixture _testAssetFixture; + + // There's a bug in TAFX where we need to use it at least one time somewhere to use it inside the fixture self (AcceptanceFixture). + public GenericTestMethodTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture, + AcceptanceFixture globalFixture) + : base(testExecutionContext) => _testAssetFixture = testAssetFixture; + + public async Task TestDifferentGenericMethodTestCases() + { + var testHost = TestHost.LocateFrom(_testAssetFixture.GetAssetPath("GenericTestMethodTests"), "GenericTestMethodTests", TargetFrameworks.NetCurrent.Arguments); + + TestHostResult testHostResult = await testHost.ExecuteAsync(); + + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputMatchesRegex( + """ + failed AMethodWithBadConstraints \(0\) \(\d+ms\) + GenericArguments\[0], 'System\.Int32', on 'Void AMethodWithBadConstraints\[T]\(T\)' violates the constraint of type 'T'\. + at .+? + failed NonParameterizedTestMethod \(\d+ms\) + The generic test method 'NonParameterizedTestMethod' doesn't have arguments, so the generic parameter cannot be inferred\. + failed ParameterizedMethodSimple \(1\) \(\d+ms\) + Assert\.Fail failed\. Test method 'ParameterizedMethodSimple' did run with parameter '1' and type 'System\.Byte'\. + at .+? + failed ParameterizedMethodSimple \(2\) \(\d+ms\) + Assert\.Fail failed\. Test method 'ParameterizedMethodSimple' did run with parameter '2' and type 'System\.Int32'\. + at .+? + failed ParameterizedMethodSimple \("Hello world"\) \(\d+ms\) + Assert\.Fail failed\. Test method 'ParameterizedMethodSimple' did run with parameter 'Hello world' and type 'System\.String'\. + at .+? + failed ParameterizedMethodSimple \(null\) \(\d+ms\) + Test method TestClass\.ParameterizedMethodSimple threw exception: + System\.InvalidOperationException: The type of the generic parameter 'T' could not be inferred\. + failed ParameterizedMethodTwoGenericParametersAndFourMethodParameters \(1,"Hello world",2,3\) \(\d+ms\) + Test method TestClass\.ParameterizedMethodTwoGenericParametersAndFourMethodParameters threw exception: + System\.InvalidOperationException: Found two conflicting types for generic parameter 'T2'\. The conflicting types are 'System\.Byte' and 'System\.Int32'\. + failed ParameterizedMethodTwoGenericParametersAndFourMethodParameters \(null,"Hello world","Hello again",3\) \(\d+ms\) + Assert\.Fail failed\. Test method 'ParameterizedMethodTwoGenericParametersAndFourMethodParameters' did run with parameters '', 'Hello world', 'Hello again', '3' and generic types 'System\.Int32', 'System\.String'\. + at .+? + failed ParameterizedMethodTwoGenericParametersAndFourMethodParameters \("Hello hello","Hello world",null,null\) \(\d+ms\) + Test method TestClass\.ParameterizedMethodTwoGenericParametersAndFourMethodParameters threw exception: + System\.InvalidOperationException: The type of the generic parameter 'T1' could not be inferred\. + failed ParameterizedMethodTwoGenericParametersAndFourMethodParameters \(null,null,null,null\) \(\d+ms\) + Test method TestClass\.ParameterizedMethodTwoGenericParametersAndFourMethodParameters threw exception: + System\.InvalidOperationException: The type of the generic parameter 'T1' could not be inferred\. + failed ParameterizedMethodSimpleParams \(1\) \(\d+ms\) + Cannot create an instance of T\[] because Type\.ContainsGenericParameters is true\. + at .+? + failed ParameterizedMethodSimpleParams \(1,2\) \(\d+ms\) + Cannot create an instance of T\[] because Type\.ContainsGenericParameters is true\. + at .+? + failed ParameterizedMethodSimpleParams \("Hello world"\) \(\d+ms\) + Cannot create an instance of T\[] because Type\.ContainsGenericParameters is true\. + at .+? + failed ParameterizedMethodSimpleParams \(null\) \(\d+ms\) + Cannot create an instance of T\[] because Type\.ContainsGenericParameters is true\. + at .+? + failed ParameterizedMethodSimpleParams \(null,"Hello world"\) \(\d+ms\) + Cannot create an instance of T\[] because Type\.ContainsGenericParameters is true\. + at .+? + """, RegexOptions.Singleline); + } + + [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] + public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + { + public override IEnumerable<(string ID, string Name, string Code)> GetAssetsToGenerate() + { + yield return ("GenericTestMethodTests", "GenericTestMethodTests", + SourceGenericTestMethod + .PatchTargetFrameworks(TargetFrameworks.NetCurrent) + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); + } + + private const string SourceGenericTestMethod = """ +#file GenericTestMethodTests.csproj + + + + Exe + true + $TargetFrameworks$ + + + + + + + + +#file UnitTest1.cs + +using System; +using System.Collections.Generic; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[TestClass] +public class TestClass +{ + [TestMethod] + [DataRow(0)] + public void AMethodWithBadConstraints(T p) where T : IDisposable + => Assert.Fail($"Test method 'AMethodWithBadConstraints' did run with T type being '{typeof(T)}'."); + + [TestMethod] + public void NonParameterizedTestMethod() + => Assert.Fail("Test method 'NonParameterizedTestMethod' did run."); + + [TestMethod] + [DataRow((byte)1)] + [DataRow((int)2)] + [DataRow("Hello world")] + [DataRow(null)] + public void ParameterizedMethodSimple(T parameter) + => Assert.Fail($"Test method 'ParameterizedMethodSimple' did run with parameter '{parameter?.ToString() ?? ""}' and type '{typeof(T)}'."); + + [TestMethod] + [DataRow((byte)1, "Hello world", (int)2, 3)] + [DataRow(null, "Hello world", "Hello again", 3)] + [DataRow("Hello hello", "Hello world", null, null)] + [DataRow(null, null, null, null)] + public void ParameterizedMethodTwoGenericParametersAndFourMethodParameters(T2 p1, string p2, T2 p3, T1 p4) + => Assert.Fail($"Test method 'ParameterizedMethodTwoGenericParametersAndFourMethodParameters' did run with parameters '{p1?.ToString() ?? ""}', '{p2 ?? ""}', '{p3?.ToString() ?? ""}', '{p4?.ToString() ?? ""}' and generic types '{typeof(T1)}', '{typeof(T2)}'."); + + [TestMethod] + [DataRow((byte)1)] + [DataRow((byte)1, 2)] + [DataRow("Hello world")] + [DataRow(null)] + [DataRow(null, "Hello world")] + public void ParameterizedMethodSimpleParams(params T[] parameter) + => Assert.Fail($"Test method 'ParameterizedMethodSimple' did run with parameter '{string.Join(",", parameter)}' and type '{typeof(T)}'."); +} +"""; + } +} diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs index 7cb676a209..a5ec05d244 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs @@ -1,6 +1,7 @@ // 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.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using System.Text.RegularExpressions; @@ -88,10 +89,13 @@ public static void AssertOutputMatchesRegexLines(this TestHostResult testHostRes } } - public static void AssertOutputMatchesRegex(this TestHostResult testHostResult, string pattern, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) + public static void AssertOutputMatchesRegex(this TestHostResult testHostResult, [StringSyntax("Regex")] string pattern, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) => Assert.That(Regex.IsMatch(testHostResult.StandardOutput, pattern), GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); - public static void AssertOutputDoesNotMatchRegex(this TestHostResult testHostResult, string pattern, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) + public static void AssertOutputMatchesRegex(this TestHostResult testHostResult, [StringSyntax("Regex")] string pattern, RegexOptions regexOptions, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) + => Assert.That(Regex.IsMatch(testHostResult.StandardOutput, pattern, regexOptions), GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + + public static void AssertOutputDoesNotMatchRegex(this TestHostResult testHostResult, [StringSyntax("Regex")] string pattern, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) => Assert.That(!Regex.IsMatch(testHostResult.StandardOutput, pattern), GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); public static void AssertOutputContains(this TestHostResult testHostResult, string value, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) @@ -103,7 +107,7 @@ public static void AssertOutputContains(this DotnetMuxerResult dotnetMuxerResult public static void AssertOutputNotContains(this DotnetMuxerResult dotnetMuxerResult, string value, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) => Assert.That(!dotnetMuxerResult.StandardOutput.Contains(value, StringComparison.Ordinal), GenerateFailedAssertionMessage(dotnetMuxerResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); - public static void AssertOutputRegEx(this DotnetMuxerResult dotnetMuxerResult, string pattern, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) + public static void AssertOutputRegEx(this DotnetMuxerResult dotnetMuxerResult, [StringSyntax("Regex")] string pattern, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) => Assert.That(Regex.IsMatch(dotnetMuxerResult.StandardOutput, pattern), GenerateFailedAssertionMessage(dotnetMuxerResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); public static void AssertOutputDoesNotContain(this TestHostResult testHostResult, string value, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DataRowShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DataRowShouldBeValidAnalyzerTests.cs index c273069028..c5a50491a8 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DataRowShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DataRowShouldBeValidAnalyzerTests.cs @@ -560,4 +560,70 @@ public void ItemsTest(int[] input) await VerifyCS.VerifyAnalyzerAsync(code); } + + public async Task WhenMethodIsGeneric() + { + string code = """ + using System; + using System.Collections.Generic; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [TestMethod] + [DataRow(0)] // This is an unfortunate false negative that will blow up at runtime. + public void AMethodWithBadConstraints(T p) where T : IDisposable + => Assert.Fail($"Test method 'AMethodWithBadConstraints' did run with T type being '{typeof(T)}'."); + + [TestMethod] + [DataRow((byte)1)] + [DataRow((int)2)] + [DataRow("Hello world")] + [{|#0:DataRow(null)|}] + public void ParameterizedMethodSimple(T parameter) + => Assert.Fail($"Test method 'ParameterizedMethodSimple' did run with parameter '{parameter?.ToString() ?? ""}' and type '{typeof(T)}'."); + + [TestMethod] + [{|#1:DataRow((byte)1, "Hello world", (int)2, 3)|}] + [DataRow(null, "Hello world", "Hello again", 3)] + [{|#2:DataRow("Hello hello", "Hello world", null, null)|}] + [{|#3:{|#4:DataRow(null, null, null, null)|}|}] + public void ParameterizedMethodTwoGenericParametersAndFourMethodParameters(T2 p1, string p2, T2 p3, T1 p4) + => Assert.Fail($"Test method 'ParameterizedMethodTwoGenericParametersAndFourMethodParameters' did run with parameters '{p1?.ToString() ?? ""}', '{p2 ?? ""}', '{p3?.ToString() ?? ""}', '{p4?.ToString() ?? ""}' and generic types '{typeof(T1)}', '{typeof(T2)}'."); + + [TestMethod] + [{|#5:DataRow((byte)1)|}] + [{|#6:DataRow((byte)1, 2)|}] + [{|#7:DataRow("Hello world")|}] + [{|#8:DataRow(null)|}] + [{|#9:DataRow(null, "Hello world")|}] + public void ParameterizedMethodSimpleParams(params T[] parameter) + => Assert.Fail($"Test method 'ParameterizedMethodSimple' did run with parameter '{string.Join(",", parameter)}' and type '{typeof(T)}'."); + } + """; + + await VerifyCS.VerifyAnalyzerAsync( + code, + // /0/Test0.cs(17,6): warning MSTEST0014: The type of the generic parameter 'T' could not be inferred. + VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.GenericTypeArgumentNotResolvedRule).WithLocation(0).WithArguments("T"), + // /0/Test0.cs(22,6): warning MSTEST0014: Found two conflicting types for generic parameter 'T2'. The conflicting types are 'Byte' and 'Int32'. + VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.GenericTypeArgumentConflictingTypesRule).WithLocation(1).WithArguments("T2", "Byte", "Int32"), + // /0/Test0.cs(24,6): warning MSTEST0014: The type of the generic parameter 'T1' could not be inferred. + VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.GenericTypeArgumentNotResolvedRule).WithLocation(2).WithArguments("T1"), + // /0/Test0.cs(25,6): warning MSTEST0014: The type of the generic parameter 'T1' could not be inferred. + VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.GenericTypeArgumentNotResolvedRule).WithLocation(3).WithArguments("T1"), + // /0/Test0.cs(25,6): warning MSTEST0014: The type of the generic parameter 'T2' could not be inferred. + VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.GenericTypeArgumentNotResolvedRule).WithLocation(4).WithArguments("T2"), + // /0/Test0.cs(30,6): warning MSTEST0014: The type of the generic parameter 'T' could not be inferred. + VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.GenericTypeArgumentNotResolvedRule).WithLocation(5).WithArguments("T"), + // /0/Test0.cs(31,6): warning MSTEST0014: The type of the generic parameter 'T' could not be inferred. + VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.GenericTypeArgumentNotResolvedRule).WithLocation(6).WithArguments("T"), + // /0/Test0.cs(32,6): warning MSTEST0014: The type of the generic parameter 'T' could not be inferred. + VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.GenericTypeArgumentNotResolvedRule).WithLocation(7).WithArguments("T"), + // /0/Test0.cs(33,6): warning MSTEST0014: The type of the generic parameter 'T' could not be inferred. + VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.GenericTypeArgumentNotResolvedRule).WithLocation(8).WithArguments("T"), + // /0/Test0.cs(34,6): warning MSTEST0014: The type of the generic parameter 'T' could not be inferred. + VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.GenericTypeArgumentNotResolvedRule).WithLocation(9).WithArguments("T")); + } } diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs index a6b598bec1..714c32714f 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs @@ -164,6 +164,12 @@ public class MyTestClass public void [|MyTestMethod|]() { } + + [TestMethod] + [DataRow(0)] + public void MyTestMethod(T t) + { + } } """; @@ -177,6 +183,12 @@ public class MyTestClass public void MyTestMethod() { } + + [TestMethod] + [DataRow(0)] + public void MyTestMethod(T t) + { + } } """; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TestMethodValidatorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TestMethodValidatorTests.cs index e7c3a59f05..5d0b135572 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TestMethodValidatorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TestMethodValidatorTests.cs @@ -2,10 +2,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Diagnostics.CodeAnalysis; -using System.Globalization; using System.Reflection; -using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; @@ -43,6 +41,8 @@ public void IsValidTestMethodShouldReturnFalseForMethodsWithoutATestMethodAttrib Verify(!_testMethodValidator.IsValidTestMethod(_mockMethodInfo.Object, _type, _warnings)); } + // TODO: Fix this test. It should be returning true, but we get false for a different reason (IsPublic is false) + // https://github.com/microsoft/testfx/issues/4207 public void IsValidTestMethodShouldReturnFalseForGenericTestMethodDefinitions() { SetupTestMethod(); @@ -53,18 +53,20 @@ public void IsValidTestMethodShouldReturnFalseForGenericTestMethodDefinitions() Verify(!_testMethodValidator.IsValidTestMethod(_mockMethodInfo.Object, _type, _warnings)); } - public void IsValidTestMethodShouldReportWarningsForGenericTestMethodDefinitions() + // TODO: Fix this test. It should be returning true, but we get false for a different reason (IsPublic is false) + // https://github.com/microsoft/testfx/issues/4207 + public void IsValidTestMethodShouldNotReportWarningsForGenericTestMethodDefinitions() { SetupTestMethod(); _mockMethodInfo.Setup(mi => mi.IsGenericMethodDefinition).Returns(true); _mockMethodInfo.Setup(mi => mi.DeclaringType.FullName).Returns("DummyTestClass"); _mockMethodInfo.Setup(mi => mi.Name).Returns("DummyTestMethod"); - + _mockMethodInfo.Setup(mi => mi.Attributes).Returns(MethodAttributes.Public); + _mockMethodInfo.Setup(mi => mi.ReturnType).Returns(typeof(void)); _testMethodValidator.IsValidTestMethod(_mockMethodInfo.Object, _type, _warnings); - Verify(_warnings.Count == 1); - Verify(_warnings.Contains(string.Format(CultureInfo.CurrentCulture, Resource.UTA_ErrorGenericTestMethod, "DummyTestClass", "DummyTestMethod"))); + Verify(_warnings.Count == 0); } public void IsValidTestMethodShouldReturnFalseForNonPublicMethods() From f711ef02f1addac01f9812454d26c8b6e54d4b0a Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Mon, 16 Dec 2024 06:34:48 -0800 Subject: [PATCH 120/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2602562 --- .../MSTest.Analyzers/xlf/Resources.cs.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.de.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.es.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.fr.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.it.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.ja.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.ko.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.pl.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.ru.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.tr.xlf | 17 ++++++++--------- .../MSTest.Analyzers/xlf/Resources.zh-Hans.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.zh-Hant.xlf | 16 ++++++++-------- 13 files changed, 104 insertions(+), 105 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index f5c97b3aaf..7c908215c1 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -644,14 +644,14 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Testovací metody (metody označené atributem [TestMethod]) by měly respektovat následující rozložení, které MSTest považuje za platné: -– musí být public (nebo internal, pokud je nastaven atribut [assembly: DiscoverInternals]), -– musí být static, -– nesmí být obecné, -– nesmí být abstract, -– návratový typ by měl být void, Task nebo ValueTask, -– nesmí být async void, -– nesmí být speciální metodou (finalizační metoda, operátor...). + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index b4e69b06f3..47965f258f 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -646,14 +646,14 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Testmethoden, Methoden, die mit dem Attribut „[TestMethod]“ gekennzeichnet sind, sollten das folgende Layout berücksichtigen, um von MSTest als gültig angesehen zu werden: -– es darf „public“ (oder „internal“ sein, wenn das Attribut „[assembly: DiscoverInternals]“ festgelegt ist) -– es darf nicht „static“ sein -– es darf nicht generisch sein -– es darf nicht „abstract“ sein -– der Rückgabetyp muss „void“, „Task“ oder „ValueTask“ sein -– es darf nicht „async void“ sein -– es darf keine spezielle Methode (Finalizer, Operator...) sein. + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index c00af72a2c..a20c8f195b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -644,14 +644,14 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Los métodos de prueba, los métodos marcados con el atributo '[TestMethod]', deben respetar el siguiente diseño para que MSTest lo considere válido: -- debe ser 'public' (o 'internal' si se establece el atributo '[assembly: DiscoverInternals]') -- no debe ser 'static' -- no debe ser genérico -: no debe ser 'abstract' -- el tipo de valor devuelto debe ser 'void', 'Task' o 'ValueTask' -- no debe ser 'async void' -- no debe ser un método especial (finalizador, operador...). + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index a6c2eda34f..24d8c001b9 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -644,14 +644,14 @@ Le type doit être une classe - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Les méthodes de test, qui sont des méthodes marquées avec l’attribut « [TestMethod] », doivent respecter la disposition suivante pour être considérées comme valides par MSTest : -– il doit être « public » (ou « interne » si l’attribut « [assembly : DiscoverInternals] » est défini) -– le texte ne doit pas être « statique » -– il ne doit pas être générique -– il ne doit pas être « abstract » -- doit être « void » ou renvoyer « Task » ou « ValueTask » -– il ne doit pas être « async void » -- il ne doit pas s’agir d’une méthode spéciale (finaliseur, opérateur...). + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index 7272d2c87e..2c2296c26c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -644,14 +644,14 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - I metodi di test, metodi contrassegnati con l'attributo '[TestMethod]', dovrebbero rispettare il layout seguente per essere considerati validi da MSTest: -- dovrebbe essere 'pubblico' (o 'interno' se l'attributo '[assembly: DiscoverInternals]' è impostato) -- non dovrebbe essere 'statico' -- non dovrebbe essere generico -- non dovrebbe essere 'astratto' -- il tipo restituito deve essere 'void', 'Task' o 'ValueTask' -- non dovrebbe essere 'asincrono nullo' -- non dovrebbe essere un metodo speciale (finalizzatore, operatore...). + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 187661886c..2461cd224f 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -644,14 +644,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - '[TestMethod]' 属性でマークされたテスト メソッドは、MSTest によって有効と見なされるように、次のレイアウトを考慮する必要があります: -- 'public' である必要があります ('[assembly: DiscoverInternals]' 属性が設定されている場合は 'internal' である必要があります) -- 'static' にすることはできません -- ジェネリックにすることはできません -- 'abstract' にすることはできません -- 戻り値の型は 'void'、'Task'、または 'ValueTask' である必要があります -- 'async void' にすることはできません -- 特殊なメソッド (ファイナライザー、演算子...) にすることはできません。 + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 3cb2e0e93e..05d9b5d338 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -644,14 +644,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - '[TestMethod]' 특성으로 표시된 메서드인 테스트 메서드는 MSTest에서 유효한 것으로 간주되도록 다음 레이아웃을 준수해야 합니다. -- 'public'(혹은 '[assembly: DiscoverInternals]' 특성이 설정된 경우 'internal')이어야 합니다. -- 'static'이 아니어야 합니다. -- 제네릭이 아니어야 합니다. -- 'abstract'가 아니어야 합니다. -- 반환 형식은 'void', 'Task' 또는 'ValueTask'여야 합니다. -- 'async void'가 아니어야 합니다. -- 특수 메서드(종료자, 연산자...)가 아니어야 합니다. + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index f7a58b7b3e..d2c7472faf 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -644,14 +644,14 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Metody testowe, czyli metody oznaczone atrybutem „[TestMethod]”, powinny uwzględniać następujący układ, aby platforma MSTest uznała je za prawidłowe: -— powinna to być wartość „public” (lub „internal”, jeśli ustawiono atrybut „[assembly: DiscoverInternals]”) -— nie powinna to być wartość „static” -— nie powinna to być wartość ogólna -— nie powinna to być wartość „abstract” -— zwracany typ powinien mieć wartość „void”, „Task” lub „ValueTask” -— nie powinna to być wartość „async void” -— nie powinna to być metoda specjalna (finalizator, operator...). + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 13f12371db..ac74336007 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -644,14 +644,14 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Os métodos de teste, métodos marcados com o atributo '[TestMethod]', devem respeitar o seguinte layout para que sejam considerados válidos pelo MSTest: -- deve ser "público" (ou "interno" se o atributo "[assembly: DiscoverInternals]" estiver definido) -- não pode ser ''estático'' -- não pode ser genérico -- não pode ser ''abstrato'' -- o tipo de retorno que será 'void', 'Task' ou 'ValueTask' -- não pode ser ''nulo assíncrono'' -- não deve ser um método especial (finalizador, operador...). + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index da5179bfe2..94ed043887 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -654,14 +654,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Методы теста (методы, помеченные атрибутом "[TestMethod]") должны соблюдать следующую структуру, чтобы считаться допустимыми в MSTest: -– должно быть присвоено значение "public" (или "internal", если задан атрибут "[assembly: DiscoverInternals]") -– не следует присваивать значение "static" -– не следует присваивать универсальное значение -– не следует присваивать значение "abstract" -- возвращаемый тип должен быть "void", "Task" или "ValueTask" -– не следует присваивать значение "async void" -– это должен быть специальный метод (метод завершения, оператор...). + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index b3461aa8e9..e4ab404253 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -645,15 +645,14 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - '[TestMethod]' özniteliğiyle işaretlenen test yöntemleri, MSTest: - tarafından geçerli kabul edilmesi için aşağıdaki düzene göre düzenlenmelidir. -- 'public' (veya '[assembly: DiscoverInternals]' özniteliği ayarlanmışsa 'internal') olmalıdır -- 'static' olmamalıdır -- genel olmamalıdır -- 'abstract' olmamalıdır -- dönüş türü 'void', 'Task' veya 'ValueTask' olmalıdır -- 'async void' olmamalıdır -- özel bir yöntem (sonlandırıcı, işleç...) olmamalıdır. + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index ac52117203..0a0749e344 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -644,14 +644,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - 测试方法 (标记有“[TestMethod]”属性的方法) 应遵循以下布局,以供 MSTest 将其视为有效: -- 它应该是“public” (如果设置了“[assembly: DiscoverInternals]”属性,则应该是“internal”) -- 它不应为“static” -- 它不应是泛型的 -- 它不应为“abstract” -- 返回类型应为“void”、“Task”或“ValueTask” -- 它不应为“async void” -- 它不应是特殊方法 (运算符、运算符...)。 + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 2025d28acb..ef642a95d8 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -644,14 +644,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - 測試方法 (標示為 '[TestMethod]' 屬性的方法) 應該遵循下列配置,讓 MSTest 視為有效: -- 它應該是 'public' (如果設定 '[assembly: DiscoverInternals]' 屬性,則為 'internal') -- 它應該是 'static' -- 它不能是泛型 -- 它不能是 'abstract' -- 傳回型別應為 'void'、'Task' 或 'ValueTask' -- 它不能是 'async void' -- 它不應該是特殊方法 (完成項、運算子...)。 + Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: +- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) +- it should not be 'static' +- it should may be generic as long as type parameters can be inferred and argument types are compatible +- it should not be 'abstract' +- return type should be 'void', 'Task' or 'ValueTask' +- it should not be 'async void' +- it should not be a special method (finalizer, operator...). From 4193dc995541c90d8364c72be637ab28e46f477e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 16 Dec 2024 16:40:29 +0100 Subject: [PATCH 121/273] Add support for ValueTuple for all target frameworks (#4360) --- Directory.Packages.props | 3 +- samples/Playground/DebuggerUtility.cs | 3 + samples/Playground/Playground.csproj | 4 ++ samples/Playground/Program.cs | 11 ++- samples/Playground/Tests.cs | 15 ++-- .../DynamicDataOperations.cs | 71 +++++++++++++++++-- .../MSTest.TestAdapter.csproj | 8 ++- .../MSTest.TestAdapter.nuspec | 3 + .../DynamicDataAttributeTests.cs | 33 --------- 9 files changed, 99 insertions(+), 52 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 2be713e468..6bd3d0c5d4 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -22,6 +22,7 @@ 4.3.1 4.3.1 4.5.4 + 4.5.0 1.1.3-beta1.24423.1 @@ -53,7 +54,7 @@ - + diff --git a/samples/Playground/DebuggerUtility.cs b/samples/Playground/DebuggerUtility.cs index 6b58a2a58d..55fb8c75eb 100644 --- a/samples/Playground/DebuggerUtility.cs +++ b/samples/Playground/DebuggerUtility.cs @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +#if NETCOREAPP #pragma warning disable CA1837 // Use 'Environment.ProcessId' #pragma warning disable CA1416 // Validate platform compatibility @@ -356,3 +357,5 @@ private static extern int NtQueryInformationProcess( [DllImport("ole32.dll")] private static extern int CreateBindCtx(uint reserved, out IBindCtx ppbc); } + +#endif diff --git a/samples/Playground/Playground.csproj b/samples/Playground/Playground.csproj index f60b5e923c..f83ced76c8 100644 --- a/samples/Playground/Playground.csproj +++ b/samples/Playground/Playground.csproj @@ -8,6 +8,10 @@ $(NoWarn);NETSDK1023 + + + + diff --git a/samples/Playground/Program.cs b/samples/Playground/Program.cs index dfa263bd6e..82315191c2 100644 --- a/samples/Playground/Program.cs +++ b/samples/Playground/Program.cs @@ -8,12 +8,13 @@ using Microsoft.Testing.Platform.Extensions.TestFramework; using Microsoft.Testing.Platform.Extensions.TestHostControllers; using Microsoft.Testing.Platform.Messages; +#if NETCOREAPP using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; +using MSTest.Acceptance.IntegrationTests.Messages.V100; +#endif using Microsoft.Testing.Platform.TestHost; using Microsoft.VisualStudio.TestTools.UnitTesting; -using MSTest.Acceptance.IntegrationTests.Messages.V100; - namespace Playground; public class Program @@ -25,8 +26,10 @@ public static async Task Main(string[] args) if (Environment.GetEnvironmentVariable("TESTSERVERMODE") != "1") { +#if NETCOREAPP // To attach to the children Microsoft.Testing.TestInfrastructure.DebuggerUtility.AttachCurrentProcessToParentVSProcess(); +#endif ITestApplicationBuilder testApplicationBuilder = await TestApplication.CreateBuilderAsync(args); @@ -49,6 +52,9 @@ public static async Task Main(string[] args) } else { +#if NETFRAMEWORK + throw new NotSupportedException("Server mode is not supported on .NET Framework"); +#else Environment.SetEnvironmentVariable("TESTSERVERMODE", "0"); using TestingPlatformClient client = await TestingPlatformClientFactory.StartAsServerAndConnectToTheClientAsync(Environment.ProcessPath!); @@ -67,6 +73,7 @@ public static async Task Main(string[] args) await client.ExitAsync(); return 0; +#endif } } } diff --git a/samples/Playground/Tests.cs b/samples/Playground/Tests.cs index eb480d750f..ffd007f386 100644 --- a/samples/Playground/Tests.cs +++ b/samples/Playground/Tests.cs @@ -15,13 +15,16 @@ public class TestClass public TestContext TestContext { get; set; } [TestMethod] - public void Test() => TestContext.AddResultFile(@"c:\hello2"); + [DynamicData(nameof(Data))] + public void Test3(int a, int b) + => Assert.AreNotEqual(a, b); - [TestMethod] - public void Test2() => Assert.AreEqual(1, 0, "few"); - - [TestMethod] - public void Test3() + public static IEnumerable<(int A, int B)> Data { + get + { + yield return (1, 2); + yield return (3, 4); + } } } diff --git a/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs b/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs index a666067292..10485ab7c3 100644 --- a/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs @@ -1,15 +1,15 @@ // 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.VisualStudio.TestTools.UnitTesting; - -#if NET471_OR_GREATER || NETCOREAPP using System.Collections; -using System.Runtime.CompilerServices; -#endif using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection; +#if NET471_OR_GREATER || NETCOREAPP +using System.Runtime.CompilerServices; +#endif + +using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; @@ -129,12 +129,12 @@ private static bool TryGetData(object dataSource, [NotNullWhen(true)] out IEnume return true; } -#if NETCOREAPP || NET471_OR_GREATER if (dataSource is IEnumerable enumerable) { List objects = new(); foreach (object? entry in enumerable) { +#if NET471_OR_GREATER || NETCOREAPP if (entry is not ITuple tuple || (objects.Count > 0 && objects[^1].Length != tuple.Length)) { @@ -149,14 +149,71 @@ private static bool TryGetData(object dataSource, [NotNullWhen(true)] out IEnume } objects.Add(array); +#else + Type type = entry.GetType(); + if (!IsTupleOrValueTuple(entry.GetType(), out int tupleSize) + || (objects.Count > 0 && objects[objects.Count - 1].Length != tupleSize)) + { + data = null; + return false; + } + + object[] array = new object[tupleSize]; + for (int i = 0; i < tupleSize; i++) + { + array[i] = type.GetField($"Item{i + 1}")?.GetValue(entry)!; + } + + objects.Add(array); +#endif } data = objects; return true; } -#endif data = null; return false; } + +#if !NET471_OR_GREATER && !NETCOREAPP + private static bool IsTupleOrValueTuple(Type type, out int tupleSize) + { + tupleSize = 0; + if (!type.IsGenericType) + { + return false; + } + + Type genericTypeDefinition = type.GetGenericTypeDefinition(); + + if (genericTypeDefinition == typeof(Tuple<>) || + genericTypeDefinition == typeof(Tuple<,>) || + genericTypeDefinition == typeof(Tuple<,,>) || + genericTypeDefinition == typeof(Tuple<,,,>) || + genericTypeDefinition == typeof(Tuple<,,,,>) || + genericTypeDefinition == typeof(Tuple<,,,,,>) || + genericTypeDefinition == typeof(Tuple<,,,,,,>) || + genericTypeDefinition == typeof(Tuple<,,,,,,,>)) + { + tupleSize = type.GetGenericArguments().Length; + return true; + } + + if (genericTypeDefinition == typeof(ValueTuple<>) || + genericTypeDefinition == typeof(ValueTuple<,>) || + genericTypeDefinition == typeof(ValueTuple<,,>) || + genericTypeDefinition == typeof(ValueTuple<,,,>) || + genericTypeDefinition == typeof(ValueTuple<,,,,>) || + genericTypeDefinition == typeof(ValueTuple<,,,,,>) || + genericTypeDefinition == typeof(ValueTuple<,,,,,,>) || + genericTypeDefinition == typeof(ValueTuple<,,,,,,,>)) + { + tupleSize = type.GetGenericArguments().Length; + return true; + } + + return false; + } +#endif } diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj index 61b5a1173c..0174d645d9 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj @@ -57,7 +57,8 @@ - + + @@ -81,11 +82,12 @@ - - + + + diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec index fab41babbc..549cd6e8c8 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec @@ -7,14 +7,17 @@ + + + diff --git a/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs index cad1caf3e4..866b30d657 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs @@ -240,7 +240,6 @@ public void GetDisplayNameForMultipleArraysOfArraysOfMultipleItems() Verify(displayName == "TestMethod1 ([[\"a\",\"b\",\"c\"],[\"d\",\"e\",\"f\"],[\"gh\",\"ij\",\"kl\"]],['m','n','o'],[[\"1\",\"2\",\"3\"],[\"4\",\"5\",\"6\"],[\"7\",\"8\",\"9\"]])"); } -#if NETCOREAPP public void DynamicDataSource_WithTuple_Works() { MethodInfo testMethodInfo = new TestClassTupleData().GetType().GetTypeInfo().GetDeclaredMethod(nameof(TestClassTupleData.DynamicDataTestWithTuple)); @@ -270,38 +269,6 @@ public void DynamicDataSource_WithValueTupleWithTupleSyntax_Works() dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.GetDataWithValueTupleWithTupleSyntax), typeof(TestClassTupleData), DynamicDataSourceType.Method); dynamicDataAttribute.GetData(testMethodInfo); } -#else - public void DynamicDataSource_WithTuple_Throws() - { - MethodInfo testMethodInfo = new TestClassTupleData().GetType().GetTypeInfo().GetDeclaredMethod(nameof(TestClassTupleData.DynamicDataTestWithTuple)); - var dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.DataWithTuple), typeof(TestClassTupleData), DynamicDataSourceType.Property); - - VerifyThrows(() => dynamicDataAttribute.GetData(testMethodInfo)); - - dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.GetDataWithTuple), typeof(TestClassTupleData), DynamicDataSourceType.Method); - VerifyThrows(() => dynamicDataAttribute.GetData(testMethodInfo)); - } - - public void DynamicDataSource_WithValueTuple_Throws() - { - MethodInfo testMethodInfo = new TestClassTupleData().GetType().GetTypeInfo().GetDeclaredMethod(nameof(TestClassTupleData.DynamicDataTestWithTuple)); - var dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.DataWithValueTuple), typeof(TestClassTupleData), DynamicDataSourceType.Property); - VerifyThrows(() => dynamicDataAttribute.GetData(testMethodInfo)); - - dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.GetDataWithValueTuple), typeof(TestClassTupleData), DynamicDataSourceType.Method); - VerifyThrows(() => dynamicDataAttribute.GetData(testMethodInfo)); - } - - public void DynamicDataSource_WithValueTupleWithTupleSyntax_Throws() - { - MethodInfo testMethodInfo = new TestClassTupleData().GetType().GetTypeInfo().GetDeclaredMethod(nameof(TestClassTupleData.DynamicDataTestWithTuple)); - var dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.DataWithValueTupleWithTupleSyntax), typeof(TestClassTupleData), DynamicDataSourceType.Property); - VerifyThrows(() => dynamicDataAttribute.GetData(testMethodInfo)); - - dynamicDataAttribute = new DynamicDataAttribute(nameof(TestClassTupleData.GetDataWithValueTupleWithTupleSyntax), typeof(TestClassTupleData), DynamicDataSourceType.Method); - VerifyThrows(() => dynamicDataAttribute.GetData(testMethodInfo)); - } -#endif } /// From 02b61599a2fdeb8be6fa6f503eab025977cea233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 16 Dec 2024 21:13:19 +0100 Subject: [PATCH 122/273] Don't make TestDataSourceDiscoveryOption obsolete (#4366) --- src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs | 1 - .../DataSource/TestDataSourceDiscoveryAttribute.cs | 8 +++----- .../DataSource/TestDataSourceDiscoveryOption.cs | 8 +++----- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index e4f3968e35..f321c9fb10 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -272,7 +272,6 @@ internal static TestIdGenerationStrategy GetTestIdGenerationStrategy(Assembly as /// Gets TestDataSourceDiscovery assembly level attribute. /// /// The test assembly. - [Obsolete] internal static TestDataSourceDiscoveryOption? GetTestDataSourceDiscoveryOption(Assembly assembly) => PlatformServiceProvider.Instance.ReflectionOperations.GetCustomAttributes(assembly, typeof(TestDataSourceDiscoveryAttribute)) .OfType() diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryAttribute.cs index 660735c263..6d957075d6 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryAttribute.cs @@ -1,17 +1,15 @@ // 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.ComponentModel; + namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// /// Specifies how to discover tests. /// [AttributeUsage(AttributeTargets.Assembly)] -#if NET6_0_OR_GREATER -[Obsolete("Attribute is obsolete and will be removed in v4, instead use 'TestDataSourceOptionsAttribute'.", DiagnosticId = "MSTESTOBS")] -#else -[Obsolete("Attribute is obsolete and will be removed in v4, instead use 'TestDataSourceOptionsAttribute'.")] -#endif +[EditorBrowsable(EditorBrowsableState.Never)] public class TestDataSourceDiscoveryAttribute : Attribute { /// diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryOption.cs b/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryOption.cs index 25b9c9b32e..1259baf4a7 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryOption.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/TestDataSourceDiscoveryOption.cs @@ -1,16 +1,14 @@ // 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.ComponentModel; + namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// /// The supported discovery modes for tests. /// -#if NET6_0_OR_GREATER -[Obsolete("Type is obsolete and will be removed in v4, instead use 'TestDataSourceUnfoldingStrategy'.", DiagnosticId = "MSTESTOBS")] -#else -[Obsolete("Type is obsolete and will be removed in v4, instead use 'TestDataSourceUnfoldingStrategy'.")] -#endif +[EditorBrowsable(EditorBrowsableState.Never)] public enum TestDataSourceDiscoveryOption { /// From e6030a8189170d6f34abfce517073d2d641cb5fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Mon, 16 Dec 2024 22:39:43 +0100 Subject: [PATCH 123/273] Fix analyzers version --- Directory.Packages.props | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 6bd3d0c5d4..cf6e363599 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -6,10 +6,9 @@ 8.2.2 17.11.4 - 3.11.0-beta1.24605.2 3.11.0 4.10.0 - $(MicrosoftCodeAnalysisAnalyzersVersion) + 3.11.0-beta1.24605.2 $(MicrosoftCodeAnalysisPublicApiAnalyzersVersion) 6.2.14 @@ -38,7 +37,7 @@ - + From 09af447ea58751915eccba149448cf30003432da Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 17 Dec 2024 18:54:40 +1100 Subject: [PATCH 124/273] Reduce alloc in GetStackTraceInformation (#4367) --- .../Execution/ExceptionHelper.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs b/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs index 1bf1e69189..5f2c2be59c 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs @@ -77,12 +77,14 @@ internal static class ExceptionHelper bool first = true; while (stackTraces.Count != 0) { - result.AppendFormat( - CultureInfo.CurrentCulture, - "{0} {1}{2}", - first ? string.Empty : (Resource.UTA_EndOfInnerExceptionTrace + Environment.NewLine), - stackTraces.Pop(), - Environment.NewLine); + if (!first) + { + result.AppendLine(Resource.UTA_EndOfInnerExceptionTrace); + } + + result.Append(' '); + result.AppendLine(stackTraces.Pop()); + first = false; } From e733620b4c9016ea67473b50356c635d5ea3dacc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 17 Dec 2024 12:32:57 +0100 Subject: [PATCH 125/273] Move TATF based tests to MSTest (#4348) --- Directory.Packages.props | 6 +- .../Services/TestDataSource.cs | 19 +- .../Utilities/FileUtility.cs | 6 +- .../WellKnownTypeProvider.cs | 6 +- ...rosoft.Testing.Extensions.CrashDump.csproj | 1 - ...rosoft.Testing.Extensions.TrxReport.csproj | 1 - ...oft.Testing.Extensions.VSTestBridge.csproj | 2 - .../ObjectModel/FastFilter.cs | 5 +- .../Microsoft.Testing.Platform.csproj | 2 - .../ServerMode/JsonRpc/SerializerUtilities.cs | 8 +- .../TestConfigurationSection.cs | 2 +- .../TestFramework.Extensions/PrivateObject.cs | 54 ++--- .../TestFramework.Extensions/PrivateType.cs | 18 +- .../TestFramework.Extensions/TestContext.cs | 2 +- .../Assertions/Assert.AreEqual.cs | 44 ++-- .../Assertions/Assert.IsInstanceOfType.cs | 4 +- .../Assertions/CollectionAssert.cs | 4 +- .../DataSource/DataSourceAttribute.cs | 2 +- test/.editorconfig | 7 + test/Directory.Build.targets | 15 +- .../AbortionTests.cs | 16 +- .../AssemblyResolutionTests.cs | 28 +-- .../AssemblyResolverTests.cs | 16 +- .../CancellationTests.cs | 27 +-- .../ConfigurationSettingsTests.cs | 41 ++-- .../DataSourceTests.cs | 12 +- .../DotnetTestCliTests.cs | 15 +- .../GenericTestMethodTests.cs | 17 +- .../HelpInfoTests.cs | 23 +- .../IgnoreTests.cs | 18 +- .../InitializeAndCleanupTimeoutTests.cs | 206 +++++++++------- .../MSBuildRunnerTests.cs | 36 ++- .../MSTest.Acceptance.IntegrationTests.csproj | 1 + .../MaxFailedTestsExtensionTests.cs | 16 +- .../NativeAotTests.cs | 18 +- .../ParameterizedTestTests.cs | 33 ++- .../Program.cs | 9 +- .../Properties/launchSettings.json | 2 +- .../PublishAotNonNativeTests.cs | 20 +- .../RunnerTests.cs | 53 ++--- .../RunsettingsTests.cs | 54 ++--- .../STATestClassTests.cs | 48 ++-- .../STATestMethodTests.cs | 58 ++--- .../SdkTests.cs | 155 ++++++------ .../ServerMode/ServerModeTestsBase.cs | 8 +- .../ServerModeTests.cs | 24 +- .../TestContextTests.cs | 24 +- .../TestDiscoveryTests.cs | 23 +- .../TestFilterTests.cs | 38 ++- .../TestRunParametersTests.cs | 22 +- .../ThreadContextTests.cs | 69 +++--- .../ThreadingTests.cs | 68 +++--- .../TimeoutTests.cs | 37 ++- .../ValueTaskTests.cs | 17 +- .../AbortionTests.cs | 35 ++- .../CrashDumpTests.cs | 55 ++--- .../CrashPlusHangDumpTests.cs | 37 ++- .../CustomBannerTests.cs | 46 ++-- .../DiagnosticTests.cs | 153 ++++++------ ...mentVariablesConfigurationProviderTests.cs | 30 +-- .../ExecutionTests.cs | 202 +++++++++------- .../ExitOnProcessExitTests.cs | 26 +- .../HangDumpOutputTests.cs | 34 +-- .../HangDumpTests.cs | 62 +++-- .../HelpInfoTests.cs | 210 ++++++++-------- .../Helpers/AcceptanceAssert.cs | 60 ++--- .../Helpers/AcceptanceFixture.cs | 13 +- .../Helpers/AcceptanceTestBase.cs | 74 +++--- .../IgnoreExitCodeTests.cs | 35 ++- .../MSBuild.KnownExtensionRegistration.cs | 29 +-- .../MSBuildTests.ConfigurationFile.cs | 83 ++++--- .../MSBuildTests.GenerateEntryPoint.cs | 89 ++++--- .../MSBuildTests.Solution.cs | 114 +++++---- .../MSBuildTests.Test.cs | 225 ++++++++++-------- .../MaxFailedTestsExtensionTests.cs | 30 +-- ...latform.Acceptance.IntegrationTests.csproj | 14 +- .../NoBannerTests.cs | 44 ++-- .../Program.cs | 8 +- .../Properties/launchSettings.json | 2 +- .../ServerLoggingTests.cs | 49 ++-- .../TelemetryTests.cs | 52 ++-- .../TestHostProcessLifetimeHandlerTests.cs | 36 ++- .../TimeoutTests.cs | 115 +++++---- .../TrxTests.cs | 170 +++++++------ .../UnhandledExceptionPolicyTests.cs | 49 ++-- .../MSTest.Performance.Runner/Program.cs | 5 + ...semblyCleanupShouldBeValidAnalyzerTests.cs | 27 ++- ...blyInitializeShouldBeValidAnalyzerTests.cs | 27 ++- ...ouldAvoidConditionalAccessAnalyzerTests.cs | 9 +- ...ouldBePassedInCorrectOrderAnalyzerTests.cs | 10 +- ...ExpectedExceptionAttributeAnalyzerTests.cs | 13 +- .../ClassCleanupShouldBeValidAnalyzerTests.cs | 38 ++- ...assInitializeShouldBeValidAnalyzerTests.cs | 38 ++- .../DataRowShouldBeValidAnalyzerTests.cs | 30 ++- ...oNotNegateBooleanAssertionAnalyzerTests.cs | 6 +- ...oNotStoreStaticTestContextAnalyzerTests.cs | 6 +- .../DoNotUseShadowingAnalyzerTests.cs | 22 +- ...SystemDescriptionAttributeAnalyzerTests.cs | 7 +- .../DynamicDataShouldBeValidAnalyzerTests.cs | 20 +- .../MSTest.Analyzers.UnitTests.csproj | 2 +- ...eReferenceNotInitializedSuppressorTests.cs | 6 +- ...lOverAlwaysFalseConditionsAnalyzerTests.cs | 60 ++++- ...structorOverTestInitializeAnalyzerTests.cs | 11 +- ...eferDisposeOverTestCleanupAnalyzerTests.cs | 12 +- ...eferTestCleanupOverDisposeAnalyzerTests.cs | 7 +- ...tInitializeOverConstructorAnalyzerTests.cs | 9 +- .../MSTest.Analyzers.UnitTests/Program.cs | 8 +- .../Properties/launchSettings.json | 2 +- ...icMethodShouldBeTestMethodAnalyzerTests.cs | 15 +- ...ublicTypeShouldBeTestClassAnalyzerTests.cs | 10 +- ...wAlwaysTrueAssertConditionAnalyzerTests.cs | 59 ++++- .../TestClassShouldBeValidAnalyzerTests.cs | 24 +- ...tClassShouldHaveTestMethodAnalyzerTests.cs | 17 +- .../TestCleanupShouldBeValidAnalyzerTests.cs | 29 ++- .../TestContextShouldBeValidAnalyzerTests.cs | 149 ++++++------ ...estInitializeShouldBeValidAnalyzerTests.cs | 29 ++- .../TestMethodShouldBeValidAnalyzerTests.cs | 24 +- ...stMethodShouldNotBeIgnoredAnalyzerTests.cs | 8 +- ...ingTestMethodShouldBeATestClassAnalyzer.cs | 12 +- ...cSuffixTestFixtureMethodSuppressorTests.cs | 6 +- ...UseAsyncSuffixTestMethodSuppressorTests.cs | 7 +- .../UseAttributeOnTestMethodAnalyzerTests.cs | 22 +- ...sCleanupBehaviorEndOfClassAnalyzerTests.cs | 16 +- ...mWithTestMethodOrTestClassAnalyzerTests.cs | 10 +- .../UseParallelizeAttributeAnalyzerTests.cs | 7 +- .../UseProperAssertMethodsAnalyzerTests.cs | 25 +- .../Verifiers/CSharpCodeFixVerifier`2+Test.cs | 1 - .../AppInsightsProviderTests.cs | 13 +- .../CrashDumpTests.cs | 15 +- .../HangDumpTests.cs | 32 ++- ...rosoft.Testing.Extensions.UnitTests.csproj | 3 +- .../Program.cs | 8 +- .../Properties/launchSettings.json | 2 +- .../TrxCompareToolCommandLineTests.cs | 24 +- .../TrxReportGeneratorCommandLineTests.cs | 20 +- .../TrxTests.cs | 37 ++- ...SettingsCommandLineOptionsProviderTests.cs | 8 +- ...arameterCommandLineOptionsProviderTests.cs | 7 +- ...g.Extensions.VSTestBridge.UnitTests.csproj | 2 +- .../ObjectModel/ObjectModelConvertersTests.cs | 88 ++++--- .../ObjectModel/RunContextAdapterTests.cs | 11 +- .../ObjectModel/RunSettingsPatcherTests.cs | 29 ++- .../Program.cs | 11 +- .../Properties/launchSettings.json | 2 +- .../MSBuildTests.cs | 22 +- ....Testing.Platform.MSBuild.UnitTests.csproj | 4 +- .../Program.cs | 7 +- .../Usings.cs | 1 - .../CommandLine/ArgumentArityTests.cs | 15 +- .../CommandLine/CommandLineHandlerTests.cs | 33 ++- .../CommandLine/CommandLineTests.cs | 27 +-- .../PlatformCommandLineProviderTests.cs | 51 ++-- ...deFilterCommandLineOptionsProviderTests.cs | 11 +- .../AggregatedConfigurationTests.cs | 36 ++- .../ConfigurationExtensionsTests.cs | 25 +- .../ConfigurationManagerTests.cs | 19 +- .../Helpers/CountDownEventTests.cs | 12 +- .../Helpers/SystemAsyncMonitorTests.cs | 10 +- .../Helpers/TaskExtensionsTests.cs | 113 +++++---- .../IPC/IPCTests.cs | 51 ++-- .../IPC/ProtocolTests.cs | 10 +- .../Logging/FileLoggerTests.cs | 30 ++- .../Logging/LogTestHelpers.cs | 3 + .../Logging/LoggerFactoryTests.cs | 8 +- .../Logging/LoggerTests.cs | 16 +- .../Logging/LoggingExtensionsTests.cs | 20 +- .../Logging/NopLoggerTests.cs | 13 +- .../Messages/AsynchronousMessageBusTests.cs | 23 +- .../Messages/PropertyBagTests.cs | 41 ++-- .../Messages/TestNodeUidTests.cs | 34 +-- ...icrosoft.Testing.Platform.UnitTests.csproj | 8 +- .../Terminal/TargetFrameworkParserTests.cs | 36 ++- .../Terminal/TerminalTestReporterTests.cs | 27 +-- .../Program.cs | 9 +- .../Properties/launchSettings.json | 2 +- .../Requests/TreeNodeFilterTests.cs | 73 +++--- .../ServerMode/FormatterUtilitiesTests.cs | 32 ++- .../ServerMode/JsonTests.cs | 15 +- .../ServerMode/JsoniteTests.cs | 10 +- .../ServerDataConsumerServiceTests.cs | 68 +++--- .../ServerMode/ServerTests.cs | 10 +- .../Services/ServiceProviderTests.cs | 40 +++- .../Services/TestApplicationResultTests.cs | 88 +++---- .../Telemetry/ServerTelemetryTests.cs | 10 +- .../Telemetry/TelemetryManagerTests.cs | 38 +-- .../TestApplicationBuilderTests.cs | 51 ++-- .../Constants.cs | 3 + ...icrosoft.Testing.TestInfrastructure.csproj | 10 +- .../RetryHelper.cs | 6 +- .../SourceCodeExtensions.cs | 4 +- .../TargetFrameworks.cs | 28 ++- .../TestAssetFixtureBase.cs | 23 +- .../TestBase.cs | 11 - .../TestsRunWatchDog.cs | 120 ---------- 194 files changed, 3338 insertions(+), 2817 deletions(-) delete mode 100644 test/Utilities/Microsoft.Testing.TestInfrastructure/TestBase.cs delete mode 100644 test/Utilities/Microsoft.Testing.TestInfrastructure/TestsRunWatchDog.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index cf6e363599..6ddbf71dfa 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -25,6 +25,7 @@ 1.1.3-beta1.24423.1 + 3.8.0-preview.24616.6 @@ -65,12 +66,13 @@ - - + + + diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs index 06ecd53fbe..da68aed004 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs @@ -9,12 +9,11 @@ using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Data; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; -using Microsoft.VisualStudio.TestTools.UnitTesting; #endif using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; +using Microsoft.VisualStudio.TestTools.UnitTesting; using ITestDataSource = Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestDataSource; -using UTF = Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; @@ -36,9 +35,9 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; public class TestDataSource : ITestDataSource { #if NETFRAMEWORK - public IEnumerable? GetData(UTF.ITestMethod testMethodInfo, ITestContext testContext) + public IEnumerable? GetData(ITestMethod testMethodInfo, ITestContext testContext) #else - IEnumerable? ITestDataSource.GetData(UTF.ITestMethod testMethodInfo, ITestContext testContext) + IEnumerable? ITestDataSource.GetData(ITestMethod testMethodInfo, ITestContext testContext) #endif { #if NETFRAMEWORK @@ -49,12 +48,12 @@ public class TestDataSource : ITestDataSource Path.GetDirectoryName(new Uri(testMethodInfo.MethodInfo.Module.Assembly.CodeBase).LocalPath), ]; - List dataRowResults = []; + List dataRowResults = []; // Connect to data source. TestDataConnectionFactory factory = new(); - GetConnectionProperties(testMethodInfo.GetAttributes(false)[0], out string providerNameInvariant, out string? connectionString, out string? tableName, out UTF.DataAccessMethod dataAccessMethod); + GetConnectionProperties(testMethodInfo.GetAttributes(false)[0], out string providerNameInvariant, out string? connectionString, out string? tableName, out DataAccessMethod dataAccessMethod); try { @@ -103,7 +102,7 @@ public class TestDataSource : ITestDataSource /// The data access method. /// Number of permutations. /// Permutations. - private static IEnumerable GetPermutation(UTF.DataAccessMethod dataAccessMethod, int length) + private static IEnumerable GetPermutation(DataAccessMethod dataAccessMethod, int length) { switch (dataAccessMethod) { @@ -127,8 +126,8 @@ private static IEnumerable GetPermutation(UTF.DataAccessMethod dataAccessMe /// The connection string. /// The table name. /// The data access method. - private static void GetConnectionProperties(UTF.DataSourceAttribute dataSourceAttribute, out string providerNameInvariant, - out string? connectionString, out string? tableName, out UTF.DataAccessMethod dataAccessMethod) + private static void GetConnectionProperties(DataSourceAttribute dataSourceAttribute, out string providerNameInvariant, + out string? connectionString, out string? tableName, out DataAccessMethod dataAccessMethod) { if (StringEx.IsNullOrEmpty(dataSourceAttribute.DataSourceSettingName)) { @@ -139,7 +138,7 @@ private static void GetConnectionProperties(UTF.DataSourceAttribute dataSourceAt return; } - UTF.DataSourceElement element = TestConfiguration.ConfigurationSection.DataSources[dataSourceAttribute.DataSourceSettingName] + DataSourceElement element = TestConfiguration.ConfigurationSection.DataSources[dataSourceAttribute.DataSourceSettingName] #pragma warning disable CA2201 // Do not raise reserved exception types ?? throw new Exception(string.Format(CultureInfo.CurrentCulture, Resource.UTA_DataSourceConfigurationSectionMissing, dataSourceAttribute.DataSourceSettingName)); #pragma warning restore CA2201 // Do not raise reserved exception types diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs index cc5b3efeb1..708fff0ec5 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs @@ -86,7 +86,7 @@ public virtual string GetNextIterationDirectoryName(string parentDirectoryName, /// Returns empty string on error when specified to continue the run on error, /// throw on error when specified to abort the run on error. /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] public virtual string CopyFileOverwrite(string source, string destination, out string? warning) { DebugEx.Assert(!StringEx.IsNullOrEmpty(source), "source should not be null."); @@ -224,7 +224,7 @@ public static string TryConvertPathToRelative(string path, string rootDir) /// them. /// /// The root directory to clear. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] public virtual void DeleteDirectories(string filePath) { Guard.NotNullOrWhiteSpace(filePath); @@ -255,7 +255,7 @@ public virtual void DeleteDirectories(string filePath) /// /// path to symbols file. /// Pdb file name or null if non-existent. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] private static string? GetSymbolsFileName(string? path) { if (StringEx.IsNullOrEmpty(path) || path.IndexOfAny(Path.GetInvalidPathChars()) != -1) diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs index 13290e5703..f988d950c2 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs @@ -171,12 +171,12 @@ private bool TryGetOrCreateTypeByMetadataNameSlow( } /// - /// Determines if is a with its type + /// Determines if is a with its type /// argument satisfying . /// - /// Type potentially representing a . + /// Type potentially representing a . /// Predicate to check the 's type argument. - /// True if is a with its + /// True if is a with its /// type argument satisfying , false otherwise. internal bool IsTaskOfType([NotNullWhen(returnValue: true)] ITypeSymbol? typeSymbol, Func typeArgumentPredicate) => typeSymbol != null diff --git a/src/Platform/Microsoft.Testing.Extensions.CrashDump/Microsoft.Testing.Extensions.CrashDump.csproj b/src/Platform/Microsoft.Testing.Extensions.CrashDump/Microsoft.Testing.Extensions.CrashDump.csproj index f711a190c2..6d7d59466d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.CrashDump/Microsoft.Testing.Extensions.CrashDump.csproj +++ b/src/Platform/Microsoft.Testing.Extensions.CrashDump/Microsoft.Testing.Extensions.CrashDump.csproj @@ -42,7 +42,6 @@ This package extends Microsoft Testing Platform to provide a crash dump function - diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Microsoft.Testing.Extensions.TrxReport.csproj b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Microsoft.Testing.Extensions.TrxReport.csproj index 336a3f8003..0cfd477f7f 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/Microsoft.Testing.Extensions.TrxReport.csproj +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/Microsoft.Testing.Extensions.TrxReport.csproj @@ -50,7 +50,6 @@ This package extends Microsoft Testing Platform to provide TRX test reports.]]> - diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Microsoft.Testing.Extensions.VSTestBridge.csproj b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Microsoft.Testing.Extensions.VSTestBridge.csproj index 64a5152e66..a3d08254e9 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Microsoft.Testing.Extensions.VSTestBridge.csproj +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Microsoft.Testing.Extensions.VSTestBridge.csproj @@ -5,8 +5,6 @@ - - diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FastFilter.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FastFilter.cs index 6e596db037..3e0ec2232c 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FastFilter.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FastFilter.cs @@ -195,14 +195,15 @@ private void AddProperty(string name, string value) { if (!_filterDictionaryBuilder.TryGetValue(name, out ImmutableHashSet.Builder? values)) { - values = ImmutableHashSet.CreateBuilder(StringComparer.OrdinalIgnoreCase); + values = ImmutableHashSet.CreateBuilder(StringComparer.OrdinalIgnoreCase)!; _filterDictionaryBuilder.Add(name, values); } values.Add(value); } - internal FastFilter? ToFastFilter() => ContainsValidFilter + internal FastFilter? ToFastFilter() + => ContainsValidFilter ? new FastFilter( _filterDictionaryBuilder.ToImmutableDictionary(kvp => kvp.Key, kvp => (ISet)_filterDictionaryBuilder[kvp.Key].ToImmutable()), _fastFilterOperation, diff --git a/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj b/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj index 20f935bb6b..65d829e792 100644 --- a/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj +++ b/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj @@ -63,8 +63,6 @@ This package provides the core platform and the .NET implementation of the proto - - diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs index e99de710ee..f3e486205d 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs @@ -218,10 +218,10 @@ static SerializerUtilities() #if NETCOREAPP properties[namedKvpStringProperty.Name] = namedKvpStringProperty.Pairs; #else - Jsonite.JsonArray collection = []; + JsonArray collection = []; foreach (KeyValuePair item in namedKvpStringProperty.Pairs) { - Jsonite.JsonObject o = new() + JsonObject o = new() { { item.Key, item.Value }, }; @@ -419,10 +419,10 @@ static SerializerUtilities() #if NETCOREAPP values[JsonRpcStrings.EnvironmentVariables] = ev.EnvironmentVariables; #else - Jsonite.JsonArray collection = []; + JsonArray collection = []; foreach (KeyValuePair item in ev.EnvironmentVariables) { - Jsonite.JsonObject o = new() + JsonObject o = new() { { item.Key, item.Value }, }; diff --git a/src/TestFramework/TestFramework.Extensions/ConfigurationSettings/TestConfigurationSection.cs b/src/TestFramework/TestFramework.Extensions/ConfigurationSettings/TestConfigurationSection.cs index 91fde548cd..602e795cfc 100644 --- a/src/TestFramework/TestFramework.Extensions/ConfigurationSettings/TestConfigurationSection.cs +++ b/src/TestFramework/TestFramework.Extensions/ConfigurationSettings/TestConfigurationSection.cs @@ -24,7 +24,7 @@ public sealed class TestConfigurationSection : ConfigurationSection /// Gets the collection of properties. /// /// - /// The of properties for the element. + /// The of properties for the element. /// protected override ConfigurationPropertyCollection Properties { get; } = [DataSourcesValue]; } diff --git a/src/TestFramework/TestFramework.Extensions/PrivateObject.cs b/src/TestFramework/TestFramework.Extensions/PrivateObject.cs index 48a7b255eb..ba97ebbbdd 100644 --- a/src/TestFramework/TestFramework.Extensions/PrivateObject.cs +++ b/src/TestFramework/TestFramework.Extensions/PrivateObject.cs @@ -73,7 +73,7 @@ public PrivateObject(string assemblyName, string typeName, params object?[]? arg /// /// Name of the assembly. /// fully qualified name. - /// An array of objects representing the number, order, and type of the parameters for the constructor to get. + /// An array of objects representing the number, order, and type of the parameters for the constructor to get. /// Arguments to pass to the constructor. public PrivateObject(string assemblyName, string typeName, Type[]? parameterTypes, object?[]? args) : this(Type.GetType(string.Format(CultureInfo.InvariantCulture, "{0}, {1}", typeName, assemblyName), false), parameterTypes, args) @@ -97,7 +97,7 @@ public PrivateObject(Type type, params object?[]? args) /// specified type. /// /// type of the object to create. - /// An array of objects representing the number, order, and type of the parameters for the constructor to get. + /// An array of objects representing the number, order, and type of the parameters for the constructor to get. /// Arguments to pass to the constructor. public PrivateObject(Type type, Type[]? parameterTypes, object?[]? args) { @@ -241,7 +241,7 @@ public override bool Equals(object? obj) /// Invokes the specified method. /// /// Name of the method. - /// An array of objects representing the number, order, and type of the parameters for the method to get. + /// An array of objects representing the number, order, and type of the parameters for the method to get. /// Arguments to pass to the member to invoke. /// Result of method call. public object? Invoke(string name, Type[] parameterTypes, object?[]? args) => Invoke(name, parameterTypes, args, CultureInfo.InvariantCulture); @@ -250,7 +250,7 @@ public override bool Equals(object? obj) /// Invokes the specified method. /// /// Name of the method. - /// An array of objects representing the number, order, and type of the parameters for the method to get. + /// An array of objects representing the number, order, and type of the parameters for the method to get. /// Arguments to pass to the member to invoke. /// An array of types corresponding to the types of the generic arguments. /// Result of method call. @@ -269,7 +269,7 @@ public override bool Equals(object? obj) /// Invokes the specified method. /// /// Name of the method. - /// An array of objects representing the number, order, and type of the parameters for the method to get. + /// An array of objects representing the number, order, and type of the parameters for the method to get. /// Arguments to pass to the member to invoke. /// Culture info. /// Result of method call. @@ -279,7 +279,7 @@ public override bool Equals(object? obj) /// Invokes the specified method. /// /// Name of the method. - /// A bitmask comprised of one or more that specify how the search is conducted. + /// A bitmask comprised of one or more that specify how the search is conducted. /// Arguments to pass to the member to invoke. /// Result of method call. public object? Invoke(string name, BindingFlags bindingFlags, params object?[]? args) => Invoke(name, bindingFlags, null, args, CultureInfo.InvariantCulture); @@ -288,8 +288,8 @@ public override bool Equals(object? obj) /// Invokes the specified method. /// /// Name of the method. - /// A bitmask comprised of one or more that specify how the search is conducted. - /// An array of objects representing the number, order, and type of the parameters for the method to get. + /// A bitmask comprised of one or more that specify how the search is conducted. + /// An array of objects representing the number, order, and type of the parameters for the method to get. /// Arguments to pass to the member to invoke. /// Result of method call. public object? Invoke(string name, BindingFlags bindingFlags, Type[] parameterTypes, object?[]? args) => Invoke(name, bindingFlags, parameterTypes, args, CultureInfo.InvariantCulture); @@ -298,7 +298,7 @@ public override bool Equals(object? obj) /// Invokes the specified method. /// /// Name of the method. - /// A bitmask comprised of one or more that specify how the search is conducted. + /// A bitmask comprised of one or more that specify how the search is conducted. /// Arguments to pass to the member to invoke. /// Culture info. /// Result of method call. @@ -308,8 +308,8 @@ public override bool Equals(object? obj) /// Invokes the specified method. /// /// Name of the method. - /// A bitmask comprised of one or more that specify how the search is conducted. - /// An array of objects representing the number, order, and type of the parameters for the method to get. + /// A bitmask comprised of one or more that specify how the search is conducted. + /// An array of objects representing the number, order, and type of the parameters for the method to get. /// Arguments to pass to the member to invoke. /// Culture info. /// Result of method call. @@ -319,8 +319,8 @@ public override bool Equals(object? obj) /// Invokes the specified method. /// /// Name of the method. - /// A bitmask comprised of one or more that specify how the search is conducted. - /// An array of objects representing the number, order, and type of the parameters for the method to get. + /// A bitmask comprised of one or more that specify how the search is conducted. + /// An array of objects representing the number, order, and type of the parameters for the method to get. /// Arguments to pass to the member to invoke. /// Culture info. /// An array of types corresponding to the types of the generic arguments. @@ -408,7 +408,7 @@ public void SetArrayElement(string name, object value, params int[] indices) /// Gets the array element using array of subscripts for each dimension. /// /// Name of the member. - /// A bitmask comprised of one or more that specify how the search is conducted. + /// A bitmask comprised of one or more that specify how the search is conducted. /// the indices of array. /// An array of elements. public object GetArrayElement(string name, BindingFlags bindingFlags, params int[] indices) @@ -423,7 +423,7 @@ public object GetArrayElement(string name, BindingFlags bindingFlags, params int /// Sets the array element using array of subscripts for each dimension. /// /// Name of the member. - /// A bitmask comprised of one or more that specify how the search is conducted. + /// A bitmask comprised of one or more that specify how the search is conducted. /// Value to set. /// the indices of array. public void SetArrayElement(string name, BindingFlags bindingFlags, object value, params int[] indices) @@ -460,7 +460,7 @@ public void SetField(string name, object value) /// Gets the field. /// /// Name of the field. - /// A bitmask comprised of one or more that specify how the search is conducted. + /// A bitmask comprised of one or more that specify how the search is conducted. /// The field. public object? GetField(string name, BindingFlags bindingFlags) { @@ -472,7 +472,7 @@ public void SetField(string name, object value) /// Sets the field. /// /// Name of the field. - /// A bitmask comprised of one or more that specify how the search is conducted. + /// A bitmask comprised of one or more that specify how the search is conducted. /// value to set. public void SetField(string name, BindingFlags bindingFlags, object? value) { @@ -506,7 +506,7 @@ public void SetFieldOrProperty(string name, object value) /// Gets the field or property. /// /// Name of the field or property. - /// A bitmask comprised of one or more that specify how the search is conducted. + /// A bitmask comprised of one or more that specify how the search is conducted. /// The field or property. public object? GetFieldOrProperty(string name, BindingFlags bindingFlags) { @@ -518,7 +518,7 @@ public void SetFieldOrProperty(string name, object value) /// Sets the field or property. /// /// Name of the field or property. - /// A bitmask comprised of one or more that specify how the search is conducted. + /// A bitmask comprised of one or more that specify how the search is conducted. /// value to set. public void SetFieldOrProperty(string name, BindingFlags bindingFlags, object? value) { @@ -538,7 +538,7 @@ public void SetFieldOrProperty(string name, BindingFlags bindingFlags, object? v /// Gets the property. /// /// Name of the property. - /// An array of objects representing the number, order, and type of the parameters for the indexed property. + /// An array of objects representing the number, order, and type of the parameters for the indexed property. /// Arguments to pass to the member to invoke. /// The property. public object? GetProperty(string name, Type[]? parameterTypes, object?[]? args) => GetProperty(name, BindToEveryThing, parameterTypes, args); @@ -555,7 +555,7 @@ public void SetFieldOrProperty(string name, BindingFlags bindingFlags, object? v /// Set the property. /// /// Name of the property. - /// An array of objects representing the number, order, and type of the parameters for the indexed property. + /// An array of objects representing the number, order, and type of the parameters for the indexed property. /// value to set. /// Arguments to pass to the member to invoke. public void SetProperty(string name, Type[]? parameterTypes, object? value, object?[]? args) => SetProperty(name, BindToEveryThing, value, parameterTypes, args); @@ -564,7 +564,7 @@ public void SetFieldOrProperty(string name, BindingFlags bindingFlags, object? v /// Gets the property. /// /// Name of the property. - /// A bitmask comprised of one or more that specify how the search is conducted. + /// A bitmask comprised of one or more that specify how the search is conducted. /// Arguments to pass to the member to invoke. /// The property. public object? GetProperty(string name, BindingFlags bindingFlags, params object?[]? args) => GetProperty(name, bindingFlags, null, args); @@ -573,8 +573,8 @@ public void SetFieldOrProperty(string name, BindingFlags bindingFlags, object? v /// Gets the property. /// /// Name of the property. - /// A bitmask comprised of one or more that specify how the search is conducted. - /// An array of objects representing the number, order, and type of the parameters for the indexed property. + /// A bitmask comprised of one or more that specify how the search is conducted. + /// An array of objects representing the number, order, and type of the parameters for the indexed property. /// Arguments to pass to the member to invoke. /// The property. public object? GetProperty(string name, BindingFlags bindingFlags, Type[]? parameterTypes, object?[]? args) @@ -594,7 +594,7 @@ public void SetFieldOrProperty(string name, BindingFlags bindingFlags, object? v /// Sets the property. /// /// Name of the property. - /// A bitmask comprised of one or more that specify how the search is conducted. + /// A bitmask comprised of one or more that specify how the search is conducted. /// value to set. /// Arguments to pass to the member to invoke. public void SetProperty(string name, BindingFlags bindingFlags, object value, params object?[]? args) => SetProperty(name, bindingFlags, value, null, args); @@ -603,9 +603,9 @@ public void SetFieldOrProperty(string name, BindingFlags bindingFlags, object? v /// Sets the property. /// /// Name of the property. - /// A bitmask comprised of one or more that specify how the search is conducted. + /// A bitmask comprised of one or more that specify how the search is conducted. /// value to set. - /// An array of objects representing the number, order, and type of the parameters for the indexed property. + /// An array of objects representing the number, order, and type of the parameters for the indexed property. /// Arguments to pass to the member to invoke. public void SetProperty(string name, BindingFlags bindingFlags, object? value, Type[]? parameterTypes, object?[]? args) { diff --git a/src/TestFramework/TestFramework.Extensions/PrivateType.cs b/src/TestFramework/TestFramework.Extensions/PrivateType.cs index c9733d65cb..9d188e76d8 100644 --- a/src/TestFramework/TestFramework.Extensions/PrivateType.cs +++ b/src/TestFramework/TestFramework.Extensions/PrivateType.cs @@ -59,7 +59,7 @@ public PrivateType(Type type) => /// Invokes static member. /// /// Name of the member to InvokeHelper. - /// An array of objects representing the number, order, and type of the parameters for the method to invoke. + /// An array of objects representing the number, order, and type of the parameters for the method to invoke. /// Arguments to the invocation. /// Result of invocation. public object InvokeStatic(string name, Type[]? parameterTypes, object?[]? args) => InvokeStatic(name, parameterTypes, args, CultureInfo.InvariantCulture); @@ -68,7 +68,7 @@ public PrivateType(Type type) => /// Invokes static member. /// /// Name of the member to InvokeHelper. - /// An array of objects representing the number, order, and type of the parameters for the method to invoke. + /// An array of objects representing the number, order, and type of the parameters for the method to invoke. /// Arguments to the invocation. /// An array of types corresponding to the types of the generic arguments. /// Result of invocation. @@ -87,7 +87,7 @@ public PrivateType(Type type) => /// Invokes the static method. /// /// Name of the member. - /// An array of objects representing the number, order, and type of the parameters for the method to invoke. + /// An array of objects representing the number, order, and type of the parameters for the method to invoke. /// Arguments to the invocation. /// Culture info. /// Result of invocation. @@ -107,7 +107,7 @@ public PrivateType(Type type) => /// /// Name of the member. /// Additional invocation attributes. - /// An array of objects representing the number, order, and type of the parameters for the method to invoke. + /// An array of objects representing the number, order, and type of the parameters for the method to invoke. /// Arguments to the invocation. /// Result of invocation. public object InvokeStatic(string name, BindingFlags bindingFlags, Type[]? parameterTypes, object?[]? args) => InvokeStatic(name, bindingFlags, parameterTypes, args, CultureInfo.InvariantCulture); @@ -127,7 +127,7 @@ public PrivateType(Type type) => /// /// Name of the member. /// Additional invocation attributes. - /// /// An array of objects representing the number, order, and type of the parameters for the method to invoke. + /// /// An array of objects representing the number, order, and type of the parameters for the method to invoke. /// Arguments to the invocation. /// Culture. /// Result of invocation. @@ -138,7 +138,7 @@ public PrivateType(Type type) => /// /// Name of the member. /// Additional invocation attributes. - /// /// An array of objects representing the number, order, and type of the parameters for the method to invoke. + /// /// An array of objects representing the number, order, and type of the parameters for the method to invoke. /// Arguments to the invocation. /// Culture. /// An array of types corresponding to the types of the generic arguments. @@ -354,7 +354,7 @@ public void SetStaticFieldOrProperty(string name, BindingFlags bindingFlags, obj /// /// Name of the property. /// Value to be set to field or property. - /// An array of objects representing the number, order, and type of the parameters for the indexed property. + /// An array of objects representing the number, order, and type of the parameters for the indexed property. /// Arguments to pass to the member to invoke. public void SetStaticProperty(string name, object value, Type[]? parameterTypes, object?[]? args) => SetStaticProperty(name, BindingFlags.SetProperty, value, parameterTypes, args); @@ -372,7 +372,7 @@ public void SetStaticFieldOrProperty(string name, BindingFlags bindingFlags, obj /// /// Name of the property. /// Additional invocation attributes. - /// An array of objects representing the number, order, and type of the parameters for the indexed property. + /// An array of objects representing the number, order, and type of the parameters for the indexed property. /// Arguments to pass to the member to invoke. /// The static property. public object GetStaticProperty(string name, BindingFlags bindingFlags, Type[]? parameterTypes, object?[]? args) @@ -403,7 +403,7 @@ public object GetStaticProperty(string name, BindingFlags bindingFlags, Type[]? /// Name of the property. /// Additional invocation attributes. /// Value to be set to field or property. - /// An array of objects representing the number, order, and type of the parameters for the indexed property. + /// An array of objects representing the number, order, and type of the parameters for the indexed property. /// Arguments to pass to the member to invoke. public void SetStaticProperty(string name, BindingFlags bindingFlags, object value, Type[]? parameterTypes, object?[]? args) { diff --git a/src/TestFramework/TestFramework.Extensions/TestContext.cs b/src/TestFramework/TestFramework.Extensions/TestContext.cs index 95f08dcde9..83082db374 100644 --- a/src/TestFramework/TestFramework.Extensions/TestContext.cs +++ b/src/TestFramework/TestFramework.Extensions/TestContext.cs @@ -206,7 +206,7 @@ public abstract class TestContext { DebugEx.Assert(Properties is not null, "Properties is null"); #if WINDOWS_UWP || WIN_UI - if (!((System.Collections.Generic.IDictionary)Properties).TryGetValue(name, out object? propertyValue)) + if (!((IDictionary)Properties).TryGetValue(name, out object? propertyValue)) { return null; } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs index b8b2831400..d186f6721b 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs @@ -16,7 +16,7 @@ public sealed partial class Assert /// /// Tests whether the specified values are equal and throws an exception /// if the two values are not equal. - /// The equality is computed using the default . + /// The equality is computed using the default . /// /// /// The type of values to compare. @@ -36,7 +36,7 @@ public static void AreEqual(T? expected, T? actual) /// /// Tests whether the specified values are equal and throws an exception /// if the two values are not equal. - /// The equality is computed using the default . + /// The equality is computed using the default . /// /// /// The type of values to compare. @@ -48,8 +48,8 @@ public static void AreEqual(T? expected, T? actual) /// The second value to compare. This is the value produced by the code under test. /// /// - /// The implementation to use when comparing keys, - /// or null to use the default . + /// The implementation to use when comparing keys, + /// or null to use the default . /// /// /// Thrown if is not equal to . @@ -60,7 +60,7 @@ public static void AreEqual(T? expected, T? actual, IEqualityComparer? com /// /// Tests whether the specified values are equal and throws an exception /// if the two values are not equal. - /// The equality is computed using the default . + /// The equality is computed using the default . /// /// /// The type of values to compare. @@ -98,8 +98,8 @@ public static void AreEqual(T? expected, T? actual, string? message) /// The second value to compare. This is the value produced by the code under test. /// /// - /// The implementation to use when comparing keys, - /// or null to use the default . + /// The implementation to use when comparing keys, + /// or null to use the default . /// /// /// The message to include in the exception when @@ -116,7 +116,7 @@ public static void AreEqual(T? expected, T? actual, IEqualityComparer? com /// /// Tests whether the specified values are equal and throws an exception /// if the two values are not equal. - /// The equality is computed using the default . + /// The equality is computed using the default . /// /// /// The type of values to compare. @@ -157,8 +157,8 @@ public static void AreEqual(T? expected, T? actual, [StringSyntax(StringSynta /// The second value to compare. This is the value produced by the code under test. /// /// - /// The implementation to use when comparing keys, - /// or null to use the default . + /// The implementation to use when comparing keys, + /// or null to use the default . /// /// /// The message to include in the exception when @@ -204,7 +204,7 @@ public static void AreEqual(T? expected, T? actual, IEqualityComparer? com /// /// Tests whether the specified values are equal and throws an exception /// if the two values are not equal. - /// The equality is computed using the default . + /// The equality is computed using the default . /// /// /// The type of values to compare. @@ -224,7 +224,7 @@ public static void AreEqual(IEquatable? expected, IEquatable? actual) /// /// Tests whether the specified values are equal and throws an exception /// if the two values are not equal. - /// The equality is computed using the default . + /// The equality is computed using the default . /// /// /// The type of values to compare. @@ -250,7 +250,7 @@ public static void AreEqual(IEquatable? expected, IEquatable? actual, s /// /// Tests whether the specified values are equal and throws an exception /// if the two values are not equal. - /// The equality is computed using the default . + /// The equality is computed using the default . /// /// /// The type of values to compare. @@ -308,7 +308,7 @@ public static void AreEqual(IEquatable? expected, IEquatable? actual, [ /// /// Tests whether the specified values are unequal and throws an exception /// if the two values are equal. - /// The equality is computed using the default . + /// The equality is computed using the default . /// /// /// The type of values to compare. @@ -342,8 +342,8 @@ public static void AreNotEqual(T? notExpected, T? actual) /// The second value to compare. This is the value produced by the code under test. /// /// - /// The implementation to use when comparing keys, - /// or null to use the default . + /// The implementation to use when comparing keys, + /// or null to use the default . /// /// /// Thrown if is equal to . @@ -354,7 +354,7 @@ public static void AreNotEqual(T? notExpected, T? actual, IEqualityComparer /// Tests whether the specified values are unequal and throws an exception /// if the two values are equal. - /// The equality is computed using the default . + /// The equality is computed using the default . /// /// /// The type of values to compare. @@ -393,8 +393,8 @@ public static void AreNotEqual(T? notExpected, T? actual, string? message) /// The second value to compare. This is the value produced by the code under test. /// /// - /// The implementation to use when comparing keys, - /// or null to use the default . + /// The implementation to use when comparing keys, + /// or null to use the default . /// /// /// The message to include in the exception when @@ -410,7 +410,7 @@ public static void AreNotEqual(T? notExpected, T? actual, IEqualityComparer /// Tests whether the specified values are unequal and throws an exception /// if the two values are equal. - /// The equality is computed using the default . + /// The equality is computed using the default . /// /// /// The type of values to compare. @@ -452,8 +452,8 @@ public static void AreNotEqual(T? notExpected, T? actual, [StringSyntax(Strin /// The second value to compare. This is the value produced by the code under test. /// /// - /// The implementation to use when comparing keys, - /// or null to use the default . + /// The implementation to use when comparing keys, + /// or null to use the default . /// /// /// The message to include in the exception when diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs index 81fe910c6c..81392a5742 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs @@ -48,7 +48,7 @@ public static void IsInstanceOfType([NotNull] object? value) /// /// The expected type of . public static void IsInstanceOfType([NotNull] object? value, out T instance) - => IsInstanceOfType(value, out instance, string.Empty, null); + => IsInstanceOfType(value, out instance, string.Empty, null); /// /// Tests whether the specified object is an instance of the expected @@ -90,7 +90,7 @@ public static void IsInstanceOfType([NotNull] object? value, string? message) /// /// The expected type of . public static void IsInstanceOfType([NotNull] object? value, out T instance, string? message) - => IsInstanceOfType(value, out instance, message, null); + => IsInstanceOfType(value, out instance, message, null); /// /// Tests whether the specified object is an instance of the expected diff --git a/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs b/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs index 98d779210f..bf76e223d5 100644 --- a/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs +++ b/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs @@ -1563,8 +1563,8 @@ private static bool FindMismatchedElement(IEnumerable expected, IEnumerab // $ CONSIDER: comparison, which should result in ~n*log(n) + m*log(m) + n. // Count the occurrences of each object in the both collections - Dictionary expectedElements = GetElementCounts(expected, comparer, out int expectedNulls); - Dictionary actualElements = GetElementCounts(actual, comparer, out int actualNulls); + Dictionary expectedElements = GetElementCounts(expected, comparer, out int expectedNulls); + Dictionary actualElements = GetElementCounts(actual, comparer, out int actualNulls); if (actualNulls != expectedNulls) { diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs index b23dec0cab..ac30e26910 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs @@ -105,7 +105,7 @@ public DataSourceAttribute(string connectionString, string tableName) /// /// /// - /// One of the values. If the is not initialized, this will return the default value . + /// One of the values. If the is not initialized, this will return the default value . /// public DataAccessMethod DataAccessMethod { get; } diff --git a/test/.editorconfig b/test/.editorconfig index 26a155ee3a..f7922ee56d 100644 --- a/test/.editorconfig +++ b/test/.editorconfig @@ -29,3 +29,10 @@ dotnet_diagnostic.CA2201.severity = none # CA2201: Do not raise reser dotnet_diagnostic.CA3075.severity = none # CA3075: Insecure DTD processing in XML dotnet_diagnostic.IDE0060.severity = none # IDE0060: Remove unused parameter + +dotnet_diagnostic.MSTEST0001.severity = warning # MSTEST0001: Explicitly enable or disable tests parallelization +dotnet_diagnostic.MSTEST0016.severity = warning # MSTEST0016: Test class should have test method +dotnet_diagnostic.MSTEST0017.severity = warning # MSTEST0017: Assertion arguments should be passed in the correct order +dotnet_diagnostic.MSTEST0029.severity = warning # MSTEST0029: Public methods should be test methods +dotnet_diagnostic.MSTEST0030.severity = warning # MSTEST0030: Type containing '[TestMethod]' should be marked with '[TestClass]' +dotnet_diagnostic.MSTEST0032.severity = warning # MSTEST0032: Assertion condition is always true diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 9f0a8ac53b..be7e8c4711 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -6,8 +6,9 @@ enable Exe - + true false + false $(PlatformTarget) x64 $(MSBuildProjectName)_$(TargetFramework)_$(Configuration)_$(Architecture) @@ -22,22 +23,20 @@ - - - - - - + + + + - + diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AbortionTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AbortionTests.cs index a96340353a..e8130111cc 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AbortionTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AbortionTests.cs @@ -9,16 +9,13 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class AbortionTests : AcceptanceTestBase +[TestClass] +public sealed class AbortionTests : AcceptanceTestBase { private const string AssetName = "Abort"; - private readonly TestAssetFixture _testAssetFixture; - - public AbortionTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task AbortWithCTRLPlusC_CancellingTests(string tfm) { // We expect the same semantic for Linux, the test setup is not cross and we're using specific @@ -28,7 +25,7 @@ public async Task AbortWithCTRLPlusC_CancellingTests(string tfm) return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); string fileCreationPath = Path.Combine(testHost.DirectoryName, "fileCreation"); File.WriteAllText(fileCreationPath, string.Empty); @@ -43,8 +40,7 @@ public async Task AbortWithCTRLPlusC_CancellingTests(string tfm) testHostResult.AssertOutputMatchesRegex("Canceling the test session.*"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string Sources = """ #file Abort.csproj diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssemblyResolutionTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssemblyResolutionTests.cs index 780b689d78..1cad3bfabc 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssemblyResolutionTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssemblyResolutionTests.cs @@ -6,17 +6,13 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class AssemblyResolutionTests : AcceptanceTestBase +[TestClass] +public sealed class AssemblyResolutionTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public AssemblyResolutionTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - + [TestMethod] public async Task AssemblyResolution_WhenNotSpecified_TestFails() { - TestHostResult testHostResult = await _testAssetFixture.TestHost.ExecuteAsync(); + TestHostResult testHostResult = await AssetFixture.TestHost.ExecuteAsync(); // Assert testHostResult.AssertExitCodeIs(2); @@ -24,10 +20,11 @@ public async Task AssemblyResolution_WhenNotSpecified_TestFails() testHostResult.AssertOutputContainsSummary(failed: 1, passed: 0, skipped: 0); } + [TestMethod] public async Task AssemblyResolution_WhenSpecified_TestSucceeds() { // Arrange - string runSettingsFilePath = Path.Combine(_testAssetFixture.TestHost.DirectoryName, ".runsettings"); + string runSettingsFilePath = Path.Combine(AssetFixture.TestHost.DirectoryName, ".runsettings"); File.WriteAllText(runSettingsFilePath, $""" @@ -35,14 +32,14 @@ public async Task AssemblyResolution_WhenSpecified_TestSucceeds() - + """); // Act - TestHostResult testHostResult = await _testAssetFixture.TestHost.ExecuteAsync($"--settings {runSettingsFilePath}"); + TestHostResult testHostResult = await AssetFixture.TestHost.ExecuteAsync($"--settings {runSettingsFilePath}"); // Assert testHostResult.AssertExitCodeIs(0); @@ -50,12 +47,11 @@ public async Task AssemblyResolution_WhenSpecified_TestSucceeds() testHostResult.AssertOutputDoesNotContain("System.IO.FileNotFoundException: Could not load file or assembly 'MSTest.Extensibility.Samples"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : IAsyncInitializable, IDisposable + public sealed class TestAssetFixture : ITestAssetFixture { public const string ProjectName = "AssemblyResolution.Main"; private const string TestProjectName = "AssemblyResolution.Test"; - private static readonly string TargetFramework = TargetFrameworks.NetCurrent.Arguments; + private static readonly string TargetFramework = TargetFrameworks.NetCurrent; private readonly TempDirectory _testAssetDirectory = new(); @@ -69,10 +65,10 @@ public void Dispose() MainDllFolder?.Dispose(); } - public async Task InitializeAsync(InitializationContext context) + public async Task InitializeAsync() { VSSolution solution = CreateTestAsset(); - DotnetMuxerResult result = await DotnetCli.RunAsync($"build -nodeReuse:false {solution.SolutionFile} -c Release", acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult result = await DotnetCli.RunAsync($"build -nodeReuse:false {solution.SolutionFile} -c Release", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.AreEqual(0, result.ExitCode); TestHost = TestHost.LocateFrom(solution.Projects.Skip(1).Single().FolderPath, TestProjectName, TargetFramework); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssemblyResolverTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssemblyResolverTests.cs index 993d5393b7..cf839e1f41 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssemblyResolverTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AssemblyResolverTests.cs @@ -7,17 +7,12 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class AssemblyResolverTests : AcceptanceTestBase +[TestClass] +public class AssemblyResolverTests : AcceptanceTestBase { private const string AssetName = "AssemblyResolverCrash"; - private readonly TestAssetFixture _testAssetFixture; - - // There's a bug in TAFX where we need to use it at least one time somewhere to use it inside the fixture self (AcceptanceFixture). - public AssemblyResolverTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture, - AcceptanceFixture globalFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; + [TestMethod] public async Task RunningTests_DoesNotHitResourceRecursionIssueAndDoesNotCrashTheRunner() { if (!OperatingSystem.IsWindows()) @@ -26,15 +21,14 @@ public async Task RunningTests_DoesNotHitResourceRecursionIssueAndDoesNotCrashTh return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, TargetFrameworks.NetFramework[0].Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, TargetFrameworks.NetFramework[0]); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertExitCodeIs(ExitCodes.Success); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public string TargetAssetPath => GetAssetPath(AssetName); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs index bab603e279..6bc078f8eb 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs @@ -6,17 +6,13 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class CancellationTests : AcceptanceTestBase +[TestClass] +public sealed class CancellationTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public CancellationTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - + [TestMethod] public async Task WhenCancelingTestContextTokenInAssemblyInit_MessageIsAsExpected() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { ["ASSEMBLYINIT_CANCEL"] = "1", @@ -28,9 +24,10 @@ public async Task WhenCancelingTestContextTokenInAssemblyInit_MessageIsAsExpecte testHostResult.AssertOutputContains("Failed!"); } + [TestMethod] public async Task WhenCancelingTestContextTokenInClassInit_MessageIsAsExpected() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { ["CLASSINIT_CANCEL"] = "1", @@ -42,9 +39,10 @@ public async Task WhenCancelingTestContextTokenInClassInit_MessageIsAsExpected() testHostResult.AssertOutputContains("Failed!"); } + [TestMethod] public async Task WhenCancelingTestContextTokenInTestInit_MessageIsAsExpected() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { ["TESTINIT_CANCEL"] = "1", @@ -56,9 +54,10 @@ public async Task WhenCancelingTestContextTokenInTestInit_MessageIsAsExpected() testHostResult.AssertOutputContains("Failed!"); } + [TestMethod] public async Task WhenCancelingTestContextTokenInTestCleanup_MessageIsAsExpected() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { ["TESTCLEANUP_CANCEL"] = "1", @@ -70,9 +69,10 @@ public async Task WhenCancelingTestContextTokenInTestCleanup_MessageIsAsExpected testHostResult.AssertOutputContains("Failed!"); } + [TestMethod] public async Task WhenCancelingTestContextTokenInTestMethod_MessageIsAsExpected() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { ["TESTMETHOD_CANCEL"] = "1", @@ -84,8 +84,7 @@ public async Task WhenCancelingTestContextTokenInTestMethod_MessageIsAsExpected( testHostResult.AssertOutputContains("Failed!"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string ProjectName = "TestCancellation"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ConfigurationSettingsTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ConfigurationSettingsTests.cs index 1ff51d33a8..8637871e8b 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ConfigurationSettingsTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ConfigurationSettingsTests.cs @@ -7,18 +7,14 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class ConfigurationSettingsTests : AcceptanceTestBase +[TestClass] +public sealed class ConfigurationSettingsTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public ConfigurationSettingsTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestConfigJson_AndRunSettingsHasMstest_Throws(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPathWithMSTestRunSettings, TestAssetFixture.ProjectNameWithMSTestRunSettings, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPathWithMSTestRunSettings, TestAssetFixture.ProjectNameWithMSTestRunSettings, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings"); // Assert @@ -26,10 +22,11 @@ public async Task TestConfigJson_AndRunSettingsHasMstest_Throws(string tfm) testHostResult.AssertStandardErrorContains("Both '.runsettings' and '.testconfig.json' files have been detected. Please select only one of these test configuration files."); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestConfigJson_AndRunSettingsHasMstestv2_Throws(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPathWithMSTestV2RunSettings, TestAssetFixture.ProjectNameWithMSTestV2RunSettings, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPathWithMSTestV2RunSettings, TestAssetFixture.ProjectNameWithMSTestV2RunSettings, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings"); // Assert @@ -37,29 +34,32 @@ public async Task TestConfigJson_AndRunSettingsHasMstestv2_Throws(string tfm) testHostResult.AssertStandardErrorContains("Both '.runsettings' and '.testconfig.json' files have been detected. Please select only one of these test configuration files."); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestConfigJson_AndRunSettingsWithoutMstest_OverrideRunConfigration(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings"); // Assert testHostResult.AssertExitCodeIs(ExitCodes.Success); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestConfigJson_WithoutRunSettings_BuildSuccess(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); // Assert testHostResult.AssertExitCodeIs(ExitCodes.Success); } + [TestMethod] public async Task TestWithConfigFromCommandLineWithMapInconclusiveToFailedIsTrue() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--config-file dummyconfigfile_map.json", environmentVariables: new() { ["TestWithConfigFromCommandLine"] = "true", @@ -69,9 +69,10 @@ public async Task TestWithConfigFromCommandLineWithMapInconclusiveToFailedIsTrue testHostResult.AssertOutputContainsSummary(failed: 1, passed: 1, skipped: 0); } + [TestMethod] public async Task TestWithConfigFromCommandLineWithMapInconclusiveToFailedIsFalse() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--config-file dummyconfigfile_doNotMap.json", environmentVariables: new() { ["TestWithConfigFromCommandLine"] = "true", @@ -81,9 +82,10 @@ public async Task TestWithConfigFromCommandLineWithMapInconclusiveToFailedIsFals testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 1); } + [TestMethod] public async Task TestWithConfigFromCommandLineWithNonExistingFile() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--config-file dummyconfigfile_not_existing_file.json", environmentVariables: new() { ["TestWithConfigFromCommandLine"] = "true", @@ -93,8 +95,7 @@ public async Task TestWithConfigFromCommandLineWithNonExistingFile() testHostResult.AssertStandardErrorContains("dummyconfigfile_not_existing_file.json"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string ProjectName = "ConfigurationSettings"; public const string ProjectNameWithMSTestRunSettings = "ConfigurationMSTestSettings"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/DataSourceTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/DataSourceTests.cs index 375dedad5f..f3ea941e28 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/DataSourceTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/DataSourceTests.cs @@ -7,8 +7,8 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class DataSourceTests : AcceptanceTestBase +[TestClass] +public sealed class DataSourceTests : AcceptanceTestBase { private const string SourceCode = """ #file DataSourceTests.csproj @@ -83,11 +83,7 @@ public void MyTest() 1,1,1 """; - private readonly AcceptanceFixture _acceptanceFixture; - - public DataSourceTests(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - + [TestMethod] public async Task TestDataSourceFromAppConfig() { if (!OperatingSystem.IsWindows()) @@ -105,7 +101,7 @@ public async Task TestDataSourceFromAppConfig() await DotnetCli.RunAsync( $"build {generator.TargetAssetPath} -c Release", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + AcceptanceFixture.NuGetGlobalPackagesFolder.Path, retryCount: 0); var testHost = TestHost.LocateFrom(generator.TargetAssetPath, "DataSourceTests", "net472"); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/DotnetTestCliTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/DotnetTestCliTests.cs index 3bed38780c..85a3cc1970 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/DotnetTestCliTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/DotnetTestCliTests.cs @@ -6,16 +6,13 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class DotnetTestCliTests : AcceptanceTestBase +[TestClass] +public class DotnetTestCliTests : AcceptanceTestBase { private const string AssetName = "MSTestProject"; - private readonly AcceptanceFixture _acceptanceFixture; - public DotnetTestCliTests(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildConfiguration))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrixTfmBuildConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] public async Task DotnetTest_Should_Execute_Tests(string tfm, BuildConfiguration buildConfiguration) { using TestAsset generator = await TestAsset.GenerateAssetAsync( @@ -28,9 +25,9 @@ public async Task DotnetTest_Should_Execute_Tests(string tfm, BuildConfiguration .PatchCodeWithReplace("$OutputType$", string.Empty) .PatchCodeWithReplace("$Extra$", string.Empty)); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test -m:1 -nodeReuse:false {generator.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test -m:1 -nodeReuse:false {generator.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); // There is whitespace difference in output in parent and public repo that depends on the version of the dotnet SDK used. - compilationResult.AssertOutputRegEx(@"Passed!\s+-\s+Failed:\s+0,\s+Passed:\s+1,\s+Skipped:\s+0,\s+Total:\s+1"); + compilationResult.AssertOutputMatchesRegex(@"Passed!\s+-\s+Failed:\s+0,\s+Passed:\s+1,\s+Skipped:\s+0,\s+Total:\s+1"); } } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs index a65b1d9827..ef0053229a 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs @@ -9,19 +9,13 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class GenericTestMethodTests : AcceptanceTestBase +[TestClass] +public class GenericTestMethodTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - // There's a bug in TAFX where we need to use it at least one time somewhere to use it inside the fixture self (AcceptanceFixture). - public GenericTestMethodTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture, - AcceptanceFixture globalFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - + [TestMethod] public async Task TestDifferentGenericMethodTestCases() { - var testHost = TestHost.LocateFrom(_testAssetFixture.GetAssetPath("GenericTestMethodTests"), "GenericTestMethodTests", TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.GetAssetPath("GenericTestMethodTests"), "GenericTestMethodTests", TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync(); @@ -75,8 +69,7 @@ at .+? """, RegexOptions.Singleline); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public override IEnumerable<(string ID, string Name, string Code)> GetAssetsToGenerate() { diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs index e64b0928f5..d43193af01 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/HelpInfoTests.cs @@ -7,21 +7,16 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class HelpInfoTests : AcceptanceTestBase +[TestClass] +public class HelpInfoTests : AcceptanceTestBase { private const string AssetName = "HelpInfo"; - private readonly TestAssetFixture _testAssetFixture; - - // There's a bug in TAFX where we need to use it at least one time somewhere to use it inside the fixture self (AcceptanceFixture). - public HelpInfoTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture, - AcceptanceFixture globalFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task Help_WhenMSTestExtensionRegistered_OutputHelpContentOfRegisteredExtension(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--help"); testHostResult.AssertExitCodeIs(ExitCodes.Success); @@ -89,10 +84,11 @@ Output verbosity when reporting tests. testHostResult.AssertOutputMatchesLines(wildcardMatchPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task Info_WhenMSTestExtensionRegistered_OutputInfoContentOfRegisteredExtension(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--info"); testHostResult.AssertExitCodeIs(ExitCodes.Success); @@ -124,8 +120,7 @@ public async Task Info_WhenMSTestExtensionRegistered_OutputInfoContentOfRegister testHostResult.AssertOutputContains(output); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public string TargetAssetPath => GetAssetPath(AssetName); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs index 40815c38f3..74d6740d73 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs @@ -6,17 +6,13 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class IgnoreTests : AcceptanceTestBase +[TestClass] +public sealed class IgnoreTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public IgnoreTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - + [TestMethod] public async Task ClassCleanup_Inheritance_WhenClassIsSkipped() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings --filter ClassName!~TestClassWithAssemblyInitialize"); // Assert @@ -26,9 +22,10 @@ public async Task ClassCleanup_Inheritance_WhenClassIsSkipped() testHostResult.AssertOutputContains("SubClass.Method"); } + [TestMethod] public async Task WhenAllTestsAreIgnored_AssemblyInitializeAndCleanupAreSkipped() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings --filter TestClassWithAssemblyInitialize"); // Assert @@ -38,8 +35,7 @@ public async Task WhenAllTestsAreIgnored_AssemblyInitializeAndCleanupAreSkipped( testHostResult.AssertOutputDoesNotContain("AssemblyCleanup"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string ProjectName = "TestIgnore"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs index 46a0a47ec4..2a78f7726f 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs @@ -8,8 +8,8 @@ namespace MSTest.Acceptance.IntegrationTests; -// [TestGroup] -public class InitializeAndCleanupTimeoutTests : AcceptanceTestBase +[TestClass] +public class InitializeAndCleanupTimeoutTests : AcceptanceTestBase { private static readonly Dictionary InfoByKind = new() { @@ -23,151 +23,175 @@ public class InitializeAndCleanupTimeoutTests : AcceptanceTestBase ["testCleanup"] = ("TestClass.TestCleanupMethod", "Test cleanup", "TESTCLEANUP", "TestCleanupTimeout"), }; - private readonly TestAssetFixture _testAssetFixture; - - // There's a bug in TAFX where we need to use it at least one time somewhere to use it inside the fixture self (AcceptanceFixture). - public InitializeAndCleanupTimeoutTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture, - AcceptanceFixture globalFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task AssemblyInit_WhenTestContextCanceled_AssemblyInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestWasCanceledAsync(_testAssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, + => await RunAndAssertTestWasCanceledAsync(AssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, tfm, "TESTCONTEXT_CANCEL_", "assemblyInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task AssemblyInit_WhenTimeoutExpires_AssemblyInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, "LONG_WAIT_", "assemblyInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task AssemblyInit_WhenTimeoutExpiresAndTestContextTokenIsUsed_AssemblyInitializeExits(string tfm) - => await RunAndAssertTestTimedOutAsync(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, "TIMEOUT_", "assemblyInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassInit_WhenTestContextCanceled_ClassInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestWasCanceledAsync(_testAssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, tfm, + => await RunAndAssertTestWasCanceledAsync(AssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, tfm, "TESTCONTEXT_CANCEL_", "classInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassInit_WhenTimeoutExpires_ClassInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, "LONG_WAIT_", "classInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassInit_WhenTimeoutExpiresAndTestContextTokenIsUsed_ClassInitializeExits(string tfm) - => await RunAndAssertTestTimedOutAsync(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, "TIMEOUT_", "classInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassInitBase_WhenTestContextCanceled_ClassInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestWasCanceledAsync(_testAssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, tfm, + => await RunAndAssertTestWasCanceledAsync(AssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, tfm, "TESTCONTEXT_CANCEL_", "baseClassInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassInitBase_WhenTimeoutExpires_ClassInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, "LONG_WAIT_", "baseClassInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassInitBase_WhenTimeoutExpiresAndTestContextTokenIsUsed_ClassInitializeExits(string tfm) - => await RunAndAssertTestTimedOutAsync(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, "TIMEOUT_", "baseClassInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task AssemblyInitialize_WhenTimeoutExpires_FromRunSettings_AssemblyInitializeIsCanceled(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "assemblyInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassInitialize_WhenTimeoutExpires_FromRunSettings_ClassInitializeIsCanceled(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "classInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task BaseClassInitialize_WhenTimeoutExpires_FromRunSettings_ClassInitializeIsCanceled(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "baseClassInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task AssemblyInitialize_WhenTimeoutExpires_AssemblyInitializeIsCanceled_AttributeTakesPrecedence(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "assemblyInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassInitialize_WhenTimeoutExpires_ClassInitializeIsCanceled_AttributeTakesPrecedence(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "classInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task BaseClassInitialize_WhenTimeoutExpires_ClassInitializeIsCanceled_AttributeTakesPrecedence(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "baseClassInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassCleanupBase_WhenTimeoutExpires_ClassCleanupTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, "LONG_WAIT_", "baseClassCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassCleanup_WhenTimeoutExpires_ClassCleanupTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, "LONG_WAIT_", "classCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassCleanup_WhenTimeoutExpires_FromRunSettings_ClassCleanupIsCanceled(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "classCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task BaseClassCleanup_WhenTimeoutExpires_FromRunSettings_ClassCleanupIsCanceled(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "baseClassCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ClassCleanup_WhenTimeoutExpires_ClassCleanupIsCanceled_AttributeTakesPrecedence(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "classCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task BaseClassCleanup_WhenTimeoutExpires_ClassCleanupIsCanceled_AttributeTakesPrecedence(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "baseClassCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task AssemblyCleanup_WhenTimeoutExpires_AssemblyCleanupTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, "LONG_WAIT_", "assemblyCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task AssemblyCleanup_WhenTimeoutExpires_FromRunSettings_AssemblyCleanupIsCanceled(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "assemblyCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task AssemblyCleanup_WhenTimeoutExpires_AssemblyCleanupIsCanceled_AttributeTakesPrecedence(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "assemblyCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestInitialize_WhenTimeoutExpires_TestInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, "LONG_WAIT_", "testInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestInitialize_WhenTimeoutExpires_FromRunSettings_TestInitializeIsCanceled(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "testInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestInitialize_WhenTimeoutExpires_TestInitializeIsCanceled_AttributeTakesPrecedence(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "testInit"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestCleanup_WhenTimeoutExpires_TestCleanupTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, "LONG_WAIT_", "testCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestCleanup_WhenTimeoutExpires_FromRunSettings_TestCleanupIsCanceled(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "testCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestCleanup_WhenTimeoutExpires_TestCleanupIsCanceled_AttributeTakesPrecedence(string tfm) => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "testCleanup"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenAssemblyInitTimeoutExpires_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["TASKDELAY_ASSEMBLYINIT"] = "1" }); @@ -178,10 +202,11 @@ public async Task CooperativeCancellation_WhenAssemblyInitTimeoutExpires_StepThr testHostResult.AssertOutputDoesNotContain("AssemblyInit completed"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenAssemblyCleanupTimeoutExpires_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["TASKDELAY_ASSEMBLYCLEANUP"] = "1" }); @@ -192,10 +217,11 @@ public async Task CooperativeCancellation_WhenAssemblyCleanupTimeoutExpires_Step testHostResult.AssertOutputDoesNotContain("AssemblyCleanup completed"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenClassInitTimeoutExpires_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["TASKDELAY_CLASSINIT"] = "1" }); @@ -206,10 +232,11 @@ public async Task CooperativeCancellation_WhenClassInitTimeoutExpires_StepThrows testHostResult.AssertOutputDoesNotContain("ClassInit completed"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenClassCleanupTimeoutExpires_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["TASKDELAY_CLASSCLEANUP"] = "1" }); @@ -220,10 +247,11 @@ public async Task CooperativeCancellation_WhenClassCleanupTimeoutExpires_StepThr testHostResult.AssertOutputDoesNotContain("ClassCleanup completed"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenTestInitTimeoutExpires_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["TASKDELAY_TESTINIT"] = "1" }); @@ -233,10 +261,11 @@ public async Task CooperativeCancellation_WhenTestInitTimeoutExpires_StepThrows( testHostResult.AssertOutputDoesNotContain("TestInit completed"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenTestCleanupTimeoutExpires_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["TASKDELAY_TESTCLEANUP"] = "1" }); @@ -246,10 +275,11 @@ public async Task CooperativeCancellation_WhenTestCleanupTimeoutExpires_StepThro testHostResult.AssertOutputDoesNotContain("TestCleanup completed"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenTestMethodTimeoutExpires_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["TASKDELAY_TESTMETHOD"] = "1" }); @@ -259,10 +289,11 @@ public async Task CooperativeCancellation_WhenTestMethodTimeoutExpires_StepThrow testHostResult.AssertOutputDoesNotContain("TestMethod completed"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenAssemblyInitTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["CHECKTOKEN_ASSEMBLYINIT"] = "1" }); @@ -273,10 +304,11 @@ public async Task CooperativeCancellation_WhenAssemblyInitTimeoutExpiresAndUserC testHostResult.AssertOutputDoesNotContain("AssemblyInit completed"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenAssemblyCleanupTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["CHECKTOKEN_ASSEMBLYCLEANUP"] = "1" }); @@ -287,10 +319,11 @@ public async Task CooperativeCancellation_WhenAssemblyCleanupTimeoutExpiresAndUs testHostResult.AssertOutputDoesNotContain("AssemblyCleanup completed"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenClassInitTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["CHECKTOKEN_CLASSINIT"] = "1" }); @@ -301,10 +334,11 @@ public async Task CooperativeCancellation_WhenClassInitTimeoutExpiresAndUserChec testHostResult.AssertOutputDoesNotContain("ClassInit completed"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenClassCleanupTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["CHECKTOKEN_CLASSCLEANUP"] = "1" }); @@ -315,10 +349,11 @@ public async Task CooperativeCancellation_WhenClassCleanupTimeoutExpiresAndUserC testHostResult.AssertOutputDoesNotContain("ClassCleanup completed"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenTestInitTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["CHECKTOKEN_TESTINIT"] = "1" }); @@ -328,10 +363,11 @@ public async Task CooperativeCancellation_WhenTestInitTimeoutExpiresAndUserCheck testHostResult.AssertOutputContains("Test initialize method 'TestClass.TestInit' timed out"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenTestCleanupTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["CHECKTOKEN_TESTCLEANUP"] = "1" }); @@ -341,10 +377,11 @@ public async Task CooperativeCancellation_WhenTestCleanupTimeoutExpiresAndUserCh testHostResult.AssertOutputContains("Test cleanup method 'TestClass.TestCleanup' timed out"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenTestMethodTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--settings my.runsettings", new() { ["CHECKTOKEN_TESTMETHOD"] = "1" }); @@ -385,8 +422,8 @@ private async Task RunAndAssertWithRunSettingsAsync(string tfm, int timeoutValue timeoutValue = assertAttributePrecedence ? 1000 : timeoutValue; TestHost testHost = assertAttributePrecedence - ? TestHost.LocateFrom(_testAssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm) - : TestHost.LocateFrom(_testAssetFixture.CodeWithNoTimeoutAssetPath, TestAssetFixture.CodeWithNoTimeout, tfm); + ? TestHost.LocateFrom(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm) + : TestHost.LocateFrom(AssetFixture.CodeWithNoTimeoutAssetPath, TestAssetFixture.CodeWithNoTimeout, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, $"{Guid.NewGuid():N}.runsettings"); File.WriteAllText(runSettingsFilePath, runSettings); @@ -402,8 +439,7 @@ private async Task RunAndAssertWithRunSettingsAsync(string tfm, int timeoutValue testHostResult.AssertOutputContains($"{InfoByKind[entryKind].Prefix} method '{InfoByKind[entryKind].MethodFullName}' timed out after {timeoutValue}ms"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string CodeWithOneSecTimeout = nameof(CodeWithOneSecTimeout); public const string CodeWithSixtySecTimeout = nameof(CodeWithSixtySecTimeout); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MSBuildRunnerTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MSBuildRunnerTests.cs index 8cb7d672e8..770b7eb021 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MSBuildRunnerTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MSBuildRunnerTests.cs @@ -6,19 +6,15 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class MSBuildRunnerTests : AcceptanceTestBase +[TestClass] +public class MSBuildRunnerTests : AcceptanceTestBase { private const string AssetName = "MSTestProject"; private const string DotnetTestVerb = "test"; - private readonly AcceptanceFixture _acceptanceFixture; - public MSBuildRunnerTests(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - - internal static IEnumerable> GetBuildMatrix() + internal static IEnumerable<(string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm, string Command)> GetBuildMatrix() { - foreach (TestArgumentsEntry<(string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm)> entry in GetBuildMatrixSingleAndMultiTfmBuildConfiguration()) + foreach ((string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm) entry in GetBuildMatrixSingleAndMultiTfmBuildConfiguration()) { foreach (string command in new string[] { @@ -26,13 +22,13 @@ public MSBuildRunnerTests(ITestExecutionContext testExecutionContext, Acceptance DotnetTestVerb, }) { - yield return new TestArgumentsEntry<(string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm, string Command)>( - (entry.Arguments.SingleTfmOrMultiTfm, entry.Arguments.BuildConfiguration, entry.Arguments.IsMultiTfm, command), $"{(entry.Arguments.IsMultiTfm ? "multitfm" : entry.Arguments.SingleTfmOrMultiTfm)},{entry.Arguments.BuildConfiguration},{command}"); + yield return new(entry.SingleTfmOrMultiTfm, entry.BuildConfiguration, entry.IsMultiTfm, command); } } } - [ArgumentsProvider(nameof(GetBuildMatrix))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrix), DynamicDataSourceType.Method)] public async Task MSBuildTestTarget_SingleAndMultiTfm_Should_Run_Solution_Tests(string singleTfmOrMultiTfm, BuildConfiguration buildConfiguration, bool isMultiTfm, string command) { // Get the template project @@ -68,24 +64,24 @@ public async Task MSBuildTestTarget_SingleAndMultiTfm_Should_Run_Solution_Tests( } // Build the solution - DotnetMuxerResult restoreResult = await DotnetCli.RunAsync($"restore -m:1 -nodeReuse:false {solution.SolutionFile} --configfile {nugetFile}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); - restoreResult.AssertOutputNotContains("An approximate best match of"); - DotnetMuxerResult testResult = await DotnetCli.RunAsync($"{command} -m:1 -nodeReuse:false {solution.SolutionFile}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult restoreResult = await DotnetCli.RunAsync($"restore -m:1 -nodeReuse:false {solution.SolutionFile} --configfile {nugetFile}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); + restoreResult.AssertOutputDoesNotContain("An approximate best match of"); + DotnetMuxerResult testResult = await DotnetCli.RunAsync($"{command} -m:1 -nodeReuse:false {solution.SolutionFile}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); if (isMultiTfm) { foreach (string tfm in singleTfmOrMultiTfm.Split(';')) { - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject0\..*' \[{tfm}\|x64\]"); - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject1\..*' \[{tfm}\|x64\]"); - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject2\..*' \[{tfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject0\..*' \[{tfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject1\..*' \[{tfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject2\..*' \[{tfm}\|x64\]"); } } else { - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject0\..*' \[{singleTfmOrMultiTfm}\|x64\]"); - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject1\..*' \[{singleTfmOrMultiTfm}\|x64\]"); - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject2\..*' \[{singleTfmOrMultiTfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject0\..*' \[{singleTfmOrMultiTfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject1\..*' \[{singleTfmOrMultiTfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject2\..*' \[{singleTfmOrMultiTfm}\|x64\]"); } } } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MSTest.Acceptance.IntegrationTests.csproj b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MSTest.Acceptance.IntegrationTests.csproj index 06e198a550..b204fdef59 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MSTest.Acceptance.IntegrationTests.csproj +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MSTest.Acceptance.IntegrationTests.csproj @@ -3,6 +3,7 @@ $(NetCurrent) false + true $(DefineConstants);SKIP_INTERMEDIATE_TARGET_FRAMEWORKS Exe true diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs index 9c5f2fe087..fe3753fae4 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs @@ -10,19 +10,16 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class MaxFailedTestsExtensionTests : AcceptanceTestBase +[TestClass] +public sealed class MaxFailedTestsExtensionTests : AcceptanceTestBase { private const string AssetName = nameof(MaxFailedTestsExtensionTests); - private readonly TestAssetFixture _testAssetFixture; - - public MaxFailedTestsExtensionTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task SimpleMaxFailedTestsScenario(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--maximum-failed-tests 3"); testHostResult.AssertExitCodeIs(ExitCodes.TestExecutionStoppedForMaxFailedTests); @@ -42,8 +39,7 @@ public async Task SimpleMaxFailedTestsScenario(string tfm) Assert.AreEqual(12, total); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string Sources = """ #file MaxFailedTestsExtensionTests.csproj diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs index 59dcb83da2..fb0cf271af 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs @@ -8,8 +8,8 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class NativeAotTests : AcceptanceTestBase +[TestClass] +public class NativeAotTests : AcceptanceTestBase { private const string SourceCode = """ #file NativeAotTests.csproj @@ -84,11 +84,7 @@ public void TestMethod3(int a, int b) } """; - private readonly AcceptanceFixture _acceptanceFixture; - - public NativeAotTests(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - + [TestMethod] public async Task NativeAotTests_WillRunWithExitCodeZero() { // The hosted AzDO agents for Mac OS don't have the required tooling for us to test Native AOT. @@ -108,23 +104,23 @@ await RetryHelper.RetryAsync( SourceCode .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$TargetFramework$", TargetFrameworks.NetCurrent.Arguments) + .PatchCodeWithReplace("$TargetFramework$", TargetFrameworks.NetCurrent) .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion) .PatchCodeWithReplace("$MSTestEngineVersion$", MSTestEngineVersion), addPublicFeeds: true); await DotnetCli.RunAsync( $"restore -m:1 -nodeReuse:false {generator.TargetAssetPath} -r {RID}", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + AcceptanceFixture.NuGetGlobalPackagesFolder.Path, retryCount: 0); DotnetMuxerResult compilationResult = await DotnetCli.RunAsync( $"publish -m:1 -nodeReuse:false {generator.TargetAssetPath} -r {RID}", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + AcceptanceFixture.NuGetGlobalPackagesFolder.Path, timeoutInSeconds: 90, retryCount: 0); compilationResult.AssertOutputContains("Generating native code"); - var testHost = TestHost.LocateFrom(generator.TargetAssetPath, "NativeAotTests", TargetFrameworks.NetCurrent.Arguments, RID, Verb.publish); + var testHost = TestHost.LocateFrom(generator.TargetAssetPath, "NativeAotTests", TargetFrameworks.NetCurrent, RID, Verb.publish); TestHostResult result = await testHost.ExecuteAsync(); result.AssertExitCodeIs(0); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ParameterizedTestTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ParameterizedTestTests.cs index 74583168d5..dc22dbb698 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ParameterizedTestTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ParameterizedTestTests.cs @@ -7,45 +7,45 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class ParameterizedTestTests : AcceptanceTestBase +[TestClass] +public class ParameterizedTestTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; private const string DynamicDataAssetName = "DynamicData"; private const string DataSourceAssetName = "DataSource"; - // There's a bug in TAFX where we need to use it at least one time somewhere to use it inside the fixture self (AcceptanceFixture). - public ParameterizedTestTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture, - AcceptanceFixture globalFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task SendingEmptyDataToDynamicDataTest_WithSettingConsiderEmptyDataSourceAsInconclusive_Passes(string currentTfm) => await RunTestsAsync(currentTfm, DynamicDataAssetName, true); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task SendingEmptyDataToDataSourceTest_WithSettingConsiderEmptyDataSourceAsInconclusive_Passes(string currentTfm) => await RunTestsAsync(currentTfm, DataSourceAssetName, true); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task SendingEmptyDataToDynamicDataTest_WithSettingConsiderEmptyDataSourceAsInconclusiveToFalse_Fails(string currentTfm) => await RunTestsAsync(currentTfm, DynamicDataAssetName, false); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task SendingEmptyDataToDataSourceTest_WithSettingConsiderEmptyDataSourceAsInconclusiveToFalse_Fails(string currentTfm) => await RunTestsAsync(currentTfm, DataSourceAssetName, false); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task SendingEmptyDataToDynamicDataTest_WithoutSettingConsiderEmptyDataSourceAsInconclusive_Fails(string currentTfm) => await RunTestsAsync(currentTfm, DynamicDataAssetName, null); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task SendingEmptyDataToDataSourceTest_WithoutSettingConsiderEmptyDataSourceAsInconclusive_Fails(string currentTfm) => await RunTestsAsync(currentTfm, DataSourceAssetName, null); private async Task RunTestsAsync(string currentTfm, string assetName, bool? isEmptyDataInconclusive) { - var testHost = TestHost.LocateFrom(_testAssetFixture.GetAssetPath(assetName), assetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.GetAssetPath(assetName), assetName, currentTfm); TestHostResult testHostResult = await testHost.ExecuteAsync(SetupRunSettingsAndGetArgs(isEmptyDataInconclusive)); @@ -79,8 +79,7 @@ private async Task RunTestsAsync(string currentTfm, string assetName, bool? isEm } } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public string DynamicDataTargetAssetPath => GetAssetPath(DynamicDataAssetName); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs index f2d4e27817..8234276d1a 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs @@ -2,11 +2,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Diagnostics; +using System.Reflection; using Microsoft.Testing.Extensions; -using Microsoft.Testing.Internal.Framework.Configurations; -using MSTest.Acceptance.IntegrationTests; +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] +[assembly: ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] // Opt-out telemetry Environment.SetEnvironmentVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1"); @@ -16,9 +17,7 @@ ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework( - new TestFrameworkConfiguration(Debugger.IsAttached ? 1 : Environment.ProcessorCount), - new SourceGeneratedTestNodesBuilder()); +builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]); #if ENABLE_CODECOVERAGE builder.AddCodeCoverageProvider(); #endif diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Properties/launchSettings.json b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Properties/launchSettings.json index f422322857..cdc273e704 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Properties/launchSettings.json +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "MSTest.Acceptance.IntegrationTests": { "commandName": "Project", - "commandLineArgs": "--treenode-filter /*/*/*/**" + "commandLineArgs": "" } } } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/PublishAotNonNativeTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/PublishAotNonNativeTests.cs index 750930798b..f26805a69a 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/PublishAotNonNativeTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/PublishAotNonNativeTests.cs @@ -10,23 +10,21 @@ namespace MSTest.Acceptance.IntegrationTests; /// When PublishAOT=true is set on a project, it will set IsDynamicCodeSupported to false, but the code will still run as managed /// and VSTest is still able to find tests in the dll. /// -[TestGroup] -public sealed class PublishAotNonNativeTests : AcceptanceTestBase +[TestClass] +public sealed class PublishAotNonNativeTests : AcceptanceTestBase { private const string AssetName = "PublishAotNonNative"; - public PublishAotNonNativeTests(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - + [TestMethod] public async Task RunTests_ThatEnablePublishAOT_ButDontBuildToNative() { using TestAsset generator = await TestAsset.GenerateAssetAsync( - AssetName, - SourceCode - .PatchCodeWithReplace("$TargetFramework$", $"{TargetFrameworks.NetCurrent.Arguments}") - .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); + AssetName, + SourceCode + .PatchCodeWithReplace("$TargetFramework$", $"{TargetFrameworks.NetCurrent}") + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test -c Debug {generator.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test -c Debug {generator.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); // In the real-world issue, access to path C:\Program Files\dotnet\ is denied, but we run this from a local .dotnet folder, where we have write access. // So instead of relying on the test run failing because of AccessDenied, we check the output, and see where TestResults were placed. @@ -80,6 +78,4 @@ public void TestMethod1() } } """; - - private readonly AcceptanceFixture _acceptanceFixture; } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunnerTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunnerTests.cs index 38255a5b64..70bb55ddc9 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunnerTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunnerTests.cs @@ -5,21 +5,17 @@ using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using SL = Microsoft.Build.Logging.StructuredLogger; using SystemTask = System.Threading.Tasks.Task; namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class RunnerTests : AcceptanceTestBase +[TestClass] +public class RunnerTests : AcceptanceTestBase { private const string AssetName = "MSTestProject"; - private readonly AcceptanceFixture _acceptanceFixture; - public RunnerTests(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildVerbConfiguration))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrixTfmBuildVerbConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] public async SystemTask EnableMSTestRunner_True_Will_Run_Standalone(string tfm, BuildConfiguration buildConfiguration, Verb verb) { using TestAsset generator = await TestAsset.GenerateAssetAsync( @@ -34,22 +30,22 @@ public async SystemTask EnableMSTestRunner_True_Will_Run_Standalone(string tfm, string binlogFile = Path.Combine(generator.TargetAssetPath, "msbuild.binlog"); DotnetMuxerResult compilationResult = await DotnetCli.RunAsync( $"restore -m:1 -nodeReuse:false {generator.TargetAssetPath} -r {RID}", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + AcceptanceFixture.NuGetGlobalPackagesFolder.Path); compilationResult = await DotnetCli.RunAsync( $"{verb} -m:1 -nodeReuse:false {generator.TargetAssetPath} -c {buildConfiguration} -bl:{binlogFile} -r {RID}", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + AcceptanceFixture.NuGetGlobalPackagesFolder.Path); - SL.Build binLog = Serialization.Read(binlogFile); - Assert.IsNotEmpty(binLog.FindChildrenRecursive() - .Where(x => x.Title.Contains("ProjectCapability")) - .Where(x => x.Children.Any(c => ((Item)c).Name == "TestingPlatformServer"))); + Build binLog = Serialization.Read(binlogFile); + Assert.AreNotEqual(0, binLog.FindChildrenRecursive() + .Count(x => x.Title.Contains("ProjectCapability") && x.Children.Any(c => ((Item)c).Name == "TestingPlatformServer"))); var testHost = TestHost.LocateFrom(generator.TargetAssetPath, AssetName, tfm, buildConfiguration: buildConfiguration, verb: verb); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 0); } - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildVerbConfiguration))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrixTfmBuildVerbConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] public async SystemTask EnableMSTestRunner_True_WithCustomEntryPoint_Will_Run_Standalone(string tfm, BuildConfiguration buildConfiguration, Verb verb) { using TestAsset generator = await TestAsset.GenerateAssetAsync( @@ -75,16 +71,17 @@ public async SystemTask EnableMSTestRunner_True_WithCustomEntryPoint_Will_Run_St preview """)); string binlogFile = Path.Combine(generator.TargetAssetPath, "msbuild.binlog"); - await DotnetCli.RunAsync($"restore -m:1 -nodeReuse:false {generator.TargetAssetPath} -r {RID}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + await DotnetCli.RunAsync($"restore -m:1 -nodeReuse:false {generator.TargetAssetPath} -r {RID}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); await DotnetCli.RunAsync( $"{verb} -m:1 -nodeReuse:false {generator.TargetAssetPath} -c {buildConfiguration} -bl:{binlogFile} -r {RID}", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + AcceptanceFixture.NuGetGlobalPackagesFolder.Path); var testHost = TestHost.LocateFrom(generator.TargetAssetPath, AssetName, tfm, buildConfiguration: buildConfiguration, verb: verb); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 0); } - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildVerbConfiguration))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrixTfmBuildVerbConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] public async SystemTask EnableMSTestRunner_False_Will_Run_Empty_Program_EntryPoint_From_Tpv2_SDK(string tfm, BuildConfiguration buildConfiguration, Verb verb) { using TestAsset generator = await TestAsset.GenerateAssetAsync( @@ -97,17 +94,17 @@ public async SystemTask EnableMSTestRunner_False_Will_Run_Empty_Program_EntryPoi .PatchCodeWithReplace("$OutputType$", "Exe") .PatchCodeWithReplace("$Extra$", string.Empty)); string binlogFile = Path.Combine(generator.TargetAssetPath, "msbuild.binlog"); - await DotnetCli.RunAsync($"restore -m:1 -nodeReuse:false {generator.TargetAssetPath} -r {RID}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + await DotnetCli.RunAsync($"restore -m:1 -nodeReuse:false {generator.TargetAssetPath} -r {RID}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); try { - await DotnetCli.RunAsync($"{verb} -m:1 -nodeReuse:false {generator.TargetAssetPath} -c {buildConfiguration} -bl:{binlogFile} -r {RID}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + await DotnetCli.RunAsync($"{verb} -m:1 -nodeReuse:false {generator.TargetAssetPath} -c {buildConfiguration} -bl:{binlogFile} -r {RID}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); var testHost = TestHost.LocateFrom(generator.TargetAssetPath, AssetName, tfm, buildConfiguration: buildConfiguration, verb: verb); TestHostResult testHostResult = await testHost.ExecuteAsync(); Assert.AreEqual(string.Empty, testHostResult.StandardOutput); } catch (Exception ex) { - if (TargetFrameworks.NetFramework.Any(x => x.Arguments == tfm)) + if (TargetFrameworks.NetFramework.Any(x => x == tfm)) { Assert.IsTrue(ex.Message.Contains("Program does not contain a static 'Main' method suitable for an entry point"), ex.Message); @@ -117,7 +114,8 @@ public async SystemTask EnableMSTestRunner_False_Will_Run_Empty_Program_EntryPoi } } - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildVerbConfiguration))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrixTfmBuildVerbConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] public async SystemTask EnableMSTestRunner_False_Wont_Flow_TestingPlatformServer_Capability(string tfm, BuildConfiguration buildConfiguration, Verb verb) { using TestAsset generator = await TestAsset.GenerateAssetAsync( @@ -131,12 +129,11 @@ public async SystemTask EnableMSTestRunner_False_Wont_Flow_TestingPlatformServer .PatchCodeWithReplace("$Extra$", string.Empty)); string binlogFile = Path.Combine(generator.TargetAssetPath, "msbuild.binlog"); - await DotnetCli.RunAsync($"restore -m:1 -nodeReuse:false {generator.TargetAssetPath} -r {RID}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); - await DotnetCli.RunAsync($"{verb} -bl:{binlogFile} -m:1 -nodeReuse:false {generator.TargetAssetPath} -c {buildConfiguration} -r {RID} ", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + await DotnetCli.RunAsync($"restore -m:1 -nodeReuse:false {generator.TargetAssetPath} -r {RID}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); + await DotnetCli.RunAsync($"{verb} -bl:{binlogFile} -m:1 -nodeReuse:false {generator.TargetAssetPath} -c {buildConfiguration} -r {RID} ", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); - SL.Build binLog = Serialization.Read(binlogFile); - Assert.IsEmpty(binLog.FindChildrenRecursive() - .Where(x => x.Title.Contains("ProjectCapability")) - .Where(x => x.Children.Any(c => ((Item)c).Name == "TestingPlatformServer"))); + Build binLog = Serialization.Read(binlogFile); + Assert.IsFalse(binLog.FindChildrenRecursive() + .Any(x => x.Title.Contains("ProjectCapability") && x.Children.Any(c => ((Item)c).Name == "TestingPlatformServer"))); } } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs index d7d87424a3..9bdbb88338 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs @@ -10,50 +10,40 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class RunSettingsTests : AcceptanceTestBase +[TestClass] +public sealed class RunSettingsTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public RunSettingsTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - internal static IEnumerable> TfmList() - { - yield return TargetFrameworks.NetCurrent; - yield return TargetFrameworks.NetFramework.First(); - } - - internal static IEnumerable> LocalizationTestCases() + internal static IEnumerable<(string? TestingPlatformUILanguage, string? DotnetCLILanguage, string? VSLang, string ExpectedLocale)> LocalizationTestCases() { // Show that TestingPlatformUILanguage is respected. - yield return new TestArgumentsEntry<(string?, string?, string?, string)>(("fr-FR", null, null, "fr-FR"), "TestingPlatformUILanguage: fr-FR, expected: fr-FR"); + yield return new("fr-FR", null, null, "fr-FR"); // Show that TestingPlatformUILanguage takes precedence over DotnetCLILanguage. - yield return new TestArgumentsEntry<(string?, string?, string?, string)>(("fr-FR", "it-IT", null, "fr-FR"), "TestingPlatformUILanguage: fr-FR, CLI: it-IT, expected: fr-FR"); + yield return new("fr-FR", "it-IT", null, "fr-FR"); // Show that DotnetCLILanguage is respected. - yield return new TestArgumentsEntry<(string?, string?, string?, string)>((null, "it-IT", null, "it-IT"), "CLI: it-IT, expected: it-IT"); + yield return new(null, "it-IT", null, "it-IT"); // Show that DotnetCLILanguage takes precedence over VSLang. - yield return new TestArgumentsEntry<(string?, string?, string?, string)>((null, "it-IT", "fr-FR", "it-IT"), "CLI: it-IT, VSLang: fr-FR, expected: it-IT"); + yield return new(null, "it-IT", "fr-FR", "it-IT"); // Show that VSLang is respected. - yield return new TestArgumentsEntry<(string?, string?, string?, string)>((null, null, "it-IT", "it-IT"), "VSLang: it-IT, expected: it-IT"); + yield return new(null, null, "it-IT", "it-IT"); // Show that TestingPlatformUILanguage takes precedence over everything. - yield return new TestArgumentsEntry<(string?, string?, string?, string)>(("fr-FR", "it-IT", "it-IT", "fr-FR"), "TestingPlatformUILanguage: fr-FR, CLI: it-IT, VSLang: it-IT, expected: fr-FR"); + yield return new("fr-FR", "it-IT", "it-IT", "fr-FR"); } - [ArgumentsProvider(nameof(TfmList))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task UnsupportedRunSettingsEntriesAreFlagged(string tfm) { - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && tfm == TargetFrameworks.NetFramework.First().Arguments) + if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && tfm == TargetFrameworks.NetFramework.First()) { return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings"); // Assert @@ -71,21 +61,22 @@ public async Task UnsupportedRunSettingsEntriesAreFlagged(string tfm) testHostResult.AssertOutputContains("Runsettings attribute 'TreatNoTestsAsError' is not supported by Microsoft.Testing.Platform and will be ignored"); } - [ArgumentsProvider(nameof(LocalizationTestCases))] - public async Task UnsupportedRunSettingsEntriesAreFlagged_Localization((string? TestingPlatformUILanguage, string? DotnetCLILanguage, string? VSLang, string? ExpectedLocale) testArgument) + [TestMethod] + [DynamicData(nameof(LocalizationTestCases), DynamicDataSourceType.Method)] + public async Task UnsupportedRunSettingsEntriesAreFlagged_Localization(string? testingPlatformUILanguage, string? dotnetCLILanguage, string? vsLang, string? expectedLocale) { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings", environmentVariables: new() { - ["TESTINGPLATFORM_UI_LANGUAGE"] = testArgument.TestingPlatformUILanguage, - ["DOTNET_CLI_UI_LANGUAGE"] = testArgument.DotnetCLILanguage, - ["VSLANG"] = testArgument.VSLang is null ? null : new CultureInfo(testArgument.VSLang).LCID.ToString(CultureInfo.CurrentCulture), + ["TESTINGPLATFORM_UI_LANGUAGE"] = testingPlatformUILanguage, + ["DOTNET_CLI_UI_LANGUAGE"] = dotnetCLILanguage, + ["VSLANG"] = vsLang is null ? null : new CultureInfo(vsLang).LCID.ToString(CultureInfo.CurrentCulture), }); // Assert testHostResult.AssertExitCodeIs(0); - switch (testArgument.ExpectedLocale) + switch (expectedLocale) { case "fr-FR": testHostResult.AssertOutputContains("Les loggers Runsettings ne sont pas pris en charge par Microsoft.Testing.Platform et seront ignorés"); @@ -100,8 +91,7 @@ public async Task UnsupportedRunSettingsEntriesAreFlagged_Localization((string? } } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string ProjectName = "TestRunSettings"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestClassTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestClassTests.cs index 3c85fd28f2..02f884fb7a 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestClassTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestClassTests.cs @@ -8,20 +8,15 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class STATestClassTests : AcceptanceTestBase +[TestClass] +public sealed class STATestClassTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; private const string AssetName = "STATestClass"; private const string TimeoutAssetName = "TimeoutSTATestClass"; private const string CooperativeTimeoutAssetName = "CooperativeTimeoutSTATestClass"; - // There's a bug in TAFX where we need to use it at least one time somewhere to use it inside the fixture self (AcceptanceFixture). - public STATestClassTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture, - AcceptanceFixture globalFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestClass_OnWindows_OnLifeCycleTestClass_FixturesAndMethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -29,7 +24,7 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClass_FixturesAndMethods return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=LifeCycleTestClass"); @@ -46,7 +41,8 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClass_FixturesAndMethods testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestClass_OnWindows_OnLifeCycleTestClassWithLastTestSkipped_FixturesAndMethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -54,7 +50,7 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClassWithLastTestSkipped return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=LifeCycleTestClassWithLastTestSkipped"); @@ -71,7 +67,8 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClassWithLastTestSkipped testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestClass_OnWindows_OnLifeCycleTestClass_WithTimeout_FixturesAndMethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -79,7 +76,7 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClass_WithTimeout_Fixtur return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetTimeoutAssetPath, TimeoutAssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetTimeoutAssetPath, TimeoutAssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=LifeCycleTestClass"); @@ -96,7 +93,8 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClass_WithTimeout_Fixtur testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestClass_OnWindows_OnLifeCycleTestClassWithLastTestSkipped_WithTimeout_FixturesAndMethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -104,7 +102,7 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClassWithLastTestSkipped return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetTimeoutAssetPath, TimeoutAssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetTimeoutAssetPath, TimeoutAssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=LifeCycleTestClassWithLastTestSkipped"); @@ -121,7 +119,8 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClassWithLastTestSkipped testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestClass_OnWindows_OnLifeCycleTestClass_WithCooperativeTimeout_FixturesAndMethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -129,7 +128,7 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClass_WithCooperativeTim return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetCooperativeTimeoutAssetPath, CooperativeTimeoutAssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetCooperativeTimeoutAssetPath, CooperativeTimeoutAssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=LifeCycleTestClass"); @@ -146,7 +145,8 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClass_WithCooperativeTim testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestClass_OnWindows_OnLifeCycleTestClassWithLastTestSkipped_WithCooperativeTimeout_FixturesAndMethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -154,7 +154,7 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClassWithLastTestSkipped return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetCooperativeTimeoutAssetPath, CooperativeTimeoutAssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetCooperativeTimeoutAssetPath, CooperativeTimeoutAssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=LifeCycleTestClassWithLastTestSkipped"); @@ -171,7 +171,8 @@ public async Task STATestClass_OnWindows_OnLifeCycleTestClassWithLastTestSkipped testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task DerivedSTATestClass_OnWindows_OnTestClassWithClassCleanupEndOfAssembly_ClassCleanupIsMTA(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -179,7 +180,7 @@ public async Task DerivedSTATestClass_OnWindows_OnTestClassWithClassCleanupEndOf return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=TestClassWithClassCleanupEndOfAssembly"); @@ -196,8 +197,7 @@ public async Task DerivedSTATestClass_OnWindows_OnTestClassWithClassCleanupEndOf testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public string TargetAssetPath => GetAssetPath(AssetName); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestMethodTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestMethodTests.cs index b1b8b523e1..031b6858c3 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestMethodTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestMethodTests.cs @@ -8,20 +8,15 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class STATestMethodTests : AcceptanceTestBase +[TestClass] +public sealed class STATestMethodTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; private const string AssetName = "STATestMethodProject"; private const string TimeoutAssetName = "TimeoutSTATestMethodProject"; private const string CooperativeTimeoutAssetName = "CooperativeTimeoutSTATestMethodProject"; - // There's a bug in TAFX where we need to use it at least one time somewhere to use it inside the fixture self (AcceptanceFixture). - public STATestMethodTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture, - AcceptanceFixture globalFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestMethod_OnWindows_OnLifeCycleTestClass_FixturesAndMethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -29,7 +24,7 @@ public async Task STATestMethod_OnWindows_OnLifeCycleTestClass_FixturesAndMethod return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=LifeCycleTestClass"); @@ -46,7 +41,8 @@ public async Task STATestMethod_OnWindows_OnLifeCycleTestClass_FixturesAndMethod testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task DerivedSTATestMethod_OnWindows_OnTestClassWithClassCleanupEndOfAssembly(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -54,7 +50,7 @@ public async Task DerivedSTATestMethod_OnWindows_OnTestClassWithClassCleanupEndO return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=TestClassWithClassCleanupEndOfAssembly"); @@ -71,7 +67,8 @@ public async Task DerivedSTATestMethod_OnWindows_OnTestClassWithClassCleanupEndO testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestMethod_OnWindows_OnTestClassWithMultipleTests_MethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -79,7 +76,7 @@ public async Task STATestMethod_OnWindows_OnTestClassWithMultipleTests_MethodsAr return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=TestClassWithMultipleTests"); @@ -99,7 +96,8 @@ public async Task STATestMethod_OnWindows_OnTestClassWithMultipleTests_MethodsAr testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestMethod_OnWindows_OnLifeCycleTestClass_WithTimeout_FixturesAndMethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -107,7 +105,7 @@ public async Task STATestMethod_OnWindows_OnLifeCycleTestClass_WithTimeout_Fixtu return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TimeoutTargetAssetPath, TimeoutAssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TimeoutTargetAssetPath, TimeoutAssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=LifeCycleTestClass"); @@ -124,7 +122,8 @@ public async Task STATestMethod_OnWindows_OnLifeCycleTestClass_WithTimeout_Fixtu testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task DerivedSTATestMethod_OnWindows_WithTimeout_OnTestClassWithClassCleanupEndOfAssembly(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -132,7 +131,7 @@ public async Task DerivedSTATestMethod_OnWindows_WithTimeout_OnTestClassWithClas return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TimeoutTargetAssetPath, TimeoutAssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TimeoutTargetAssetPath, TimeoutAssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=TestClassWithClassCleanupEndOfAssembly"); @@ -149,7 +148,8 @@ public async Task DerivedSTATestMethod_OnWindows_WithTimeout_OnTestClassWithClas testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestMethod_OnWindows_OnTestClassWithMultipleTests_WithTimeout_MethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -157,7 +157,7 @@ public async Task STATestMethod_OnWindows_OnTestClassWithMultipleTests_WithTimeo return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.TimeoutTargetAssetPath, TimeoutAssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TimeoutTargetAssetPath, TimeoutAssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=TestClassWithMultipleTests"); @@ -177,7 +177,8 @@ public async Task STATestMethod_OnWindows_OnTestClassWithMultipleTests_WithTimeo testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestMethod_OnWindows_OnLifeCycleTestClass_WithCooperativeTimeout_FixturesAndMethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -185,7 +186,7 @@ public async Task STATestMethod_OnWindows_OnLifeCycleTestClass_WithCooperativeTi return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutTargetAssetPath, CooperativeTimeoutAssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutTargetAssetPath, CooperativeTimeoutAssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=LifeCycleTestClass"); @@ -202,7 +203,8 @@ public async Task STATestMethod_OnWindows_OnLifeCycleTestClass_WithCooperativeTi testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task DerivedSTATestMethod_OnWindows_WithCooperativeTimeout_OnTestClassWithClassCleanupEndOfAssembly(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -210,7 +212,7 @@ public async Task DerivedSTATestMethod_OnWindows_WithCooperativeTimeout_OnTestCl return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutTargetAssetPath, CooperativeTimeoutAssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutTargetAssetPath, CooperativeTimeoutAssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=TestClassWithClassCleanupEndOfAssembly"); @@ -227,7 +229,8 @@ public async Task DerivedSTATestMethod_OnWindows_WithCooperativeTimeout_OnTestCl testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task STATestMethod_OnWindows_OnTestClassWithMultipleTests_WithCooperativeTimeout_MethodsAreOnExpectedApartmentState(string currentTfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -235,7 +238,7 @@ public async Task STATestMethod_OnWindows_OnTestClassWithMultipleTests_WithCoope return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.CooperativeTimeoutTargetAssetPath, CooperativeTimeoutAssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutTargetAssetPath, CooperativeTimeoutAssetName, currentTfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath} --filter className=TestClassWithMultipleTests"); @@ -255,8 +258,7 @@ public async Task STATestMethod_OnWindows_OnTestClassWithMultipleTests_WithCoope testHostResult.AssertOutputContains("LifeCycleTestClass.AssemblyCleanup"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public string TargetAssetPath => GetAssetPath(AssetName); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs index 22c7931d86..540b214800 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs @@ -11,8 +11,8 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class SdkTests : AcceptanceTestBase +[TestClass] +public sealed class SdkTests : AcceptanceTestBase { private const string AssetName = "MSTestSdk"; @@ -51,17 +51,8 @@ public void TestMethod1() } """; - private readonly AcceptanceFixture _acceptanceFixture; - private readonly TestAssetFixture _testAssetFixture; - - public SdkTests(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture, TestAssetFixture testAssetFixture) - : base(testExecutionContext) - { - _acceptanceFixture = acceptanceFixture; - _testAssetFixture = testAssetFixture; - } - - [ArgumentsProvider(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] public async Task RunTests_With_VSTest(string multiTfm, BuildConfiguration buildConfiguration) { using TestAsset testAsset = await TestAsset.GenerateAssetAsync( @@ -71,23 +62,24 @@ public async Task RunTests_With_VSTest(string multiTfm, BuildConfiguration build .PatchCodeWithReplace("$TargetFramework$", multiTfm) .PatchCodeWithReplace("$ExtraProperties$", "true")); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test -c {buildConfiguration} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test -c {buildConfiguration} {testAsset.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.AreEqual(0, compilationResult.ExitCode); - compilationResult.AssertOutputRegEx(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net9\.0\)"); + compilationResult.AssertOutputMatchesRegex(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net9\.0\)"); #if !SKIP_INTERMEDIATE_TARGET_FRAMEWORKS - compilationResult.AssertOutputRegEx(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net8\.0\)"); - compilationResult.AssertOutputRegEx(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net7\.0\)"); - compilationResult.AssertOutputRegEx(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net6\.0\)"); + compilationResult.AssertOutputMatchesRegex(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net8\.0\)"); + compilationResult.AssertOutputMatchesRegex(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net7\.0\)"); + compilationResult.AssertOutputMatchesRegex(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net6\.0\)"); #endif if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - compilationResult.AssertOutputRegEx(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net462\)"); + compilationResult.AssertOutputMatchesRegex(@"Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1, Duration: .* [m]?s - MSTestSdk.dll \(net462\)"); } } - [ArgumentsProvider(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] public async Task RunTests_With_MSTestRunner_DotnetTest(string multiTfm, BuildConfiguration buildConfiguration) { using TestAsset testAsset = await TestAsset.GenerateAssetAsync( @@ -97,23 +89,24 @@ public async Task RunTests_With_MSTestRunner_DotnetTest(string multiTfm, BuildCo .PatchCodeWithReplace("$TargetFramework$", multiTfm) .PatchCodeWithReplace("$ExtraProperties$", string.Empty)); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test -c {buildConfiguration} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test -c {buildConfiguration} {testAsset.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.AreEqual(0, compilationResult.ExitCode); - compilationResult.AssertOutputRegEx(@"Tests succeeded: .* \[net9\.0|x64\]"); + compilationResult.AssertOutputMatchesRegex(@"Tests succeeded: .* \[net9\.0|x64\]"); #if !SKIP_INTERMEDIATE_TARGET_FRAMEWORKS - compilationResult.AssertOutputRegEx(@"Tests succeeded: .* \[net8\.0|x64\]"); - compilationResult.AssertOutputRegEx(@"Tests succeeded: .* \[net7\.0|x64\]"); - compilationResult.AssertOutputRegEx(@"Tests succeeded: .* \[net6\.0|x64\]"); + compilationResult.AssertOutputMatchesRegex(@"Tests succeeded: .* \[net8\.0|x64\]"); + compilationResult.AssertOutputMatchesRegex(@"Tests succeeded: .* \[net7\.0|x64\]"); + compilationResult.AssertOutputMatchesRegex(@"Tests succeeded: .* \[net6\.0|x64\]"); #endif if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { - compilationResult.AssertOutputRegEx(@"Tests succeeded: .* \[net462|x64\]"); + compilationResult.AssertOutputMatchesRegex(@"Tests succeeded: .* \[net462|x64\]"); } } - [ArgumentsProvider(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] public async Task RunTests_With_MSTestRunner_Standalone(string multiTfm, BuildConfiguration buildConfiguration) { using TestAsset testAsset = await TestAsset.GenerateAssetAsync( @@ -123,7 +116,7 @@ public async Task RunTests_With_MSTestRunner_Standalone(string multiTfm, BuildCo .PatchCodeWithReplace("$TargetFramework$", multiTfm) .PatchCodeWithReplace("$ExtraProperties$", string.Empty)); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.AreEqual(0, compilationResult.ExitCode); foreach (string tfm in multiTfm.Split(";")) { @@ -133,7 +126,8 @@ public async Task RunTests_With_MSTestRunner_Standalone(string multiTfm, BuildCo } } - [ArgumentsProvider(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] public async Task RunTests_With_CentralPackageManagement_Standalone(string multiTfm, BuildConfiguration buildConfiguration) { using TestAsset testAsset = await TestAsset.GenerateAssetAsync( @@ -143,7 +137,7 @@ public async Task RunTests_With_CentralPackageManagement_Standalone(string multi .PatchCodeWithReplace("$TargetFramework$", multiTfm) .PatchCodeWithReplace("$ExtraProperties$", string.Empty)); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.AreEqual(0, compilationResult.ExitCode); foreach (string tfm in multiTfm.Split(";")) { @@ -153,48 +147,39 @@ public async Task RunTests_With_CentralPackageManagement_Standalone(string multi } } - public static IEnumerable> RunTests_With_MSTestRunner_Standalone_Plus_Extensions_Data() + public static IEnumerable<(string MultiTfm, BuildConfiguration BuildConfiguration, string MSBuildExtensionEnableFragment, string EnableCommandLineArg, string InvalidCommandLineArg)> RunTests_With_MSTestRunner_Standalone_Plus_Extensions_Data() { - foreach (TestArgumentsEntry<(string MultiTfm, BuildConfiguration BuildConfiguration)> buildConfig in GetBuildMatrixMultiTfmFoldedBuildConfiguration()) + foreach ((string MultiTfm, BuildConfiguration BuildConfiguration) buildConfig in GetBuildMatrixMultiTfmFoldedBuildConfiguration()) { - yield return new TestArgumentsEntry<(string, BuildConfiguration, string, string, string)>( - (buildConfig.Arguments.MultiTfm, buildConfig.Arguments.BuildConfiguration, + yield return new(buildConfig.MultiTfm, buildConfig.BuildConfiguration, "true", "--coverage", - "--crashdump"), - $"multitfm,{buildConfig.Arguments.BuildConfiguration},CodeCoverage"); + "--crashdump"); - yield return new TestArgumentsEntry<(string, BuildConfiguration, string, string, string)>( - (buildConfig.Arguments.MultiTfm, buildConfig.Arguments.BuildConfiguration, + yield return new(buildConfig.MultiTfm, buildConfig.BuildConfiguration, "true", "--retry-failed-tests 3", - "--crashdump"), - $"multitfm,{buildConfig.Arguments.BuildConfiguration},Retry"); + "--crashdump"); - yield return new TestArgumentsEntry<(string, BuildConfiguration, string, string, string)>( - (buildConfig.Arguments.MultiTfm, buildConfig.Arguments.BuildConfiguration, + yield return new(buildConfig.MultiTfm, buildConfig.BuildConfiguration, "true", "--report-trx", - "--crashdump"), - $"multitfm,{buildConfig.Arguments.BuildConfiguration},TrxReport"); + "--crashdump"); - yield return new TestArgumentsEntry<(string, BuildConfiguration, string, string, string)>( - (buildConfig.Arguments.MultiTfm, buildConfig.Arguments.BuildConfiguration, + yield return new(buildConfig.MultiTfm, buildConfig.BuildConfiguration, "true", "--crashdump", - "--hangdump"), - $"multitfm,{buildConfig.Arguments.BuildConfiguration},CrashDump"); + "--hangdump"); - yield return new TestArgumentsEntry<(string, BuildConfiguration, string, string, string)>( - (buildConfig.Arguments.MultiTfm, buildConfig.Arguments.BuildConfiguration, + yield return new(buildConfig.MultiTfm, buildConfig.BuildConfiguration, "true", "--hangdump", - "--crashdump"), - $"multitfm,{buildConfig.Arguments.BuildConfiguration},HangDump"); + "--crashdump"); } } - [ArgumentsProvider(nameof(RunTests_With_MSTestRunner_Standalone_Plus_Extensions_Data))] + [TestMethod] + [DynamicData(nameof(RunTests_With_MSTestRunner_Standalone_Plus_Extensions_Data), DynamicDataSourceType.Method)] public async Task RunTests_With_MSTestRunner_Standalone_Selectively_Enabled_Extensions(string multiTfm, BuildConfiguration buildConfiguration, string msbuildExtensionEnableFragment, string enableCommandLineArg, @@ -207,7 +192,7 @@ public async Task RunTests_With_MSTestRunner_Standalone_Selectively_Enabled_Exte .PatchCodeWithReplace("$TargetFramework$", multiTfm) .PatchCodeWithReplace("$ExtraProperties$", msbuildExtensionEnableFragment)); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.AreEqual(0, compilationResult.ExitCode); foreach (string tfm in multiTfm.Split(";")) { @@ -220,7 +205,8 @@ public async Task RunTests_With_MSTestRunner_Standalone_Selectively_Enabled_Exte } } - [ArgumentsProvider(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] public async Task RunTests_With_MSTestRunner_Standalone_EnableAll_Extensions(string multiTfm, BuildConfiguration buildConfiguration) { using TestAsset testAsset = await TestAsset.GenerateAssetAsync( @@ -230,7 +216,7 @@ public async Task RunTests_With_MSTestRunner_Standalone_EnableAll_Extensions(str .PatchCodeWithReplace("$TargetFramework$", multiTfm) .PatchCodeWithReplace("$ExtraProperties$", "AllMicrosoft")); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.AreEqual(0, compilationResult.ExitCode); foreach (string tfm in multiTfm.Split(";")) { @@ -240,21 +226,17 @@ public async Task RunTests_With_MSTestRunner_Standalone_EnableAll_Extensions(str } } - public static IEnumerable> RunTests_With_MSTestRunner_Standalone_Default_Extensions_Data() + public static IEnumerable<(string MultiTfm, BuildConfiguration BuildConfiguration, bool EnableDefaultExtensions)> RunTests_With_MSTestRunner_Standalone_Default_Extensions_Data() { - foreach (TestArgumentsEntry<(string MultiTfm, BuildConfiguration BuildConfiguration)> buildConfig in GetBuildMatrixMultiTfmFoldedBuildConfiguration()) + foreach ((string MultiTfm, BuildConfiguration BuildConfiguration) buildConfig in GetBuildMatrixMultiTfmFoldedBuildConfiguration()) { - yield return new TestArgumentsEntry<(string, BuildConfiguration, bool)>( - (buildConfig.Arguments.MultiTfm, buildConfig.Arguments.BuildConfiguration, true), - $"enabled,{buildConfig.Arguments.BuildConfiguration},CodeCoverage"); - - yield return new TestArgumentsEntry<(string, BuildConfiguration, bool)>( - (buildConfig.Arguments.MultiTfm, buildConfig.Arguments.BuildConfiguration, false), - $"disabled,{buildConfig.Arguments.BuildConfiguration},CodeCoverage"); + yield return new(buildConfig.MultiTfm, buildConfig.BuildConfiguration, true); + yield return new(buildConfig.MultiTfm, buildConfig.BuildConfiguration, false); } } - [ArgumentsProvider(nameof(RunTests_With_MSTestRunner_Standalone_Default_Extensions_Data))] + [TestMethod] + [DynamicData(nameof(RunTests_With_MSTestRunner_Standalone_Default_Extensions_Data), DynamicDataSourceType.Method)] public async Task RunTests_With_MSTestRunner_Standalone_Enable_Default_Extensions(string multiTfm, BuildConfiguration buildConfiguration, bool enableDefaultExtensions) { using TestAsset testAsset = await TestAsset.GenerateAssetAsync( @@ -264,7 +246,7 @@ public async Task RunTests_With_MSTestRunner_Standalone_Enable_Default_Extension .PatchCodeWithReplace("$TargetFramework$", multiTfm) .PatchCodeWithReplace("$ExtraProperties$", enableDefaultExtensions ? string.Empty : "None")); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.AreEqual(0, compilationResult.ExitCode); foreach (string tfm in multiTfm.Split(";")) { @@ -281,7 +263,8 @@ public async Task RunTests_With_MSTestRunner_Standalone_Enable_Default_Extension } } - [ArgumentsProvider(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration))] + [TestMethod] + [DynamicData(nameof(GetBuildMatrixMultiTfmFoldedBuildConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] public async Task Invalid_TestingProfile_Name_Should_Fail(string multiTfm, BuildConfiguration buildConfiguration) { using TestAsset testAsset = await TestAsset.GenerateAssetAsync( @@ -291,11 +274,12 @@ public async Task Invalid_TestingProfile_Name_Should_Fail(string multiTfm, Build .PatchCodeWithReplace("$TargetFramework$", multiTfm) .PatchCodeWithReplace("$ExtraProperties$", "WrongName")); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"build -c {buildConfiguration} {testAsset.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); Assert.AreEqual(1, compilationResult.ExitCode); compilationResult.AssertOutputContains("Invalid value for property TestingExtensionsProfile. Valid values are 'Default', 'AllMicrosoft' and 'None'."); } + [TestMethod] public async Task NativeAot_Smoke_Test_Windows() // The native AOT publication is pretty flaky and is often failing on CI with "fatal error LNK1136: invalid or corrupt file", // or sometimes doesn't fail but the native code generation is not done. @@ -323,12 +307,12 @@ public async Task NativeAot_Smoke_Test_Windows() DotnetMuxerResult compilationResult = await DotnetCli.RunAsync( $"publish -r {RID} -f net9.0 {testAsset.TargetAssetPath}", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + AcceptanceFixture.NuGetGlobalPackagesFolder.Path, // We prefer to use the outer retry mechanism as we need some extra checks retryCount: 0, timeoutInSeconds: 180); compilationResult.AssertOutputContains("Generating native code"); - compilationResult.AssertOutputNotContains("warning"); + compilationResult.AssertOutputDoesNotContain("warning"); var testHost = TestHost.LocateFrom(testAsset.TargetAssetPath, AssetName, "net9.0", verb: Verb.publish); TestHostResult testHostResult = await testHost.ExecuteAsync(); @@ -337,10 +321,11 @@ public async Task NativeAot_Smoke_Test_Windows() testHostResult.AssertOutputContainsSummary(0, 1, 0); }, times: 15, every: TimeSpan.FromSeconds(5)); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task EnablePlaywrightProperty_WhenUsingRunner_AllowsToRunPlaywrightTests(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.PlaywrightProjectPath, TestAssetFixture.PlaywrightProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.PlaywrightProjectPath, TestAssetFixture.PlaywrightProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); // Depending on the machine, the test might fail due to the browser not being installed. @@ -361,16 +346,17 @@ public async Task EnablePlaywrightProperty_WhenUsingRunner_AllowsToRunPlaywright } } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task EnablePlaywrightProperty_WhenUsingVSTest_AllowsToRunPlaywrightTests(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.PlaywrightProjectPath, TestAssetFixture.PlaywrightProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.PlaywrightProjectPath, TestAssetFixture.PlaywrightProjectName, tfm); string exeOrDllName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? testHost.FullName : testHost.FullName + ".dll"; DotnetMuxerResult dotnetTestResult = await DotnetCli.RunAsync( $"test {exeOrDllName}", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + AcceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false, warnAsError: false, suppressPreviewDotNetMessage: false); @@ -396,22 +382,24 @@ public async Task EnablePlaywrightProperty_WhenUsingVSTest_AllowsToRunPlaywright } } + [TestMethod] public async Task EnableAspireProperty_WhenUsingRunner_AllowsToRunAspireTests() { - var testHost = TestHost.LocateFrom(_testAssetFixture.AspireProjectPath, TestAssetFixture.AspireProjectName, TargetFrameworks.NetCurrent.UidFragment); + var testHost = TestHost.LocateFrom(AssetFixture.AspireProjectPath, TestAssetFixture.AspireProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertOutputContainsSummary(0, 1, 0); } + [TestMethod] public async Task EnableAspireProperty_WhenUsingVSTest_AllowsToRunAspireTests() { - var testHost = TestHost.LocateFrom(_testAssetFixture.AspireProjectPath, TestAssetFixture.AspireProjectName, TargetFrameworks.NetCurrent.UidFragment); + var testHost = TestHost.LocateFrom(AssetFixture.AspireProjectPath, TestAssetFixture.AspireProjectName, TargetFrameworks.NetCurrent); string exeOrDllName = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? testHost.FullName : testHost.FullName + ".dll"; DotnetMuxerResult dotnetTestResult = await DotnetCli.RunAsync( $"test {exeOrDllName}", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + AcceptanceFixture.NuGetGlobalPackagesFolder.Path, warnAsError: false, suppressPreviewDotNetMessage: false); Assert.AreEqual(0, dotnetTestResult.ExitCode); @@ -420,17 +408,18 @@ public async Task EnableAspireProperty_WhenUsingVSTest_AllowsToRunAspireTests() dotnetTestResult.AssertOutputContains("Passed! - Failed: 0, Passed: 1, Skipped: 0, Total: 1"); } + [TestMethod] public async Task SettingIsTestApplicationToFalseReducesAddedExtensionsAndMakesProjectNotExecutable() { using TestAsset testAsset = await TestAsset.GenerateAssetAsync( AssetName, SingleTestSourceCode .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion) - .PatchCodeWithReplace("$TargetFramework$", TargetFrameworks.NetCurrent.UidFragment) + .PatchCodeWithReplace("$TargetFramework$", TargetFrameworks.NetCurrent) .PatchCodeWithReplace("$ExtraProperties$", "false")); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test {testAsset.TargetAssetPath} -bl:{binlogFile}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"test {testAsset.TargetAssetPath} -bl:{binlogFile}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.AreEqual(0, compilationResult.ExitCode); @@ -450,9 +439,7 @@ public async Task SettingIsTestApplicationToFalseReducesAddedExtensionsAndMakesP Assert.IsFalse(binLog.FindChildrenRecursive(p => p.Name == "OutputType").Any(p => p.Value == "Exe")); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture _acceptanceFixture) - : TestAssetFixtureBase(_acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string AspireProjectName = "AspireProject"; public const string PlaywrightProjectName = "PlaywrightProject"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/ServerModeTestsBase.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/ServerModeTestsBase.cs index d31bf62902..00f2a47feb 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/ServerModeTestsBase.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/ServerModeTestsBase.cs @@ -13,7 +13,8 @@ namespace MSTest.Acceptance.IntegrationTests.Messages.V100; -public partial /* for codegen regx */ class ServerModeTestsBase : AcceptanceTestBase +public partial /* for codegen regx */ class ServerModeTestsBase : AcceptanceTestBase + where TFixture : TestAssetFixtureBase, new() { private static readonly string Root = RootFinder.Find(); private static readonly Dictionary DefaultEnvironmentVariables = new() @@ -24,11 +25,6 @@ namespace MSTest.Acceptance.IntegrationTests.Messages.V100; { "DOTNET_MULTILEVEL_LOOKUP", "0" }, }; - protected ServerModeTestsBase(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - protected async Task StartAsServerAndConnectToTheClientAsync(TestHost testHost) { var environmentVariables = new Dictionary(DefaultEnvironmentVariables); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs index 989d5feae1..3449eb1a14 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs @@ -8,18 +8,14 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class ServerModeTests : ServerModeTestsBase +[TestClass] +public sealed class ServerModeTests : ServerModeTestsBase { - private readonly TestAssetFixture _fixture; - - public ServerModeTests(ITestExecutionContext testExecutionContext, TestAssetFixture fixture) - : base(testExecutionContext) => _fixture = fixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task DiscoverAndRun(string tfm) { - using TestingPlatformClient jsonClient = await StartAsServerAndConnectToTheClientAsync(TestHost.LocateFrom(_fixture.ProjectPath, "MSTestProject", tfm, buildConfiguration: BuildConfiguration.Release)); + using TestingPlatformClient jsonClient = await StartAsServerAndConnectToTheClientAsync(TestHost.LocateFrom(AssetFixture.ProjectPath, "MSTestProject", tfm, buildConfiguration: BuildConfiguration.Release)); LogsCollector logs = new(); jsonClient.RegisterLogListener(logs); TelemetryCollector telemetry = new(); @@ -40,17 +36,18 @@ public async Task DiscoverAndRun(string tfm) await Task.WhenAll(discoveryListener.WaitCompletion(), runListener.WaitCompletion()); Assert.AreEqual(1, discoveryCollector.TestNodeUpdates.Count(x => x.Node.NodeType == "action"), $"Wrong number of discovery"); Assert.AreEqual(2, runCollector.TestNodeUpdates.Count, $"Wrong number of updates"); - Assert.IsFalse(logs.Count == 0, $"Logs are empty"); + Assert.AreNotEqual(0, logs.Count, $"Logs are empty"); Assert.IsFalse(telemetry.IsEmpty, $"telemetry is empty"); await jsonClient.Exit(); Assert.AreEqual(0, await jsonClient.WaitServerProcessExit()); Assert.AreEqual(0, jsonClient.ExitCode); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task WhenClientDies_Server_ShouldClose_Gracefully(string tfm) { - using TestingPlatformClient jsonClient = await StartAsServerAndConnectToTheClientAsync(TestHost.LocateFrom(_fixture.ProjectPath, "MSTestProject", tfm, buildConfiguration: BuildConfiguration.Release)); + using TestingPlatformClient jsonClient = await StartAsServerAndConnectToTheClientAsync(TestHost.LocateFrom(AssetFixture.ProjectPath, "MSTestProject", tfm, buildConfiguration: BuildConfiguration.Release)); LogsCollector logs = new(); jsonClient.RegisterLogListener(logs); TelemetryCollector telemetry = new(); @@ -70,8 +67,7 @@ public async Task WhenClientDies_Server_ShouldClose_Gracefully(string tfm) Assert.AreEqual(3, exitCode); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string ProjectName = "MSTestProject"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestContextTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestContextTests.cs index 152c28dc96..e387366476 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestContextTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestContextTests.cs @@ -6,17 +6,13 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class TestContextTests : AcceptanceTestBase +[TestClass] +public sealed class TestContextTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public TestContextTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - + [TestMethod] public async Task TestContextsAreCorrectlySet() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--filter ClassName~TestContextCtor"); // Assert @@ -24,9 +20,10 @@ public async Task TestContextsAreCorrectlySet() testHostResult.AssertOutputContainsSummary(failed: 0, passed: 5, skipped: 0); } + [TestMethod] public async Task TestContext_TestData_PropertyContainsExpectedValue() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--filter ClassName~TestContextData"); // Assert @@ -34,9 +31,10 @@ public async Task TestContext_TestData_PropertyContainsExpectedValue() testHostResult.AssertOutputContainsSummary(failed: 0, passed: 3, skipped: 0); } + [TestMethod] public async Task TestContext_TestException_PropertyContainsExpectedValue() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--filter ClassName~TestContextException"); // Assert @@ -46,9 +44,10 @@ public async Task TestContext_TestException_PropertyContainsExpectedValue() testHostResult.AssertOutputContains("Test method TestContextExceptionFailingInTestMethod.TestFailingInTestMethod threw exception:"); } + [TestMethod] public async Task TestContext_TestDisplayName_PropertyContainsExpectedValue() { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--filter ClassName~TestContextDisplayName"); // Assert @@ -56,8 +55,7 @@ public async Task TestContext_TestDisplayName_PropertyContainsExpectedValue() testHostResult.AssertOutputContainsSummary(failed: 0, passed: 4, skipped: 0); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string ProjectName = "TestTestContext"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDiscoveryTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDiscoveryTests.cs index 8e0c7e53d0..bec1c9dd3a 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDiscoveryTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestDiscoveryTests.cs @@ -7,21 +7,16 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class TestDiscoveryTests : AcceptanceTestBase +[TestClass] +public class TestDiscoveryTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; private const string AssetName = "TestDiscovery"; - // There's a bug in TAFX where we need to use it at least one time somewhere to use it inside the fixture self (AcceptanceFixture). - public TestDiscoveryTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture, - AcceptanceFixture globalFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task DiscoverTests_FindsAllTests(string currentTfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--list-tests"); @@ -30,10 +25,11 @@ public async Task DiscoverTests_FindsAllTests(string currentTfm) testHostResult.AssertOutputContains("Test2"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task DiscoverTests_WithFilter_FindsOnlyFilteredOnes(string currentTfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--list-tests --filter Name=Test1"); @@ -42,8 +38,7 @@ public async Task DiscoverTests_WithFilter_FindsOnlyFilteredOnes(string currentT testHostResult.AssertOutputDoesNotContain("Test2"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public string TargetAssetPath => GetAssetPath(AssetName); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestFilterTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestFilterTests.cs index 03ee39c31a..aac2557286 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestFilterTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestFilterTests.cs @@ -7,21 +7,16 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class TestFilterTests : AcceptanceTestBase +[TestClass] +public class TestFilterTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; private const string AssetName = "TestFilter"; - // There's a bug in TAFX where we need to use it at least one time somewhere to use it inside the fixture self (AcceptanceFixture). - public TestFilterTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture, - AcceptanceFixture globalFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task RunWithFilter_UsingTestProperty_FilteredTests(string currentTfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--filter tree=one"); @@ -29,10 +24,11 @@ public async Task RunWithFilter_UsingTestProperty_FilteredTests(string currentTf testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 0); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task DiscoverTestsWithFilter_UsingTestProperty_FilteredTests(string currentTfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--filter tree=one --list-tests"); @@ -43,10 +39,11 @@ public async Task DiscoverTestsWithFilter_UsingTestProperty_FilteredTests(string """); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task UsingTestPropertyForOwnerAndPriorityAndTestCategory_TestsFailed(string currentTfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--filter tree!~one"); @@ -60,10 +57,11 @@ failed TestCategoryTest (0ms) """); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task RunWithFilter_UsingTestPropertyForOwner_FilteredButTestsFailed(string currentTfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--filter owner=testOwner"); @@ -73,10 +71,11 @@ failed OwnerTest (0ms) """); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task RunWithFilter_UsingTestPropertyForPriorityAndTestCategory_NotFiltered(string currentTfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--filter TestCategory=category|Priority=1"); @@ -84,8 +83,7 @@ public async Task RunWithFilter_UsingTestPropertyForPriorityAndTestCategory_NotF testHostResult.AssertExitCodeIs(8); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public string TargetAssetPath => GetAssetPath(AssetName); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestRunParametersTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestRunParametersTests.cs index 723ded5cd7..e3c188cd43 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestRunParametersTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TestRunParametersTests.cs @@ -6,18 +6,14 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class TestRunParametersTests : AcceptanceTestBase +[TestClass] +public sealed class TestRunParametersTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public TestRunParametersTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestRunParameters_WhenProvidingMultipleArgumentsToTheOption(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings --test-parameter MyParameter2=MyValue2 MyParameter3=MyValue3"); // Assert @@ -25,10 +21,11 @@ public async Task TestRunParameters_WhenProvidingMultipleArgumentsToTheOption(st testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 0); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestRunParameters_WhenProvidingMultipleMultipleTimesTheOptionAndArgument(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings --test-parameter MyParameter2=MyValue2 --test-parameter MyParameter3=MyValue3"); // Assert @@ -36,8 +33,7 @@ public async Task TestRunParameters_WhenProvidingMultipleMultipleTimesTheOptionA testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 0); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string ProjectName = "TestRunParameters"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadContextTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadContextTests.cs index 596bbd3325..4667b789f7 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadContextTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadContextTests.cs @@ -6,65 +6,67 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class ThreadContextTests : AcceptanceTestBase +[TestClass] +public sealed class ThreadContextTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public ThreadContextTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_WhenCultureIsNotSet_TestMethodFails(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.InitToTestProjectPath, TestAssetFixture.InitToTestProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.InitToTestProjectPath, TestAssetFixture.InitToTestProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertOutputContainsSummary(failed: 1, passed: 0, skipped: 0); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_WhenChangedInAssemblyInitialize_IsPassedToTestMethod(string tfm) => await SetCultureInFixtureMethodAndRunTests(tfm, "MSTEST_TEST_SET_CULTURE_ASSEMBLY_INIT"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_WhenChangedInClassInitialize_IsPassedToTestMethod(string tfm) => await SetCultureInFixtureMethodAndRunTests(tfm, "MSTEST_TEST_SET_CULTURE_CLASS_INIT"); - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_WhenChangedInTestInitialize_IsPassedToTestMethod(string tfm) => await SetCultureInFixtureMethodAndRunTests(tfm, "MSTEST_TEST_SET_CULTURE_TEST_INIT"); private async Task SetCultureInFixtureMethodAndRunTests(string tfm, string envVarKey) { - var testHost = TestHost.LocateFrom(_testAssetFixture.InitToTestProjectPath, TestAssetFixture.InitToTestProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.InitToTestProjectPath, TestAssetFixture.InitToTestProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { [envVarKey] = "true" }); testHostResult.AssertExitCodeIs(0); testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 0); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_CurrentCultureFlowsBetweenMethods(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CultureFlowsProjectPath, TestAssetFixture.CultureFlowsProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CultureFlowsProjectPath, TestAssetFixture.CultureFlowsProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertExitCodeIs(0); testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 0); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_WhenUsingSTAThread_CurrentCultureFlowsBetweenMethods(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CultureFlowsProjectPath, TestAssetFixture.CultureFlowsProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CultureFlowsProjectPath, TestAssetFixture.CultureFlowsProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "sta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}"); testHostResult.AssertExitCodeIs(0); testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 0); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_WhenUsingSTAThreadAndTimeout_CurrentCultureFlowsBetweenMethods(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CultureFlowsProjectPath, TestAssetFixture.CultureFlowsProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CultureFlowsProjectPath, TestAssetFixture.CultureFlowsProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "sta-timeout.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -74,10 +76,11 @@ public async Task ThreadingContext_WhenUsingSTAThreadAndTimeout_CurrentCultureFl testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 0); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_WhenUsingTimeout_CurrentCultureFlowsBetweenMethods(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CultureFlowsProjectPath, TestAssetFixture.CultureFlowsProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CultureFlowsProjectPath, TestAssetFixture.CultureFlowsProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "timeout.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -87,29 +90,32 @@ public async Task ThreadingContext_WhenUsingTimeout_CurrentCultureFlowsBetweenMe testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 0); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_Inheritance_CurrentCultureFlowsBetweenMethods(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CultureFlowsInheritanceProjectPath, TestAssetFixture.CultureFlowsInheritanceProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CultureFlowsInheritanceProjectPath, TestAssetFixture.CultureFlowsInheritanceProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertExitCodeIs(0); testHostResult.AssertOutputContainsSummary(failed: 0, passed: 8, skipped: 0); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_Inheritance_WhenUsingSTAThread_CurrentCultureFlowsBetweenMethods(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CultureFlowsInheritanceProjectPath, TestAssetFixture.CultureFlowsInheritanceProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CultureFlowsInheritanceProjectPath, TestAssetFixture.CultureFlowsInheritanceProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "sta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}"); testHostResult.AssertExitCodeIs(0); testHostResult.AssertOutputContainsSummary(failed: 0, passed: 8, skipped: 0); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_Inheritance_WhenUsingSTAThreadAndTimeout_CurrentCultureFlowsBetweenMethods(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CultureFlowsInheritanceProjectPath, TestAssetFixture.CultureFlowsInheritanceProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CultureFlowsInheritanceProjectPath, TestAssetFixture.CultureFlowsInheritanceProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "sta-timeout.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -119,10 +125,11 @@ public async Task ThreadingContext_Inheritance_WhenUsingSTAThreadAndTimeout_Curr testHostResult.AssertOutputContainsSummary(failed: 0, passed: 8, skipped: 0); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task ThreadingContext_Inheritance_WhenUsingTimeout_CurrentCultureFlowsBetweenMethods(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.CultureFlowsInheritanceProjectPath, TestAssetFixture.CultureFlowsInheritanceProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.CultureFlowsInheritanceProjectPath, TestAssetFixture.CultureFlowsInheritanceProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "timeout.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -132,9 +139,7 @@ public async Task ThreadingContext_Inheritance_WhenUsingTimeout_CurrentCultureFl testHostResult.AssertOutputContainsSummary(failed: 0, passed: 8, skipped: 0); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) - : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string InitToTestProjectName = "InitToTestThreadContextProject"; public const string CultureFlowsProjectName = "CultureFlowsThreadContextProject"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadingTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadingTests.cs index b84b167237..393791acf7 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadingTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadingTests.cs @@ -8,25 +8,22 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class ThreadingTests : AcceptanceTestBase +[TestClass] +public sealed class ThreadingTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public ThreadingTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestMethodThreading_WhenMainIsNotSTA_NoRunsettingsProvided_ThreadIsNotSTA(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertExitCodeIs(0); testHostResult.AssertOutputContains("Passed!"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestMethodThreading_WhenMainIsNotSTA_RunsettingsAsksForSTA_OnWindows_ThreadIsSTA(string tfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -34,7 +31,7 @@ public async Task TestMethodThreading_WhenMainIsNotSTA_RunsettingsAsksForSTA_OnW return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "sta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -45,7 +42,8 @@ public async Task TestMethodThreading_WhenMainIsNotSTA_RunsettingsAsksForSTA_OnW testHostResult.AssertOutputContains("Passed!"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestMethodThreading_WhenMainIsNotSTA_RunsettingsAsksForSTA_OnNonWindows_ThreadIsNotSTAAndWarningIsEmitted(string tfm) { if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -53,7 +51,7 @@ public async Task TestMethodThreading_WhenMainIsNotSTA_RunsettingsAsksForSTA_OnN return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "sta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -65,10 +63,11 @@ public async Task TestMethodThreading_WhenMainIsNotSTA_RunsettingsAsksForSTA_OnN testHostResult.AssertOutputContains("Runsettings entry 'STA' is not supported on non-Windows OSes"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestMethodThreading_WhenMainIsNotSTA_RunsettingsAsksForMTA_ThreadIsNotSTA(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -80,7 +79,8 @@ public async Task TestMethodThreading_WhenMainIsNotSTA_RunsettingsAsksForMTA_Thr testHostResult.AssertOutputDoesNotContain("Runsettings entry 'STA' is not supported on non-Windows OSes"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestMethodThreading_MainIsSTAThread_OnWindows_NoRunsettingsProvided_ThreadIsSTA(string tfm) { // Test cannot work on non-Windows OSes as the main method is marked with [STAThread] @@ -89,7 +89,7 @@ public async Task TestMethodThreading_MainIsSTAThread_OnWindows_NoRunsettingsPro return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.STAThreadProjectPath, TestAssetFixture.STAThreadProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.STAThreadProjectPath, TestAssetFixture.STAThreadProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { ["MSTEST_THREAD_STATE_IS_STA"] = "1", @@ -99,7 +99,8 @@ public async Task TestMethodThreading_MainIsSTAThread_OnWindows_NoRunsettingsPro testHostResult.AssertOutputContains("Passed!"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestMethodThreading_MainIsSTAThread_OnWindows_RunsettingsAsksForSTA_ThreadIsSTA(string tfm) { // Test cannot work on non-Windows OSes as the main method is marked with [STAThread] @@ -108,7 +109,7 @@ public async Task TestMethodThreading_MainIsSTAThread_OnWindows_RunsettingsAsksF return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.STAThreadProjectPath, TestAssetFixture.STAThreadProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.STAThreadProjectPath, TestAssetFixture.STAThreadProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "sta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -119,7 +120,8 @@ public async Task TestMethodThreading_MainIsSTAThread_OnWindows_RunsettingsAsksF testHostResult.AssertOutputContains("Passed!"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TestMethodThreading_MainIsSTAThread_OnWindows_RunsettingsAsksForMTA_ThreadIsMTA(string tfm) { // Test cannot work on non-Windows OSes as the main method is marked with [STAThread] @@ -128,7 +130,7 @@ public async Task TestMethodThreading_MainIsSTAThread_OnWindows_RunsettingsAsksF return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.STAThreadProjectPath, TestAssetFixture.STAThreadProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.STAThreadProjectPath, TestAssetFixture.STAThreadProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "mta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -139,7 +141,8 @@ public async Task TestMethodThreading_MainIsSTAThread_OnWindows_RunsettingsAsksF testHostResult.AssertOutputContains("Passed!"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task LifecycleAttributesVoidThreading_WhenMainIsNotSTA_RunsettingsAsksForSTA_OnWindows_ThreadIsSTA(string tfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -147,7 +150,7 @@ public async Task LifecycleAttributesVoidThreading_WhenMainIsNotSTA_RunsettingsA return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.LifecycleAttributesVoidProjectPath, TestAssetFixture.LifecycleAttributesVoidProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.LifecycleAttributesVoidProjectPath, TestAssetFixture.LifecycleAttributesVoidProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "sta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -158,7 +161,8 @@ public async Task LifecycleAttributesVoidThreading_WhenMainIsNotSTA_RunsettingsA testHostResult.AssertOutputContains("Passed!"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task LifecycleAttributesTaskThreading_WhenMainIsNotSTA_RunsettingsAsksForSTA_OnWindows_ThreadIsSTA(string tfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -166,7 +170,7 @@ public async Task LifecycleAttributesTaskThreading_WhenMainIsNotSTA_RunsettingsA return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.LifecycleAttributesTaskProjectPath, TestAssetFixture.LifecycleAttributesTaskProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.LifecycleAttributesTaskProjectPath, TestAssetFixture.LifecycleAttributesTaskProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "sta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -177,7 +181,8 @@ public async Task LifecycleAttributesTaskThreading_WhenMainIsNotSTA_RunsettingsA testHostResult.AssertOutputContains("Passed!"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task LifecycleAttributesTaskThreading_WhenMainIsNotSTA_RunsettingsAsksForSTA_OnWindows_ThreadIsSTA_With_ParallelAttribute(string tfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -185,7 +190,7 @@ public async Task LifecycleAttributesTaskThreading_WhenMainIsNotSTA_RunsettingsA return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.LifecycleAttributesTaskProjectPath, TestAssetFixture.LifecycleWithParallelAttributesTaskProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.LifecycleAttributesTaskProjectPath, TestAssetFixture.LifecycleWithParallelAttributesTaskProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "sta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -196,7 +201,8 @@ public async Task LifecycleAttributesTaskThreading_WhenMainIsNotSTA_RunsettingsA testHostResult.AssertOutputContains("Passed!"); } - [ArgumentsProvider(nameof(TargetFrameworks.Net), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.NetForDynamicData), typeof(TargetFrameworks))] public async Task LifecycleAttributesValueTaskThreading_WhenMainIsNotSTA_RunsettingsAsksForSTA_OnWindows_ThreadIsSTA(string tfm) { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -204,7 +210,7 @@ public async Task LifecycleAttributesValueTaskThreading_WhenMainIsNotSTA_Runsett return; } - var testHost = TestHost.LocateFrom(_testAssetFixture.LifecycleAttributesValueTaskProjectPath, TestAssetFixture.LifecycleAttributesValueTaskProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.LifecycleAttributesValueTaskProjectPath, TestAssetFixture.LifecycleAttributesValueTaskProjectName, tfm); string runSettingsFilePath = Path.Combine(testHost.DirectoryName, "sta.runsettings"); TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { @@ -215,9 +221,7 @@ public async Task LifecycleAttributesValueTaskThreading_WhenMainIsNotSTA_Runsett testHostResult.AssertOutputContains("Passed!"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) - : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string ProjectName = "TestThreading"; public const string STAThreadProjectName = "STATestThreading"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs index f2847639e0..59a05bfe2f 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs @@ -7,58 +7,58 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public class TimeoutTests : AcceptanceTestBase +[TestClass] +public class TimeoutTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public TimeoutTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TimeoutWithInvalidArg_WithoutLetterSuffix_OutputInvalidMessage(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 5"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.AssertOutputContains("'timeout' option should have one argument as string in the format [h|m|s] where 'value' is float"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TimeoutWithInvalidArg_WithInvalidLetterSuffix_OutputInvalidMessage(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 5y"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.AssertOutputContains("'timeout' option should have one argument as string in the format [h|m|s] where 'value' is float"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TimeoutWithInvalidArg_WithInvalidFormat_OutputInvalidMessage(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 5h6m"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.AssertOutputContains("'timeout' option should have one argument as string in the format [h|m|s] where 'value' is float"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task Timeout_WhenTimeoutValueSmallerThanTestDuration_OutputContainsCancelingMessage(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 1s"); testHostResult.AssertExitCodeIsNot(ExitCodes.Success); testHostResult.AssertOutputContains("Canceling the test session"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task Timeout_WhenTimeoutValueGreaterThanTestDuration_OutputDoesNotContainCancelingMessage(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 30s"); testHostResult.AssertExitCodeIs(ExitCodes.Success); @@ -66,8 +66,7 @@ public async Task Timeout_WhenTimeoutValueGreaterThanTestDuration_OutputDoesNotC testHostResult.AssertOutputDoesNotContain("Canceling the test session"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string AssetName = "TimeoutTest"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ValueTaskTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ValueTaskTests.cs index 110cfc716e..acaed7964b 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ValueTaskTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ValueTaskTests.cs @@ -6,18 +6,14 @@ namespace MSTest.Acceptance.IntegrationTests; -[TestGroup] -public sealed class ValueTaskTests : AcceptanceTestBase +[TestClass] +public sealed class ValueTaskTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public ValueTaskTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CanUseValueTaskForAllKnownLocations(string tfm) { - var testHost = TestHost.LocateFrom(_testAssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); // Assert @@ -25,8 +21,7 @@ public async Task CanUseValueTaskForAllKnownLocations(string tfm) testHostResult.AssertOutputContainsSummary(failed: 1, passed: 2, skipped: 1); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string ProjectName = "TestValueTask"; diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AbortionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AbortionTests.cs index 3938ea7cf8..80d9cfb1a0 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AbortionTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AbortionTests.cs @@ -3,22 +3,16 @@ using System.Runtime.InteropServices; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class AbortionTests : AcceptanceTestBase +[TestClass] +public class AbortionTests : AcceptanceTestBase { private const string AssetName = "Abort"; - private readonly TestAssetFixture _testAssetFixture; - - public AbortionTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; // We retry because sometime the Canceling the session message is not showing up. - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task AbortWithCTRLPlusC_TestHost_Succeeded(string tfm) { // We expect the same semantic for Linux, the test setup is not cross and we're using specific @@ -28,14 +22,14 @@ public async Task AbortWithCTRLPlusC_TestHost_Succeeded(string tfm) return; } - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertExitCodeIs(ExitCodes.TestSessionAborted); // We check only in netcore for netfx is now showing in CI every time, the same behavior in local something works sometime nope. // Manual test works pretty always as expected, looks like the implementation is different, we care more on .NET Core. - if (TargetFrameworks.Net.Select(x => x.Arguments).Contains(tfm)) + if (TargetFrameworks.Net.Contains(tfm)) { testHostResult.AssertOutputMatchesRegex("Canceling the test session.*"); } @@ -43,8 +37,7 @@ public async Task AbortWithCTRLPlusC_TestHost_Succeeded(string tfm) testHostResult.AssertOutputContainsSummary(failed: 0, passed: 0, skipped: 0, aborted: true); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string Sources = """ #file Abort.csproj @@ -78,11 +71,11 @@ internal sealed class Program public static async Task Main(string[] args) { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); - builder.RegisterTestFramework(_ => new Capabilities(), (_, __) => new DummyAdapter()); + builder.RegisterTestFramework(_ => new Capabilities(), (_, __) => new DummyTestFramework()); using ITestApplication app = await builder.BuildAsync(); _ = Task.Run(() => { - DummyAdapter.FireCancel.Wait(); + DummyTestFramework.FireCancel.Wait(); if (!GenerateConsoleCtrlEvent(ConsoleCtrlEvent.CTRL_C, 0)) { @@ -105,10 +98,10 @@ public enum ConsoleCtrlEvent } -internal class DummyAdapter : ITestFramework, IDataProducer +internal class DummyTestFramework : ITestFramework, IDataProducer { public static readonly ManualResetEventSlim FireCancel = new ManualResetEventSlim(false); - public string Uid => nameof(DummyAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => string.Empty; @@ -118,9 +111,11 @@ internal class DummyAdapter : ITestFramework, IDataProducer public Type[] DataTypesProduced => new[] { typeof(TestNodeUpdateMessage) }; - public Task CloseTestSessionAsync(CloseTestSessionContext context) => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); - public Task CreateTestSessionAsync(CreateTestSessionContext context) => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); public async Task ExecuteRequestAsync(ExecuteRequestContext context) { diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs index cad2f04a15..5805981732 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs @@ -3,20 +3,13 @@ using System.Runtime.InteropServices; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public sealed class CrashDumpTests : AcceptanceTestBase +[TestClass] +public sealed class CrashDumpTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public CrashDumpTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.Net), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.NetForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task CrashDump_DefaultSetting_CreateDump(string tfm) { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -25,14 +18,15 @@ public async Task CrashDump_DefaultSetting_CreateDump(string tfm) return; } - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N")); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "CrashDump", tfm); + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N")); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "CrashDump", tfm); TestHostResult testHostResult = await testHost.ExecuteAsync($"--crashdump --results-directory {resultDirectory}"); testHostResult.AssertExitCodeIs(ExitCodes.TestHostProcessExitedNonGracefully); string? dumpFile = Directory.GetFiles(resultDirectory, "CrashDump.dll_*.dmp", SearchOption.AllDirectories).SingleOrDefault(); Assert.IsTrue(dumpFile is not null, $"Dump file not found '{tfm}'\n{testHostResult}'"); } + [TestMethod] public async Task CrashDump_CustomDumpName_CreateDump() { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -41,17 +35,18 @@ public async Task CrashDump_CustomDumpName_CreateDump() return; } - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N")); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "CrashDump", TargetFrameworks.NetCurrent.Arguments); + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N")); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "CrashDump", TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync($"--crashdump --crashdump-filename customdumpname.dmp --results-directory {resultDirectory}"); testHostResult.AssertExitCodeIs(ExitCodes.TestHostProcessExitedNonGracefully); Assert.IsTrue(Directory.GetFiles(resultDirectory, "customdumpname.dmp", SearchOption.AllDirectories).SingleOrDefault() is not null, "Dump file not found"); } - [Arguments("Mini")] - [Arguments("Heap")] - [Arguments("Triage")] - [Arguments("Full")] + [DataRow("Mini")] + [DataRow("Heap")] + [DataRow("Triage")] + [DataRow("Full")] + [TestMethod] public async Task CrashDump_Formats_CreateDump(string format) { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -60,8 +55,8 @@ public async Task CrashDump_Formats_CreateDump(string format) return; } - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N")); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "CrashDump", TargetFrameworks.NetCurrent.Arguments); + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N")); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "CrashDump", TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync($"--crashdump --crashdump-type {format} --results-directory {resultDirectory}"); testHostResult.AssertExitCodeIs(ExitCodes.TestHostProcessExitedNonGracefully); string? dumpFile = Directory.GetFiles(resultDirectory, "CrashDump.dll_*.dmp", SearchOption.AllDirectories).SingleOrDefault(); @@ -69,17 +64,17 @@ public async Task CrashDump_Formats_CreateDump(string format) File.Delete(dumpFile); } + [TestMethod] public async Task CrashDump_InvalidFormat_ShouldFail() { - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N")); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "CrashDump", TargetFrameworks.NetCurrent.Arguments); + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N")); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "CrashDump", TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync($"--crashdump --crashdump-type invalid --results-directory {resultDirectory}"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.AssertOutputContains("Option '--crashdump-type' has invalid arguments: 'invalid' is not a valid dump type. Valid options are 'Mini', 'Heap', 'Triage' and 'Full'"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string AssetName = "CrashDumpFixture"; @@ -130,22 +125,22 @@ public class Startup public static async Task Main(string[] args) { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); - builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestAdapter()); + builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestFramework()); builder.AddCrashDumpProvider(); using ITestApplication app = await builder.BuildAsync(); return await app.RunAsync(); } } -public class DummyTestAdapter : ITestFramework +public class DummyTestFramework : ITestFramework { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs index 8d4a1adca5..56ad9445d5 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs @@ -3,19 +3,12 @@ using System.Runtime.InteropServices; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public sealed class CrashPlusHangDumpTests : AcceptanceTestBase +[TestClass] +public sealed class CrashPlusHangDumpTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public CrashPlusHangDumpTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - + [TestMethod] public async Task CrashPlusHangDump_InCaseOfCrash_CreateCrashDump() { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -24,8 +17,8 @@ public async Task CrashPlusHangDump_InCaseOfCrash_CreateCrashDump() return; } - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent.Arguments); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "CrashPlusHangDump", TargetFrameworks.NetCurrent.Arguments); + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "CrashPlusHangDump", TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync( $"--hangdump --hangdump-timeout 5m --crashdump --results-directory {resultDirectory}", new Dictionary @@ -43,6 +36,7 @@ public async Task CrashPlusHangDump_InCaseOfCrash_CreateCrashDump() Assert.IsFalse(Directory.GetFiles(resultDirectory, "CrashPlusHangDump*_hang.dmp", SearchOption.AllDirectories).Length > 0, $"Dump file not found '{TargetFrameworks.NetCurrent}'\n{testHostResult}'"); } + [TestMethod] public async Task CrashPlusHangDump_InCaseOfHang_CreateHangDump() { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -51,8 +45,8 @@ public async Task CrashPlusHangDump_InCaseOfHang_CreateHangDump() return; } - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent.Arguments); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "CrashPlusHangDump", TargetFrameworks.NetCurrent.Arguments); + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "CrashPlusHangDump", TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync( $"--hangdump --hangdump-timeout 8s --crashdump --results-directory {resultDirectory}", new Dictionary @@ -70,10 +64,9 @@ public async Task CrashPlusHangDump_InCaseOfHang_CreateHangDump() Assert.IsTrue(Directory.GetFiles(resultDirectory, "CrashPlusHangDump*_hang.dmp", SearchOption.AllDirectories).Length > 0, $"Dump file not found '{TargetFrameworks.NetCurrent}'\n{testHostResult}'"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { - private const string AssetName = "TestAssetFixture"; + private const string AssetName = "AssetFixture"; public string TargetAssetPath => GetAssetPath(AssetName); @@ -123,7 +116,7 @@ public class Startup public static async Task Main(string[] args) { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); - builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestAdapter()); + builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestFramework()); builder.AddCrashDumpProvider(); builder.AddHangDumpProvider(); using ITestApplication app = await builder.BuildAsync(); @@ -131,15 +124,15 @@ public static async Task Main(string[] args) } } -public class DummyTestAdapter : ITestFramework, IDataProducer +public class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CustomBannerTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CustomBannerTests.cs index 4c3920dbfd..9239a51a4a 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CustomBannerTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CustomBannerTests.cs @@ -1,34 +1,29 @@ // 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.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class CustomBannerTests : AcceptanceTestBase +[TestClass] +public class CustomBannerTests : AcceptanceTestBase { private const string AssetName = "CustomBannerTest"; - private readonly TestAssetFixture _testAssetFixture; - - public CustomBannerTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task UsingNoBanner_TheBannerDoesNotAppear(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--no-banner"); testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); testHostResult.AssertOutputDoesNotContain(TestAssetFixture.CustomBannerPrefix); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task UsingNoBanner_InTheEnvironmentVars_TheBannerDoesNotAppear(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( null, new Dictionary @@ -40,10 +35,11 @@ public async Task UsingNoBanner_InTheEnvironmentVars_TheBannerDoesNotAppear(stri testHostResult.AssertOutputDoesNotContain(TestAssetFixture.CustomBannerPrefix); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task UsingDotnetNoLogo_InTheEnvironmentVars_TheBannerDoesNotAppear(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( null, new Dictionary @@ -55,18 +51,18 @@ public async Task UsingDotnetNoLogo_InTheEnvironmentVars_TheBannerDoesNotAppear( testHostResult.AssertOutputDoesNotContain(TestAssetFixture.CustomBannerPrefix); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task WithoutUsingNoBanner_TheBannerAppears(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); testHostResult.AssertOutputMatchesRegex($"{TestAssetFixture.CustomBannerPrefix} Platform info: Name: .NET Testing Platform, Version: .+?, Hash: .*?, Date: .+?"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string CustomBannerPrefix = "Custom banner |"; @@ -102,7 +98,7 @@ public static async Task Main(string[] args) ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); builder.RegisterTestFramework( sp => new TestFrameworkCapabilities(new DummyBannerMessageOwnerCapability(sp)), - (_,__) => new DummyTestAdapter()); + (_,__) => new DummyTestFramework()); using ITestApplication app = await builder.BuildAsync(); return await app.RunAsync(); } @@ -128,20 +124,20 @@ public DummyBannerMessageOwnerCapability(IServiceProvider serviceProvider) sb.Append($", Hash: {platformInformation.CommitHash}"); sb.Append($", Date: {platformInformation.BuildDate}"); - return Task.FromResult(sb.ToString()); + return Task.FromResult(sb.ToString()); } } #pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. -public class DummyTestAdapter : ITestFramework +public class DummyTestFramework : ITestFramework { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs index 65eaeb6028..d584878a83 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs @@ -3,111 +3,112 @@ using System.Text.RegularExpressions; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; using Microsoft.Testing.Platform.Configurations; -using Microsoft.Testing.Platform.Helpers; namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class DiagnosticTests : AcceptanceTestBase +[TestClass] +public class DiagnosticTests : AcceptanceTestBase { private const string AssetName = "DiagnosticTest"; - private readonly TestAssetFixture _testAssetFixture; - - public DiagnosticTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_WhenDiagnosticIsSpecified_ReportIsGeneratedInDefaultLocation(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); + string diagPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); string diagPathPattern = Path.Combine(diagPath, @"log_.*.diag").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--diagnostic"); await AssertDiagnosticReportWasGeneratedAsync(testHostResult, diagPathPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_WhenDiagnosticAndOutputFilePrefixAreSpecified_ReportIsGeneratedInDefaultLocation(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); + string diagPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); string diagPathPattern = Path.Combine(diagPath, @"abcd_.*.diag").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--diagnostic --diagnostic-output-fileprefix abcd"); await AssertDiagnosticReportWasGeneratedAsync(testHostResult, diagPathPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_WhenDiagnosticAndOutputDirectoryAreSpecified_ReportIsGeneratedInSpecifiedLocation(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, "test1"); + string diagPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, "test1"); string diagPathPattern = Path.Combine(diagPath, @"log_.*.diag").Replace(@"\", @"\\"); Assert.IsTrue(Directory.CreateDirectory(diagPath).Exists); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync($"--diagnostic --diagnostic-output-directory {diagPath}"); await AssertDiagnosticReportWasGeneratedAsync(testHostResult, diagPathPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_WhenDiagnosticAndOutputFilePrefixAndOutputDirectoryAreSpecified_ReportIsGeneratedInSpecifiedLocation(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, "test2"); + string diagPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, "test2"); string diagPathPattern = Path.Combine(diagPath, @"abcde_.*.diag").Replace(@"\", @"\\"); Assert.IsTrue(Directory.CreateDirectory(diagPath).Exists); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync($"--diagnostic --diagnostic-output-fileprefix abcde --diagnostic-output-directory {diagPath}"); await AssertDiagnosticReportWasGeneratedAsync(testHostResult, diagPathPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_WhenDiagnosticOutputFilePrefixButNotDiagnosticIsSpecified_ReportGenerationFails(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--diagnostic-output-fileprefix cccc"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.AssertOutputContains("'--diagnostic-output-fileprefix' requires '--diagnostic' to be provided"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_WhenDiagnosticOutputDirectoryButNotDiagnosticIsSpecified_ReportGenerationFails(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--diagnostic-output-directory cccc"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.AssertOutputContains("'--diagnostic-output-directory' requires '--diagnostic' to be provided"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_WhenDiagnosticFilePrefixAndDiagnosticOutputDirectoryButNotDiagnosticAreSpecified_ReportGenerationFails(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--diagnostic-output-fileprefix aaaa --diagnostic-output-directory cccc"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.AssertOutputContains("'--diagnostic-output-directory' requires '--diagnostic' to be provided"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_EnableWithEnvironmentVariables_Succeeded(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); + string diagPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); string diagPathPattern = Path.Combine(diagPath, @"log_.*.diag").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( null, new Dictionary @@ -118,13 +119,14 @@ public async Task Diag_EnableWithEnvironmentVariables_Succeeded(string tfm) await AssertDiagnosticReportWasGeneratedAsync(testHostResult, diagPathPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_EnableWithEnvironmentVariables_Verbosity_Succeeded(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); + string diagPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); string diagPathPattern = Path.Combine(diagPath, @"log_.*.diag").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( null, new Dictionary @@ -136,13 +138,14 @@ public async Task Diag_EnableWithEnvironmentVariables_Verbosity_Succeeded(string await AssertDiagnosticReportWasGeneratedAsync(testHostResult, diagPathPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_EnableWithEnvironmentVariables_CustomPrefix_Succeeded(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); + string diagPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); string diagPathPattern = Path.Combine(diagPath, @"MyPrefix_.*.diag").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( null, new Dictionary @@ -154,13 +157,14 @@ public async Task Diag_EnableWithEnvironmentVariables_CustomPrefix_Succeeded(str await AssertDiagnosticReportWasGeneratedAsync(testHostResult, diagPathPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_EnableWithEnvironmentVariables_SynchronousWrite_Succeeded(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); + string diagPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); string diagPathPattern = Path.Combine(diagPath, @"log_.*.diag").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( null, new Dictionary @@ -172,10 +176,11 @@ public async Task Diag_EnableWithEnvironmentVariables_SynchronousWrite_Succeeded await AssertDiagnosticReportWasGeneratedAsync(testHostResult, diagPathPattern, flushType: "sync"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Diag_EnableWithEnvironmentVariables_Disable_Succeeded(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--diagnostic", @@ -183,17 +188,17 @@ public async Task Diag_EnableWithEnvironmentVariables_Disable_Succeeded(string t { { EnvironmentVariableConstants.TESTINGPLATFORM_DIAGNOSTIC, "0" }, }); - testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); testHostResult.AssertOutputDoesNotContain("Diagnostic file"); testHostResult = await testHost.ExecuteAsync("--diagnostic"); - testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); testHostResult.AssertOutputContains("Diagnostic file"); } private async Task AssertDiagnosticReportWasGeneratedAsync(TestHostResult testHostResult, string diagPathPattern, string level = "Trace", string flushType = "async") { - testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); string outputPattern = $""" Diagnostic file \(level '{level}' with {flushType} flush\): {diagPathPattern} @@ -222,8 +227,7 @@ private async Task AssertDiagnosticReportWasGeneratedAsync(TestHostResul return (Regex.IsMatch(content, pattern), content); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string TestCode = """ #file DiagnosticTest.csproj @@ -237,37 +241,51 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test preview - - - - #file Program.cs -using DiagnosticTest; -ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new SourceGeneratedTestNodesBuilder()); -using ITestApplication app = await builder.BuildAsync(); -return await app.RunAsync(); - -#file UnitTest1.cs -namespace DiagnosticTest; +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.Services; -[TestGroup] -public class UnitTest1 +public class Program { - public void TestMethod1() + public static async Task Main(string[] args) { - Assert.IsTrue(true); + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + builder.RegisterTestFramework( + sp => new TestFrameworkCapabilities(), + (_,__) => new DummyTestFramework()); + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); } } -#file Usings.cs -global using Microsoft.Testing.Platform.Builder; -global using Microsoft.Testing.Internal.Framework; -global using Microsoft.Testing.Extensions; +public class DummyTestFramework : ITestFramework +{ + public string Uid => nameof(DummyTestFramework); + + public string Version => "2.0.0"; + + public string DisplayName => nameof(DummyTestFramework); + + public string Description => nameof(DummyTestFramework); + + public Task IsEnabledAsync() => Task.FromResult(true); + + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + public Task ExecuteRequestAsync(ExecuteRequestContext context) + { + context.Complete(); + return Task.CompletedTask; + } +} """; public string TargetAssetPath => GetAssetPath(AssetName); @@ -278,8 +296,7 @@ public void TestMethod1() TestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); } } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/EnvironmentVariablesConfigurationProviderTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/EnvironmentVariablesConfigurationProviderTests.cs index 5b8e45a901..1da20468e9 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/EnvironmentVariablesConfigurationProviderTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/EnvironmentVariablesConfigurationProviderTests.cs @@ -1,31 +1,23 @@ // 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.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public sealed class EnvironmentVariablesConfigurationProviderTests : AcceptanceTestBase +[TestClass] +public sealed class EnvironmentVariablesConfigurationProviderTests : AcceptanceTestBase { private const string AssetName = "EnvironmentVariablesConfigurationProvider"; - private readonly TestAssetFixture _testAssetFixture; - - public EnvironmentVariablesConfigurationProviderTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task SetEnvironmentVariable_ShouldSucceed(string currentTfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertExitCodeIs(ExitCodes.Success); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) - : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string Sources = """ #file EnvironmentVariablesConfigurationProvider.csproj @@ -63,7 +55,7 @@ public class Startup public static async Task Main(string[] args) { var testApplicationBuilder = await TestApplication.CreateBuilderAsync(args); - testApplicationBuilder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestAdapter()); + testApplicationBuilder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestFramework()); testApplicationBuilder.TestHostControllers.AddEnvironmentVariableProvider(_ => new TestHostEnvironmentVariableProviderTestClass()); using ITestApplication app = await testApplicationBuilder.BuildAsync(); return await app.RunAsync(); @@ -97,15 +89,15 @@ public Task ValidateTestHostEnvironmentVariablesAsync(IReadOnl } } -public class DummyTestAdapter : ITestFramework, IDataProducer +public class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs index b925c1cefc..235c2c376d 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs @@ -3,121 +3,115 @@ using System.Diagnostics; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class ExecutionTests : AcceptanceTestBase +[TestClass] +public class ExecutionTests : AcceptanceTestBase { private const string AssetName = "ExecutionTests"; private const string AssetName2 = "ExecutionTests2"; - private readonly TestAssetFixture _testAssetFixture; - - public ExecutionTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Exec_WhenListTestsIsSpecified_AllTestsAreFound(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--list-tests"); testHostResult.AssertExitCodeIs(ExitCodes.Success); const string OutputPattern = """ The following Tests are available: -TestMethod1 -TestMethod2 -TestMethod3 -FilteredOutTest$ +Test1 +Test2$ """; testHostResult.AssertOutputMatchesRegex(OutputPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Exec_WhenOnlyAssetNameIsSpecified_AllTestsAreRun(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertExitCodeIs(ExitCodes.Success); - testHostResult.AssertOutputContainsSummary(failed: 0, passed: 4, skipped: 0); - testHostResult.AssertOutputContains($"! - {_testAssetFixture.TargetAssetPath}"); + testHostResult.AssertOutputContainsSummary(failed: 0, passed: 2, skipped: 0); + testHostResult.AssertOutputContains($"! - {AssetFixture.TargetAssetPath}"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Exec_WhenListTestsAndFilterAreSpecified_OnlyFilteredTestsAreFound(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync("--list-tests --treenode-filter \"/ExecutionTests/ExecutionTests/UnitTest1/TestMethod*\""); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync("--list-tests --treenode-filter \"\""); testHostResult.AssertExitCodeIs(ExitCodes.Success); const string OutputPattern = """ The following Tests are available: -TestMethod1 -TestMethod2 -TestMethod3$ +Test1$ """; testHostResult.AssertOutputMatchesRegex(OutputPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Exec_WhenFilterIsSpecified_OnlyFilteredTestsAreRun(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync("--treenode-filter \"/ExecutionTests/ExecutionTests/UnitTest1/TestMethod*\""); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync("--treenode-filter \"\""); testHostResult.AssertExitCodeIs(ExitCodes.Success); - testHostResult.AssertOutputContainsSummary(failed: 0, passed: 3, skipped: 0); - testHostResult.AssertOutputContains($"! - {_testAssetFixture.TargetAssetPath}"); + testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 0); + testHostResult.AssertOutputContains($"! - {AssetFixture.TargetAssetPath}"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Exec_WhenMinimumExpectedTestsIsSpecifiedAndEnoughTestsRun_ResultIsOk(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync("--minimum-expected-tests 4"); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync("--minimum-expected-tests 2"); testHostResult.AssertExitCodeIs(ExitCodes.Success); - testHostResult.AssertOutputContainsSummary(failed: 0, passed: 4, skipped: 0); - testHostResult.AssertOutputContains($"! - {_testAssetFixture.TargetAssetPath}"); + testHostResult.AssertOutputContainsSummary(failed: 0, passed: 2, skipped: 0); + testHostResult.AssertOutputContains($"! - {AssetFixture.TargetAssetPath}"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Exec_WhenMinimumExpectedTestsIsSpecifiedAndNotEnoughTestsRun_ResultIsNotOk(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync("--minimum-expected-tests 5"); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync("--minimum-expected-tests 3"); testHostResult.AssertExitCodeIs(ExitCodes.MinimumExpectedTestsPolicyViolation); - testHostResult.AssertOutputContainsSummary(failed: 0, passed: 4, skipped: 0, minimumNumberOfTests: 5); - testHostResult.AssertOutputContains($" - {_testAssetFixture.TargetAssetPath}"); + testHostResult.AssertOutputContainsSummary(failed: 0, passed: 2, skipped: 0, minimumNumberOfTests: 3); + testHostResult.AssertOutputContains($" - {AssetFixture.TargetAssetPath}"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Exec_WhenListTestsAndMinimumExpectedTestsAreSpecified_DiscoveryFails(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync("--list-tests --minimum-expected-tests 4"); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync("--list-tests --minimum-expected-tests 2"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); - - const string OutputPattern = "Error: '--list-tests' and '--minimum-expected-tests' are incompatible options"; - Assert.That(testHostResult.StandardOutput.Contains(OutputPattern), $"Output of the test host is:\n{testHostResult}"); + testHostResult.AssertOutputContains("Error: '--list-tests' and '--minimum-expected-tests' are incompatible options"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Exec_Honor_Request_Complete(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath2, AssetName2, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath2, AssetName2, tfm); var stopwatch = Stopwatch.StartNew(); TestHostResult testHostResult = await testHost.ExecuteAsync(); stopwatch.Stop(); @@ -125,8 +119,7 @@ public async Task Exec_Honor_Request_Complete(string tfm) Assert.IsTrue(stopwatch.Elapsed.TotalSeconds > 3); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string TestCode = """ #file ExecutionTests.csproj @@ -140,52 +133,92 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test preview - - - - #file Program.cs -using ExecutionTests; -ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new SourceGeneratedTestNodesBuilder()); -using ITestApplication app = await builder.BuildAsync(); -return await app.RunAsync(); - -#file UnitTest1.cs -namespace ExecutionTests; +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions; +using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.Services; -[TestGroup] -public class UnitTest1 +public class Program { - public void TestMethod1() + public static async Task Main(string[] args) { - Assert.IsTrue(true); + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + MyExtension myExtension = new(); + builder.RegisterTestFramework( + sp => new TestFrameworkCapabilities(), + (_,sp) => new DummyTestFramework(sp, myExtension)); + builder.AddTreeNodeFilterService(myExtension); + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); } +} - public void TestMethod2() - { - Assert.IsTrue(true); - } +public class MyExtension : IExtension +{ + public string Uid => "MyExtension"; + public string Version => "1.0.0"; + public string DisplayName => "My Extension"; + public string Description => "My Extension Description"; + public Task IsEnabledAsync() => Task.FromResult(true); +} + +public class DummyTestFramework : ITestFramework, IDataProducer +{ + private IServiceProvider _sp; + private MyExtension _myExtension; - public void TestMethod3() + public DummyTestFramework(IServiceProvider sp, MyExtension myExtension) { - Assert.IsTrue(true); + _sp = sp; + _myExtension = myExtension; } - public void FilteredOutTest() + public string Uid => _myExtension.Uid; + + public string Version => _myExtension.Version; + + public string DisplayName => _myExtension.DisplayName; + + public string Description => _myExtension.Description; + + public Type[] DataTypesProduced => [typeof(TestNodeUpdateMessage)]; + + public Task IsEnabledAsync() => _myExtension.IsEnabledAsync(); + + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + + public async Task ExecuteRequestAsync(ExecuteRequestContext context) { - Assert.IsTrue(true); + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "0", DisplayName = "Test1", Properties = new(DiscoveredTestNodeStateProperty.CachedInstance) })); + + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "0", DisplayName = "Test1", Properties = new(PassedTestNodeStateProperty.CachedInstance) })); + + if (!_sp.GetCommandLineOptions().TryGetOptionArgumentList("--treenode-filter", out _)) + { + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "1", DisplayName = "Test2", Properties = new(DiscoveredTestNodeStateProperty.CachedInstance) })); + + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "1", DisplayName = "Test2", Properties = new(PassedTestNodeStateProperty.CachedInstance) })); + } + + context.Complete(); } } - -#file Usings.cs -global using Microsoft.Testing.Platform.Builder; -global using Microsoft.Testing.Internal.Framework; -global using Microsoft.Testing.Extensions; """; private const string TestCode2 = """ @@ -215,13 +248,13 @@ public void FilteredOutTest() using System.Threading.Tasks; ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.RegisterTestFramework(_ => new Capabilities(), (_, __) => new DummyAdapter()); +builder.RegisterTestFramework(_ => new Capabilities(), (_, __) => new DummyTestFramework()); using ITestApplication app = await builder.BuildAsync(); return await app.RunAsync(); -internal class DummyAdapter : ITestFramework, IDataProducer +internal class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => string.Empty; @@ -271,8 +304,7 @@ internal class Capabilities : ITestFrameworkCapabilities TestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); yield return (AssetName2, AssetName2, TestCode2 diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExitOnProcessExitTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExitOnProcessExitTests.cs index 98b741b9e9..d7382cc3b0 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExitOnProcessExitTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExitOnProcessExitTests.cs @@ -5,19 +5,16 @@ namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class ExitOnProcessExitTests : AcceptanceTestBase +[TestClass] +public class ExitOnProcessExitTests : AcceptanceTestBase { private const string AssetName = "ExecutionTests"; - private readonly TestAssetFixture _testAssetFixture; - public ExitOnProcessExitTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public void ExitOnProcessExit_Succeed(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); // Create the mutex name used to wait for the PID file created by the test host. string waitPid = Guid.NewGuid().ToString("N"); @@ -60,8 +57,7 @@ public void ExitOnProcessExit_Succeed(string tfm) } } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string TestCode = """ #file ExecutionTests.csproj @@ -115,21 +111,21 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test else { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); - builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, __) => new DummyTestAdapter()); + builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, __) => new DummyTestFramework()); using ITestApplication app = await builder.BuildAsync(); return await app.RunAsync(); } -public class DummyTestAdapter : ITestFramework, IDataProducer +public class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs index a66c6d166f..a46fd94340 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs @@ -3,20 +3,13 @@ using System.Runtime.InteropServices; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public sealed class HangDumpOutputTests : AcceptanceTestBase +[TestClass] +public sealed class HangDumpOutputTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public HangDumpOutputTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [Arguments("Mini")] + [DataRow("Mini")] + [TestMethod] public async Task HangDump_Outputs_HangingTests_EvenWhenHangingTestsHaveTheSameDisplayName(string format) { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -30,8 +23,8 @@ public async Task HangDump_Outputs_HangingTests_EvenWhenHangingTestsHaveTheSameD // a dictionary based on DisplayName. In that case both tests were started at the same time, and only 1 entry was added // to currently executing tests. When first test with name Test1 completed we removed that entry, but Class2.Test1 was still // running. Solution is to use a more unique identifier. - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), format); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent.Arguments); + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), format); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync( $"--hangdump --hangdump-timeout 8s --hangdump-type {format} --results-directory {resultDirectory} --no-progress", new Dictionary @@ -43,10 +36,9 @@ public async Task HangDump_Outputs_HangingTests_EvenWhenHangingTestsHaveTheSameD testHostResult.AssertOutputContains("Test1"); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { - private const string AssetName = "TestAssetFixture"; + private const string AssetName = "AssetFixture"; public string TargetAssetPath => GetAssetPath(AssetName); @@ -96,22 +88,22 @@ public class Startup public static async Task Main(string[] args) { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); - builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestAdapter()); + builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestFramework()); builder.AddHangDumpProvider(); using ITestApplication app = await builder.BuildAsync(); return await app.RunAsync(); } } -public class DummyTestAdapter : ITestFramework, IDataProducer +public class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs index fc9935efce..15d4bfe244 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs @@ -3,20 +3,13 @@ using System.Runtime.InteropServices; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public sealed class HangDumpTests : AcceptanceTestBase +[TestClass] +public sealed class HangDumpTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public HangDumpTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task HangDump_DefaultSetting_CreateDump(string tfm) { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -25,8 +18,8 @@ public async Task HangDump_DefaultSetting_CreateDump(string tfm) return; } - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), tfm); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "HangDump", tfm); + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "HangDump", tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( $"--hangdump --hangdump-timeout 8s --results-directory {resultDirectory}", new Dictionary @@ -39,6 +32,7 @@ public async Task HangDump_DefaultSetting_CreateDump(string tfm) Assert.IsTrue(dumpFile is not null, $"Dump file not found '{tfm}'\n{testHostResult}'"); } + [TestMethod] public async Task HangDump_CustomFileName_CreateDump() { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -47,8 +41,8 @@ public async Task HangDump_CustomFileName_CreateDump() return; } - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent.Arguments); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent.Arguments); + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync( $"--hangdump --hangdump-timeout 8s --hangdump-filename myhungdumpfile_%p.dmp --results-directory {resultDirectory}", new Dictionary @@ -61,6 +55,7 @@ public async Task HangDump_CustomFileName_CreateDump() Assert.IsTrue(dumpFile is not null, $"Dump file not found '{TargetFrameworks.NetCurrent}'\n{testHostResult}'"); } + [TestMethod] public async Task HangDump_PathWithSpaces_CreateDump() { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -69,10 +64,10 @@ public async Task HangDump_PathWithSpaces_CreateDump() return; } - string resultDir = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent.Arguments); + string resultDir = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent); string resultDirectory = Path.Combine(resultDir, "directory with spaces"); Directory.CreateDirectory(resultDirectory); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent.Arguments); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync( $"""--hangdump --hangdump-timeout 8s --hangdump-filename myhungdumpfile_%p.dmp --results-directory "{resultDirectory}" """, new Dictionary @@ -85,10 +80,11 @@ public async Task HangDump_PathWithSpaces_CreateDump() Assert.IsTrue(dumpFile is not null, $"Dump file not found '{TargetFrameworks.NetCurrent}'\n{testHostResult}'"); } - [Arguments("Mini")] - [Arguments("Heap")] - [Arguments("Triage")] - [Arguments("Full")] + [DataRow("Mini")] + [DataRow("Heap")] + [DataRow("Triage")] + [DataRow("Full")] + [TestMethod] public async Task HangDump_Formats_CreateDump(string format) { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -97,8 +93,8 @@ public async Task HangDump_Formats_CreateDump(string format) return; } - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), format); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent.Arguments); + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), format); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync( $"--hangdump --hangdump-timeout 8s --hangdump-type {format} --results-directory {resultDirectory}", new Dictionary @@ -111,10 +107,11 @@ public async Task HangDump_Formats_CreateDump(string format) Assert.IsTrue(dumpFile is not null, $"Dump file not found '{format}'\n{testHostResult}'"); } + [TestMethod] public async Task HangDump_InvalidFormat_ShouldFail() { - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent.Arguments); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent.Arguments); + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), TargetFrameworks.NetCurrent); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "HangDump", TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync( $"--hangdump --hangdump-timeout 8s --hangdump-type invalid --results-directory {resultDirectory}", new Dictionary @@ -129,10 +126,9 @@ public async Task HangDump_InvalidFormat_ShouldFail() """); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { - private const string AssetName = "TestAssetFixture"; + private const string AssetName = "AssetFixture"; public string TargetAssetPath => GetAssetPath(AssetName); @@ -182,22 +178,22 @@ public class Startup public static async Task Main(string[] args) { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); - builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestAdapter()); + builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestFramework()); builder.AddHangDumpProvider(); using ITestApplication app = await builder.BuildAsync(); return await app.RunAsync(); } } -public class DummyTestAdapter : ITestFramework, IDataProducer +public class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs index 1f66b97679..5c6f2f5b98 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs @@ -1,23 +1,16 @@ // 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.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class HelpInfoTests : AcceptanceTestBase +[TestClass] +public class HelpInfoTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public HelpInfoTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Help_WhenNoExtensionRegistered_OutputDefaultHelpContent(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.NoExtensionAssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.NoExtensionAssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--help"); testHostResult.AssertExitCodeIs(ExitCodes.Success); @@ -72,17 +65,16 @@ Disable reporting progress to screen. --output Output verbosity when reporting tests. Valid values are 'Normal', 'Detailed'. Default is 'Normal'. - --treenode-filter - Use a tree filter to filter down the tests to execute """; testHostResult.AssertOutputMatchesLines(wildcardMatchPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task HelpShortName_WhenNoExtensionRegistered_OutputDefaultHelpContent(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.NoExtensionAssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.NoExtensionAssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--?"); testHostResult.AssertExitCodeIs(ExitCodes.Success); @@ -97,12 +89,13 @@ Execute a .NET Test Application. testHostResult.AssertOutputMatchesLines(wildcardMatchPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Help_WhenNoExtensionRegisteredAndUnknownOptionIsSpecified_OutputDefaultHelpContentAndUnknownOption(string tfm) { const string UnknownOption = "aaa"; - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.NoExtensionAssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.NoExtensionAssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync($"-{UnknownOption}"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); @@ -118,10 +111,11 @@ Execute a .NET Test Application. testHostResult.AssertOutputMatchesLines(wildcardMatchPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Info_WhenNoExtensionRegistered_OutputDefaultInfoContent(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.NoExtensionAssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.NoExtensionAssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--info"); testHostResult.AssertExitCodeIs(ExitCodes.Success); @@ -132,7 +126,7 @@ .NET Testing Platform v.+ \[.+\] Version: .+ Dynamic Code Supported: True Runtime information: .+ - {(tfm != TargetFrameworks.NetFramework[0].Arguments ? "###SKIP###" : $"Runtime location: .+")} + {(tfm != TargetFrameworks.NetFramework[0] ? "###SKIP###" : $"Runtime location: .+")} Test module: .+{TestAssetFixture.NoExtensionAssetName}.* Built-in command line providers: PlatformCommandLineProvider @@ -260,15 +254,6 @@ Takes one argument as string in the format \[h\|m\|s\] where 'value' is f Hidden: False Description: Output verbosity when reporting tests. Valid values are 'Normal', 'Detailed'. Default is 'Normal'. - TestingFrameworkExtension - Name: Microsoft Testing Framework - Version: .+ - Description: Microsoft Testing Framework\. This framework allows you to test your code anywhere in any mode \(all OSes, all platforms, all configurations\.\.\.\)\. - Options: - --treenode-filter - Arity: 1 - Hidden: False - Description: Use a tree filter to filter down the tests to execute Registered tools: There are no registered tools\. """; @@ -276,10 +261,11 @@ There are no registered tools\. testHostResult.AssertOutputMatchesRegexLines(regexMatchPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Help_WithAllExtensionsRegistered_OutputFullHelpContent(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.AllExtensionsTargetAssetPath, TestAssetFixture.AllExtensionsAssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.AllExtensionsTargetAssetPath, TestAssetFixture.AllExtensionsAssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--help"); testHostResult.AssertExitCodeIs(ExitCodes.Success); @@ -367,17 +353,16 @@ Output verbosity when reporting tests. Enable generating TRX report --report-trx-filename The name of the generated TRX report - --treenode-filter - Use a tree filter to filter down the tests to execute """; testHostResult.AssertOutputMatchesLines(wildcardPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task HelpShortName_WithAllExtensionsRegistered_OutputFullHelpContent(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.AllExtensionsTargetAssetPath, TestAssetFixture.AllExtensionsAssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.AllExtensionsTargetAssetPath, TestAssetFixture.AllExtensionsAssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("-?"); testHostResult.AssertExitCodeIs(ExitCodes.Success); @@ -392,10 +377,11 @@ Execute a .NET Test Application. testHostResult.AssertOutputMatchesLines(wildcardPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Info_WithAllExtensionsRegistered_OutputFullInfoContent(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.AllExtensionsTargetAssetPath, TestAssetFixture.AllExtensionsAssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.AllExtensionsTargetAssetPath, TestAssetFixture.AllExtensionsAssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--info"); testHostResult.AssertExitCodeIs(ExitCodes.Success); @@ -406,7 +392,7 @@ .NET Testing Platform v* [*] Version: * Dynamic Code Supported: True Runtime information: * - {(tfm != TargetFrameworks.NetFramework[0].Arguments ? "###SKIP###" : $"Runtime location: *")} + {(tfm != TargetFrameworks.NetFramework[0] ? "###SKIP###" : $"Runtime location: *")} Test module: *{TestAssetFixture.AllExtensionsAssetName}* Built-in command line providers: PlatformCommandLineProvider @@ -563,6 +549,15 @@ Default is 30m. Description: Specify the type of the dump. Valid values are 'Mini', 'Heap', 'Triage' (only available in .NET 6+) or 'Full'. Default type is 'Full' + MSBuildCommandLineProvider + Name: MSBuildCommandLineProvider + Version: * + Description: Extension used to pass parameters from MSBuild node and the hosts + Options: + --internal-msbuild-node + Arity: 1 + Hidden: True + Description: Used to pass the MSBuild node handle RetryCommandLineOptionsProvider Name: Retry failed tests Version: * @@ -602,15 +597,6 @@ Default type is 'Full' Hidden: False Description: Output verbosity when reporting tests. Valid values are 'Normal', 'Detailed'. Default is 'Normal'. - TestingFrameworkExtension - Name: Microsoft Testing Framework - Version: * - Description: Microsoft Testing Framework. This framework allows you to test your code anywhere in any mode (all OSes, all platforms, all configurations...). - Options: - --treenode-filter - Arity: 1 - Hidden: False - Description: Use a tree filter to filter down the tests to execute TrxReportGeneratorCommandLine Name: TRX report generator Version: * @@ -649,8 +635,7 @@ Default type is 'Full' testHostResult.AssertOutputMatchesLines(wildcardPattern); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string AllExtensionsAssetName = "AllExtensionsInfoTest"; public const string NoExtensionAssetName = "NoExtensionInfoTest"; @@ -664,13 +649,10 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test enable Exe preview + false - - - - - + @@ -680,33 +662,47 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test #file Program.cs -using AllExtensionsInfoTest; -ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new SourceGeneratedTestNodesBuilder()); -builder.AddCrashDumpProvider(); -builder.AddHangDumpProvider(); -builder.AddHotReloadProvider(); -builder.AddRetryProvider(); -builder.AddTrxReportProvider(); -using ITestApplication app = await builder.BuildAsync(); -return await app.RunAsync(); - -#file UnitTest1.cs -namespace AllExtensionsInfoTest; - -[TestGroup] -public class UnitTest1 +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.Services; + +public class Program { - public void TestMethod1() + public static async Task Main(string[] args) { - Assert.IsTrue(true); + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + builder.RegisterTestFramework( + sp => new TestFrameworkCapabilities(), + (_,__) => new DummyTestFramework()); + builder.AddSelfRegisteredExtensions(args); + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); } } -#file Usings.cs -global using Microsoft.Testing.Platform.Builder; -global using Microsoft.Testing.Internal.Framework; -global using Microsoft.Testing.Extensions; +public class DummyTestFramework : ITestFramework +{ + public string Uid => nameof(DummyTestFramework); + + public string Version => "2.0.0"; + + public string DisplayName => nameof(DummyTestFramework); + + public string Description => nameof(DummyTestFramework); + + public Task IsEnabledAsync() => Task.FromResult(true); + + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + public Task ExecuteRequestAsync(ExecuteRequestContext context) + { + context.Complete(); + return Task.CompletedTask; + } +} """; private const string NoExtensionTestCode = """ @@ -721,37 +717,51 @@ public void TestMethod1() preview - - - - #file Program.cs -using NoExtensionInfoTest; -ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new SourceGeneratedTestNodesBuilder()); -using ITestApplication app = await builder.BuildAsync(); -return await app.RunAsync(); - -#file UnitTest1.cs -namespace NoExtensionInfoTest; +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.Services; -[TestGroup] -public class UnitTest1 +public class Program { - public void TestMethod1() + public static async Task Main(string[] args) { - Assert.IsTrue(true); + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + builder.RegisterTestFramework( + sp => new TestFrameworkCapabilities(), + (_,__) => new DummyTestFramework()); + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); } } -#file Usings.cs -global using Microsoft.Testing.Platform.Builder; -global using Microsoft.Testing.Internal.Framework; -global using Microsoft.Testing.Extensions; +public class DummyTestFramework : ITestFramework +{ + public string Uid => nameof(DummyTestFramework); + + public string Version => "2.0.0"; + + public string DisplayName => nameof(DummyTestFramework); + + public string Description => nameof(DummyTestFramework); + + public Task IsEnabledAsync() => Task.FromResult(true); + + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + public Task ExecuteRequestAsync(ExecuteRequestContext context) + { + context.Complete(); + return Task.CompletedTask; + } +} """; public string NoExtensionTargetAssetPath => GetAssetPath(NoExtensionAssetName); @@ -764,14 +774,12 @@ public void TestMethod1() NoExtensionTestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); yield return (AllExtensionsAssetName, AllExtensionsAssetName, AllExtensionsTestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); } } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs index a5ec05d244..737af51263 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs @@ -10,10 +10,10 @@ namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; internal static class AcceptanceAssert { public static void AssertExitCodeIs(this TestHostResult testHostResult, int exitCode, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) - => Assert.That(exitCode == testHostResult.ExitCode, GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + => Assert.AreEqual(exitCode, testHostResult.ExitCode, GenerateFailedAssertionMessage(testHostResult, callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber)); public static void AssertExitCodeIsNot(this TestHostResult testHostResult, int exitCode, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) - => Assert.That(exitCode != testHostResult.ExitCode, GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + => Assert.AreNotEqual(exitCode, testHostResult.ExitCode, GenerateFailedAssertionMessage(testHostResult, callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber)); /// /// Ensure that the output matches the given pattern. The pattern can use `*` to mean any character, it is internally replaced by `.*` and matched as regex. @@ -40,22 +40,15 @@ public static void AssertOutputMatchesLines(this TestHostResult testHostResult, + Regex.Escape(wildcardLines[i]).Replace("\\*", ".*") + "$"; - Assert.That( + Assert.IsTrue( Regex.IsMatch(outputLine, matchingPatternLine, RegexOptions.Singleline), - $"Output on line {j + 1}{Environment.NewLine}{outputLine}{Environment.NewLine}doesn't match pattern{Environment.NewLine}{matchingPatternLine}{Environment.NewLine}Standard output:{Environment.NewLine}{testHostResult.StandardOutput}", - callerMemberName: callerMemberName, - callerFilePath: callerFilePath, - callerLineNumber: callerLineNumber); + $"Output on line {j + 1}{Environment.NewLine}{outputLine}{Environment.NewLine}doesn't match pattern{Environment.NewLine}{matchingPatternLine}{Environment.NewLine}Standard output:{Environment.NewLine}{testHostResult.StandardOutput}{Environment.NewLine}for member '{callerMemberName}' at line {callerLineNumber} of file '{callerFilePath}'."); } else { string expectedLine = wildcardLines[i]; - Assert.That( - string.Equals(outputLine, expectedLine, StringComparison.Ordinal), - $"Output on line {j + 1} (length: {outputLine.Length}){Environment.NewLine}{outputLine}{Environment.NewLine}doesn't match line (length: {expectedLine.Length}){Environment.NewLine}{expectedLine}{Environment.NewLine}Standard output:{Environment.NewLine}{testHostResult.StandardOutput}", - callerMemberName: callerMemberName, - callerFilePath: callerFilePath, - callerLineNumber: callerLineNumber); + Assert.AreEqual(expectedLine, outputLine, StringComparer.Ordinal, + $"Output on line {j + 1} (length: {outputLine.Length}){Environment.NewLine}{outputLine}{Environment.NewLine}doesn't match line (length: {expectedLine.Length}){Environment.NewLine}{expectedLine}{Environment.NewLine}Standard output:{Environment.NewLine}{testHostResult.StandardOutput}{Environment.NewLine}for member '{callerMemberName}' at line {callerLineNumber} of file '{callerFilePath}'."); } j++; @@ -79,42 +72,39 @@ public static void AssertOutputMatchesRegexLines(this TestHostResult testHostRes } string outputLine = testHostResult.StandardOutputLines[j]; - Assert.That( + Assert.IsTrue( Regex.IsMatch(outputLine, patternLines[i], RegexOptions.Singleline), - $"Output on line {j + 1}{Environment.NewLine}{outputLine}{Environment.NewLine}doesn't match pattern{Environment.NewLine}{patternLines[i]}{Environment.NewLine}Standard output:{Environment.NewLine}{testHostResult.StandardOutput}", - callerMemberName: callerMemberName, - callerFilePath: callerFilePath, - callerLineNumber: callerLineNumber); + $"Output on line {j + 1}{Environment.NewLine}{outputLine}{Environment.NewLine}doesn't match pattern{Environment.NewLine}{patternLines[i]}{Environment.NewLine}Standard output:{Environment.NewLine}{testHostResult.StandardOutput}{Environment.NewLine}for member '{callerMemberName}' at line {callerLineNumber} of file '{callerFilePath}'."); j++; } } public static void AssertOutputMatchesRegex(this TestHostResult testHostResult, [StringSyntax("Regex")] string pattern, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) - => Assert.That(Regex.IsMatch(testHostResult.StandardOutput, pattern), GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + => Assert.IsTrue(Regex.IsMatch(testHostResult.StandardOutput, pattern), GenerateFailedAssertionMessage(testHostResult, callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber)); public static void AssertOutputMatchesRegex(this TestHostResult testHostResult, [StringSyntax("Regex")] string pattern, RegexOptions regexOptions, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) - => Assert.That(Regex.IsMatch(testHostResult.StandardOutput, pattern, regexOptions), GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + => Assert.IsTrue(Regex.IsMatch(testHostResult.StandardOutput, pattern, regexOptions), GenerateFailedAssertionMessage(testHostResult, callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber)); public static void AssertOutputDoesNotMatchRegex(this TestHostResult testHostResult, [StringSyntax("Regex")] string pattern, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) - => Assert.That(!Regex.IsMatch(testHostResult.StandardOutput, pattern), GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + => Assert.IsFalse(Regex.IsMatch(testHostResult.StandardOutput, pattern), GenerateFailedAssertionMessage(testHostResult, callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber)); public static void AssertOutputContains(this TestHostResult testHostResult, string value, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) - => Assert.That(testHostResult.StandardOutput.Contains(value, StringComparison.Ordinal), GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + => StringAssert.Contains(testHostResult.StandardOutput, value, GenerateFailedAssertionMessage(testHostResult, callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber), StringComparison.Ordinal); public static void AssertOutputContains(this DotnetMuxerResult dotnetMuxerResult, string value, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) - => Assert.That(dotnetMuxerResult.StandardOutput.Contains(value, StringComparison.Ordinal), GenerateFailedAssertionMessage(dotnetMuxerResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + => StringAssert.Contains(dotnetMuxerResult.StandardOutput, value, GenerateFailedAssertionMessage(dotnetMuxerResult, callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber), StringComparison.Ordinal); - public static void AssertOutputNotContains(this DotnetMuxerResult dotnetMuxerResult, string value, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) - => Assert.That(!dotnetMuxerResult.StandardOutput.Contains(value, StringComparison.Ordinal), GenerateFailedAssertionMessage(dotnetMuxerResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + public static void AssertOutputDoesNotContain(this DotnetMuxerResult dotnetMuxerResult, string value, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) + => Assert.IsFalse(dotnetMuxerResult.StandardOutput.Contains(value, StringComparison.Ordinal), GenerateFailedAssertionMessage(dotnetMuxerResult, callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber)); - public static void AssertOutputRegEx(this DotnetMuxerResult dotnetMuxerResult, [StringSyntax("Regex")] string pattern, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) - => Assert.That(Regex.IsMatch(dotnetMuxerResult.StandardOutput, pattern), GenerateFailedAssertionMessage(dotnetMuxerResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + public static void AssertOutputMatchesRegex(this DotnetMuxerResult dotnetMuxerResult, [StringSyntax("Regex")] string pattern, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) + => Assert.IsTrue(Regex.IsMatch(dotnetMuxerResult.StandardOutput, pattern), GenerateFailedAssertionMessage(dotnetMuxerResult, callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber)); public static void AssertOutputDoesNotContain(this TestHostResult testHostResult, string value, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) - => Assert.That(!testHostResult.StandardOutput.Contains(value, StringComparison.Ordinal), GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + => Assert.IsFalse(testHostResult.StandardOutput.Contains(value, StringComparison.Ordinal), GenerateFailedAssertionMessage(testHostResult, callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber)); public static void AssertStandardErrorContains(this TestHostResult testHostResult, string value, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) - => Assert.That(testHostResult.StandardError.Contains(value, StringComparison.Ordinal), GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + => StringAssert.Contains(testHostResult.StandardError, value, GenerateFailedAssertionMessage(testHostResult, callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber), StringComparison.Ordinal); public static void AssertOutputContainsSummary(this TestHostResult testHostResult, int failed, int passed, int skipped, bool? aborted = false, int? minimumNumberOfTests = null, [CallerMemberName] string? callerMemberName = null, [CallerFilePath] string? callerFilePath = null, [CallerLineNumber] int callerLineNumber = 0) { @@ -136,13 +126,13 @@ public static void AssertOutputContainsSummary(this TestHostResult testHostResul succeeded: {passed} skipped: {skipped} """; - Assert.That(testHostResult.StandardOutput.Contains(summaryResult, StringComparison.Ordinal), GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); - Assert.That(testHostResult.StandardOutput.Contains(summaryCounts, StringComparison.Ordinal), GenerateFailedAssertionMessage(testHostResult), callerMemberName: callerMemberName, callerFilePath: callerFilePath, callerLineNumber: callerLineNumber); + Assert.IsTrue(testHostResult.StandardOutput.Contains(summaryResult, StringComparison.Ordinal), GenerateFailedAssertionMessage(testHostResult, callerMemberName, callerFilePath, callerLineNumber)); + Assert.IsTrue(testHostResult.StandardOutput.Contains(summaryCounts, StringComparison.Ordinal), GenerateFailedAssertionMessage(testHostResult, callerMemberName, callerFilePath, callerLineNumber)); } - private static string GenerateFailedAssertionMessage(TestHostResult testHostResult) - => $"Output of the test host is:\n{testHostResult}"; + private static string GenerateFailedAssertionMessage(TestHostResult testHostResult, string? callerMemberName, string? callerFilePath, int callerLineNumber, [CallerMemberName] string? assertCallerMemberName = null) + => $"Expression '{assertCallerMemberName}' failed for member '{callerMemberName}' at line {callerLineNumber} of file '{callerFilePath}'. Output of the test host is:{Environment.NewLine}{testHostResult}"; - private static string GenerateFailedAssertionMessage(DotnetMuxerResult dotnetMuxerResult) - => $"Output of the dotnet muxer is:\n{dotnetMuxerResult}"; + private static string GenerateFailedAssertionMessage(DotnetMuxerResult dotnetMuxerResult, string? callerMemberName, string? callerFilePath, int callerLineNumber, [CallerMemberName] string? assertCallerMemberName = null) + => $"Expression '{assertCallerMemberName}' failed for member '{callerMemberName}' at line {callerLineNumber} of file '{callerFilePath}'. Output of the dotnet muxer is:{Environment.NewLine}{dotnetMuxerResult}"; } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceFixture.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceFixture.cs index 007fc22af7..1783ebe6a1 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceFixture.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceFixture.cs @@ -3,11 +3,16 @@ namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestFixture(TestFixtureSharingStrategy.PerTestApplication)] -public sealed class AcceptanceFixture : IDisposable +[TestClass] +public static class AcceptanceFixture { - public TempDirectory NuGetGlobalPackagesFolder { get; } = new(".packages"); + public static TempDirectory NuGetGlobalPackagesFolder { get; private set; } = null!; - public void Dispose() + [AssemblyInitialize] + public static void AssemblyInitialize(TestContext context) + => NuGetGlobalPackagesFolder = new(".packages"); + + [AssemblyCleanup] + public static void AssemblyCleanup() => NuGetGlobalPackagesFolder.Dispose(); } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs index 093d37d5b9..7c64902ec6 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs @@ -1,18 +1,15 @@ // 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.Diagnostics.CodeAnalysis; using System.Globalization; using System.Runtime.InteropServices; using System.Xml.Linq; namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -/// -/// All the properties of this class should be non static. -/// At the moment are static because we need to share them between perclass/id fixtures and -/// it's not supported at the moment. -/// -public abstract class AcceptanceTestBase : TestBase +public abstract class AcceptanceTestBase + where TFixture : ITestAssetFixture, new() { private const string NuGetPackageExtensionName = ".nupkg"; @@ -62,14 +59,10 @@ static AcceptanceTestBase() MSTestVersion = ExtractVersionFromPackage(Constants.ArtifactsPackagesShipping, "MSTest.TestFramework."); MicrosoftTestingPlatformVersion = ExtractVersionFromPackage(Constants.ArtifactsPackagesShipping, "Microsoft.Testing.Platform."); MicrosoftTestingEnterpriseExtensionsVersion = ExtractVersionFromXmlFile(versionsPropsFileDoc, "MicrosoftTestingExtensionsRetryVersion"); - MicrosoftTestingInternalFrameworkVersion = ExtractVersionFromXmlFile(directoryPackagesPropsFileDoc, "MicrosoftTestingInternalFrameworkVersion"); MSTestEngineVersion = ExtractVersionFromXmlFile(versionsPropsFileDoc, "MSTestEngineVersion"); } - protected AcceptanceTestBase(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } + protected static TFixture AssetFixture { get; private set; } = default!; internal static string RID { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) @@ -90,61 +83,70 @@ protected AcceptanceTestBase(ITestExecutionContext testExecutionContext) public static string MicrosoftTestingEnterpriseExtensionsVersion { get; private set; } - public static string MicrosoftTestingInternalFrameworkVersion { get; private set; } + [ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)] + [SuppressMessage("Design", "CA1000:Do not declare static members on generic types", Justification = "Fine in this context")] + public static async Task ClassInitialize(TestContext testContext) + { + AssetFixture = new(); + await AssetFixture.InitializeAsync(); + } + + [ClassCleanup(InheritanceBehavior.BeforeEachDerivedClass)] + [SuppressMessage("Design", "CA1000:Do not declare static members on generic types", Justification = "Fine in this context")] + public static void ClassCleanup() + => AssetFixture.Dispose(); - internal static IEnumerable> GetBuildMatrixTfmBuildVerbConfiguration() + internal static IEnumerable<(string Tfm, BuildConfiguration BuildConfiguration, Verb Verb)> GetBuildMatrixTfmBuildVerbConfiguration() { - foreach (TestArgumentsEntry tfm in TargetFrameworks.All) + foreach (string tfm in TargetFrameworks.All) { foreach (BuildConfiguration compilationMode in Enum.GetValues()) { foreach (Verb verb in Enum.GetValues()) { - yield return new TestArgumentsEntry<(string Tfm, BuildConfiguration BuildConfiguration, Verb Verb)>((tfm.Arguments, compilationMode, verb), $"{tfm.Arguments},{compilationMode},{verb}"); + yield return new(tfm, compilationMode, verb); } } } } - internal static IEnumerable> GetBuildMatrixTfmBuildConfiguration() + internal static IEnumerable<(string Tfm, BuildConfiguration BuildConfiguration)> GetBuildMatrixTfmBuildConfiguration() { - foreach (TestArgumentsEntry tfm in TargetFrameworks.All) + foreach (string tfm in TargetFrameworks.All) { foreach (BuildConfiguration compilationMode in Enum.GetValues()) { - yield return new TestArgumentsEntry<(string Tfm, BuildConfiguration BuildConfiguration)>((tfm.Arguments, compilationMode), $"{tfm.Arguments},{compilationMode}"); + yield return new(tfm, compilationMode); } } } - internal static IEnumerable> GetBuildMatrixMultiTfmFoldedBuildConfiguration() + internal static IEnumerable<(string MultiTfm, BuildConfiguration BuildConfiguration)> GetBuildMatrixMultiTfmFoldedBuildConfiguration() { foreach (BuildConfiguration compilationMode in Enum.GetValues()) { - yield return new TestArgumentsEntry<(string MultiTfm, BuildConfiguration BuildConfiguration)>((TargetFrameworks.All.ToMSBuildTargetFrameworks(), compilationMode), $"multitfm,{compilationMode}"); + yield return new(TargetFrameworks.All.ToMSBuildTargetFrameworks(), compilationMode); } } - internal static IEnumerable> GetBuildMatrixMultiTfmBuildConfiguration() + internal static IEnumerable<(string MultiTfm, BuildConfiguration BuildConfiguration)> GetBuildMatrixMultiTfmBuildConfiguration() { foreach (BuildConfiguration compilationMode in Enum.GetValues()) { - yield return new TestArgumentsEntry<(string MultiTfm, BuildConfiguration BuildConfiguration)>((TargetFrameworks.All.ToMSBuildTargetFrameworks(), compilationMode), $"{TargetFrameworks.All.ToMSBuildTargetFrameworks()},{compilationMode}"); + yield return new(TargetFrameworks.All.ToMSBuildTargetFrameworks(), compilationMode); } } - internal static IEnumerable> GetBuildMatrixSingleAndMultiTfmBuildConfiguration() + internal static IEnumerable<(string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm)> GetBuildMatrixSingleAndMultiTfmBuildConfiguration() { - foreach (TestArgumentsEntry<(string Tfm, BuildConfiguration BuildConfiguration)> entry in GetBuildMatrixTfmBuildConfiguration()) + foreach ((string Tfm, BuildConfiguration BuildConfiguration) entry in GetBuildMatrixTfmBuildConfiguration()) { - yield return new TestArgumentsEntry<(string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm)>( - (entry.Arguments.Tfm, entry.Arguments.BuildConfiguration, false), $"{entry.Arguments.Tfm},{entry.Arguments.BuildConfiguration}"); + yield return new(entry.Tfm, entry.BuildConfiguration, false); } - foreach (TestArgumentsEntry<(string MultiTfm, BuildConfiguration BuildConfiguration)> entry in GetBuildMatrixMultiTfmBuildConfiguration()) + foreach ((string MultiTfm, BuildConfiguration BuildConfiguration) entry in GetBuildMatrixMultiTfmBuildConfiguration()) { - yield return new TestArgumentsEntry<(string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm)>( - (entry.Arguments.MultiTfm, entry.Arguments.BuildConfiguration, true), $"multitfm,{entry.Arguments.BuildConfiguration}"); + yield return new(entry.MultiTfm, entry.BuildConfiguration, true); } } @@ -160,13 +162,13 @@ private static string ExtractVersionFromPackage(string rootFolder, string packag // So we need to find a package that contains a number after the prefix. // Ideally, we would want to do a full validation to check this is a nuget version number, but that's too much work for now. matches = matches - // (full path, file name without prefix) - .Select(path => (path, fileName: Path.GetFileName(path)[packagePrefixName.Length..])) - // check if first character of file name without prefix is number - .Where(tuple => int.TryParse(tuple.fileName[0].ToString(), CultureInfo.InvariantCulture, out _)) - // take the full path - .Select(tuple => tuple.path) - .ToArray(); + // (full path, file name without prefix) + .Select(path => (path, fileName: Path.GetFileName(path)[packagePrefixName.Length..])) + // check if first character of file name without prefix is number + .Where(tuple => int.TryParse(tuple.fileName[0].ToString(), CultureInfo.InvariantCulture, out _)) + // take the full path + .Select(tuple => tuple.path) + .ToArray(); } if (matches.Length != 1) diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/IgnoreExitCodeTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/IgnoreExitCodeTests.cs index b1b27a3e97..50bf5178bf 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/IgnoreExitCodeTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/IgnoreExitCodeTests.cs @@ -1,13 +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.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class IgnoreExitCodeTests : AcceptanceTestBase +[TestClass] +public class IgnoreExitCodeTests : AcceptanceTestBase { private const string AssetName = "TestProject"; @@ -43,21 +40,21 @@ public class Startup public static async Task Main(string[] args) { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); - builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestAdapter()); + builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestFramework()); using ITestApplication app = await builder.BuildAsync(); return await app.RunAsync(); } } -public class DummyTestAdapter : ITestFramework, IDataProducer +public class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); @@ -83,21 +80,17 @@ public async Task ExecuteRequestAsync(ExecuteRequestContext context) } """; - private readonly AcceptanceFixture _acceptanceFixture; - - public IgnoreExitCodeTests(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - - public static IEnumerable> GetBuildMatrix() + public static IEnumerable<(string Tfm, BuildConfiguration BuildConfiguration, string CommandLine, string EnvironmentVariable)> GetBuildMatrix() { - foreach (TestArgumentsEntry<(string Tfm, BuildConfiguration BuildConfiguration)> buildConfig in GetBuildMatrixTfmBuildConfiguration()) + foreach ((string Tfm, BuildConfiguration BuildConfiguration) buildConfig in GetBuildMatrixTfmBuildConfiguration()) { - yield return new TestArgumentsEntry<(string, BuildConfiguration, string, string)>((buildConfig.Arguments.Tfm, buildConfig.Arguments.BuildConfiguration, "--ignore-exit-code 2", string.Empty), $"{buildConfig.Arguments.Tfm},{buildConfig.Arguments.BuildConfiguration},CommandLine"); - yield return new TestArgumentsEntry<(string, BuildConfiguration, string, string)>((buildConfig.Arguments.Tfm, buildConfig.Arguments.BuildConfiguration, string.Empty, "2"), $"{buildConfig.Arguments.Tfm},{buildConfig.Arguments.BuildConfiguration},EnvironmentVariable"); + yield return new(buildConfig.Tfm, buildConfig.BuildConfiguration, "--ignore-exit-code 2", string.Empty); + yield return new(buildConfig.Tfm, buildConfig.BuildConfiguration, string.Empty, "2"); } } - [ArgumentsProvider(nameof(GetBuildMatrix))] + [DynamicData(nameof(GetBuildMatrix), DynamicDataSourceType.Method)] + [TestMethod] public async Task If_IgnoreExitCode_Specified_Should_Return_Success_ExitCode(string tfm, BuildConfiguration buildConfiguration, string commandLine, string environmentVariable) { using TestAsset generator = await TestAsset.GenerateAssetAsync( @@ -107,7 +100,7 @@ public async Task If_IgnoreExitCode_Specified_Should_Return_Success_ExitCode(str .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); string assetPath = generator.TargetAssetPath; - string globalPackagesPath = _acceptanceFixture.NuGetGlobalPackagesFolder.Path; + string globalPackagesPath = AcceptanceFixture.NuGetGlobalPackagesFolder.Path; await DotnetCli.RunAsync($"restore -m:1 -nodeReuse:false {assetPath} -r {RID}", globalPackagesPath); await DotnetCli.RunAsync($"build -m:1 -nodeReuse:false {assetPath} -c {buildConfiguration} -r {RID}", globalPackagesPath); var host = TestInfrastructure.TestHost.LocateFrom(assetPath, AssetName, tfm, buildConfiguration: buildConfiguration); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuild.KnownExtensionRegistration.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuild.KnownExtensionRegistration.cs index 8ed4ecc05e..8ef8d9c03c 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuild.KnownExtensionRegistration.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuild.KnownExtensionRegistration.cs @@ -1,22 +1,17 @@ // 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.Testing.Platform.Acceptance.IntegrationTests.Helpers; - using SL = Microsoft.Build.Logging.StructuredLogger; namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class MSBuildTests_KnownExtensionRegistration : AcceptanceTestBase +[TestClass] +public class MSBuildTests_KnownExtensionRegistration : AcceptanceTestBase { - private readonly AcceptanceFixture _acceptanceFixture; private const string AssetName = "MSBuildTests"; - public MSBuildTests_KnownExtensionRegistration(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildVerbConfiguration))] + [DynamicData(nameof(GetBuildMatrixTfmBuildVerbConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] + [TestMethod] public async Task Microsoft_Testing_Platform_Extensions_ShouldBe_Correctly_Registered(string tfm, BuildConfiguration compilationMode, Verb verb) { TestAsset testAsset = await TestAsset.GenerateAssetAsync( @@ -26,8 +21,8 @@ public async Task Microsoft_Testing_Platform_Extensions_ShouldBe_Correctly_Regis .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); - await DotnetCli.RunAsync($"restore -r {RID} {testAsset.TargetAssetPath}{Path.DirectorySeparatorChar}MSBuildTests.csproj", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); - await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -c {compilationMode} -r {RID} -nodeReuse:false -bl:{binlogFile} {testAsset.TargetAssetPath} -v:n", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + await DotnetCli.RunAsync($"restore -r {RID} {testAsset.TargetAssetPath}{Path.DirectorySeparatorChar}MSBuildTests.csproj", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); + await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -c {compilationMode} -r {RID} -nodeReuse:false -bl:{binlogFile} {testAsset.TargetAssetPath} -v:n", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); var testHost = TestInfrastructure.TestHost.LocateFrom(testAsset.TargetAssetPath, AssetName, tfm, rid: RID, verb: verb, buildConfiguration: compilationMode); TestHostResult testHostResult = await testHost.ExecuteAsync("--help"); @@ -55,8 +50,8 @@ public async Task Microsoft_Testing_Platform_Extensions_ShouldBe_Correctly_Regis - DummyAdapter - MyNamespaceRoot.Level1.Level2.DummyAdapterRegistration + DummyTestFramework + MyNamespaceRoot.Level1.Level2.DummyTestFrameworkRegistration @@ -93,17 +88,17 @@ public async Task Microsoft_Testing_Platform_Extensions_ShouldBe_Correctly_Regis namespace MyNamespaceRoot.Level1.Level2; -public static class DummyAdapterRegistration +public static class DummyTestFrameworkRegistration { public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, string[] args) { - testApplicationBuilder.RegisterTestFramework(_ => new Capabilities(), (_, __) => new DummyAdapter()); + testApplicationBuilder.RegisterTestFramework(_ => new Capabilities(), (_, __) => new DummyTestFramework()); } } -internal sealed class DummyAdapter : ITestFramework, IDataProducer +internal sealed class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => string.Empty; diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs index 8d3e9286c2..8040163b92 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs @@ -5,13 +5,11 @@ namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class MSBuildTests : AcceptanceTestBase +[TestClass] +public class MSBuildTests : AcceptanceTestBase { - public MSBuildTests(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildVerbConfiguration))] + [DynamicData(nameof(GetBuildMatrixTfmBuildVerbConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] + [TestMethod] public async Task ConfigFileGeneration_CorrectlyCreateAndCacheAndCleaned(string tfm, BuildConfiguration compilationMode, Verb verb) { using TestAsset testAsset = await TestAsset.GenerateAssetAsync( @@ -20,10 +18,9 @@ public async Task ConfigFileGeneration_CorrectlyCreateAndCacheAndCleaned(string .PatchCodeWithReplace("$TargetFrameworks$", tfm) .PatchCodeWithReplace("$JsonContent$", ConfigurationContent) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -v:normal -nodeReuse:false {testAsset.TargetAssetPath} -c {compilationMode}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -v:normal -nodeReuse:false {testAsset.TargetAssetPath} -c {compilationMode}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); var testHost = TestInfrastructure.TestHost.LocateFrom(testAsset.TargetAssetPath, "MSBuildTests", tfm, verb: verb, buildConfiguration: compilationMode); string generatedConfigurationFile = Path.Combine(testHost.DirectoryName, "MSBuildTests.testconfig.json"); @@ -31,7 +28,7 @@ public async Task ConfigFileGeneration_CorrectlyCreateAndCacheAndCleaned(string Assert.AreEqual(ConfigurationContent.Trim(), File.ReadAllText(generatedConfigurationFile).Trim()); Assert.IsTrue(compilationResult.StandardOutput.Contains("Microsoft Testing Platform configuration file written")); - compilationResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -v:normal -nodeReuse:false {testAsset.TargetAssetPath} -c {compilationMode}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + compilationResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -v:normal -nodeReuse:false {testAsset.TargetAssetPath} -c {compilationMode}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); Assert.IsTrue(File.Exists(generatedConfigurationFile)); Assert.AreEqual(ConfigurationContent.Trim(), File.ReadAllText(generatedConfigurationFile).Trim()); compilationResult.StandardOutput.Contains("Microsoft Testing Platform configuration file written"); @@ -41,7 +38,7 @@ public async Task ConfigFileGeneration_CorrectlyCreateAndCacheAndCleaned(string \s*GenerateTestingPlatformConfigurationFile: \s*Skipping target "GenerateTestingPlatformConfigurationFile" because all output files are up\-to\-date with respect to the input files\. """)); - await DotnetCli.RunAsync($"clean -c {compilationMode} -v:normal {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + await DotnetCli.RunAsync($"clean -c {compilationMode} -v:normal {testAsset.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); // dotnet clean doesn't clean the publish output folder if (verb == Verb.build) @@ -50,7 +47,8 @@ public async Task ConfigFileGeneration_CorrectlyCreateAndCacheAndCleaned(string } } - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildVerbConfiguration))] + [DynamicData(nameof(GetBuildMatrixTfmBuildVerbConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] + [TestMethod] public async Task ConfigFileGeneration_NoConfigurationFile_TaskWontRun(string tfm, BuildConfiguration compilationMode, Verb verb) { using TestAsset testAsset = await TestAsset.GenerateAssetAsync( @@ -59,12 +57,11 @@ public async Task ConfigFileGeneration_NoConfigurationFile_TaskWontRun(string tf .PatchCodeWithReplace("$TargetFrameworks$", tfm) .PatchCodeWithReplace("$JsonContent$", ConfigurationContent) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); File.Delete(Path.Combine(testAsset.TargetAssetPath, "testconfig.json")); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -v:diagnostic -nodeReuse:false {testAsset.TargetAssetPath} -c {compilationMode}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -v:diagnostic -nodeReuse:false {testAsset.TargetAssetPath} -c {compilationMode}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); var testHost = TestInfrastructure.TestHost.LocateFrom(testAsset.TargetAssetPath, "MSBuildTests", tfm, verb: verb, buildConfiguration: compilationMode); Assert.IsTrue(compilationResult.StandardOutput.Contains("Target \"GenerateTestingPlatformConfigurationFile\" skipped, due to false condition;")); @@ -94,11 +91,6 @@ public async Task ConfigFileGeneration_NoConfigurationFile_TaskWontRun(string tf - - - - - @@ -106,28 +98,45 @@ public async Task ConfigFileGeneration_NoConfigurationFile_TaskWontRun(string tf $JsonContent$ #file Program.cs -using MSBuildTests; -ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new SourceGeneratedTestNodesBuilder()); -using ITestApplication app = await builder.BuildAsync(); -return await app.RunAsync(); - -#file UnitTest1.cs -namespace MSBuildTests; +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.Services; -[TestGroup] -public class UnitTest1 +public class Program { - public void TestMethod1() + public static async Task Main(string[] args) { - Assert.IsTrue(true); + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + builder.RegisterTestFramework( + sp => new TestFrameworkCapabilities(), + (_,__) => new DummyTestFramework()); + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); } } -#file Usings.cs -global using Microsoft.Testing.Platform.Builder; -global using Microsoft.Testing.Internal.Framework; -"""; +public class DummyTestFramework : ITestFramework +{ + public string Uid => nameof(DummyTestFramework); + + public string Version => "2.0.0"; + + public string DisplayName => nameof(DummyTestFramework); - private readonly AcceptanceFixture _acceptanceFixture; + public string Description => nameof(DummyTestFramework); + + public Task IsEnabledAsync() => Task.FromResult(true); + + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + public Task ExecuteRequestAsync(ExecuteRequestContext context) + { + context.Complete(); + return Task.CompletedTask; + } +} +"""; } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.GenerateEntryPoint.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.GenerateEntryPoint.cs index 8d1f11f367..9f87d0df98 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.GenerateEntryPoint.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.GenerateEntryPoint.cs @@ -1,23 +1,17 @@ // 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.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - using SL = Microsoft.Build.Logging.StructuredLogger; namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class MSBuildTests_EntryPoint : AcceptanceTestBase +[TestClass] +public class MSBuildTests_EntryPoint : AcceptanceTestBase { private const string AssetName = "MSBuildTests"; - private readonly AcceptanceFixture _acceptanceFixture; - - public MSBuildTests_EntryPoint(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildVerbConfiguration))] + [DynamicData(nameof(GetBuildMatrixTfmBuildVerbConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] + [TestMethod] public async Task When_GenerateTestingPlatformEntryPoint_IsFalse_NoEntryPointInjected(string tfm, BuildConfiguration compilationMode, Verb verb) { using TestAsset testAsset = await TestAsset.GenerateAssetAsync( @@ -25,9 +19,9 @@ public async Task When_GenerateTestingPlatformEntryPoint_IsFalse_NoEntryPointInj CSharpSourceCode .PatchCodeWithReplace("$TargetFrameworks$", tfm) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"restore -r {RID} {testAsset.TargetAssetPath}{Path.DirectorySeparatorChar}MSBuildTests.csproj ", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"restore -r {RID} {testAsset.TargetAssetPath}{Path.DirectorySeparatorChar}MSBuildTests.csproj ", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); - compilationResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -c {compilationMode} -r {RID} -nodeReuse:false -p:GenerateTestingPlatformEntryPoint=False -bl:{binlogFile} {testAsset.TargetAssetPath} -v:n", _acceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); + compilationResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -c {compilationMode} -r {RID} -nodeReuse:false -p:GenerateTestingPlatformEntryPoint=False -bl:{binlogFile} {testAsset.TargetAssetPath} -v:n", AcceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); SL.Build binLog = SL.Serialization.Read(binlogFile); SL.Target generateTestingPlatformEntryPoint = binLog.FindChildrenRecursive().Single(t => t.Name == "_GenerateTestingPlatformEntryPoint"); Assert.AreEqual("Target \"_GenerateTestingPlatformEntryPoint\" skipped, due to false condition; ( '$(GenerateTestingPlatformEntryPoint)' == 'True' ) was evaluated as ( 'False' == 'True' ).", ((SL.Message)generateTestingPlatformEntryPoint.Children[0]).Text); @@ -38,7 +32,8 @@ public async Task When_GenerateTestingPlatformEntryPoint_IsFalse_NoEntryPointInj Assert.AreNotEqual(0, compilationResult.ExitCode); } - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildVerbConfiguration))] + [DynamicData(nameof(GetBuildMatrixTfmBuildVerbConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] + [TestMethod] public async Task GenerateCSharpEntryPointAndVerifyTheCacheUsage(string tfm, BuildConfiguration compilationMode, Verb verb) => await GenerateAndVerifyLanguageSpecificEntryPoint(nameof(GenerateCSharpEntryPointAndVerifyTheCacheUsage), CSharpSourceCode, "cs", tfm, compilationMode, verb, @"Entrypoint source: @@ -62,7 +57,8 @@ internal sealed class TestingPlatformEntryPoint } }'", "Csc"); - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildVerbConfiguration))] + [DynamicData(nameof(GetBuildMatrixTfmBuildVerbConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] + [TestMethod] public async Task GenerateVBEntryPointAndVerifyTheCacheUsage(string tfm, BuildConfiguration compilationMode, Verb verb) => await GenerateAndVerifyLanguageSpecificEntryPoint(nameof(GenerateVBEntryPointAndVerifyTheCacheUsage), VBSourceCode, "vb", tfm, compilationMode, verb, @"Entrypoint source: @@ -89,7 +85,8 @@ End Function End Module'", "Vbc"); - [ArgumentsProvider(nameof(GetBuildMatrixTfmBuildVerbConfiguration))] + [DynamicData(nameof(GetBuildMatrixTfmBuildVerbConfiguration), typeof(AcceptanceTestBase), DynamicDataSourceType.Method)] + [TestMethod] public async Task GenerateFSharpEntryPointAndVerifyTheCacheUsage(string tfm, BuildConfiguration compilationMode, Verb verb) => await GenerateAndVerifyLanguageSpecificEntryPoint(nameof(GenerateFSharpEntryPointAndVerifyTheCacheUsage), FSharpSourceCode, "fs", tfm, compilationMode, verb, @"Entrypoint source: @@ -120,9 +117,9 @@ private async Task GenerateAndVerifyLanguageSpecificEntryPoint(string assetName, // We need to pickup local build packages -dev .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingPlatformVersion); using TestAsset testAsset = await TestAsset.GenerateAssetAsync(assetName, finalSourceCode); - await DotnetCli.RunAsync($"restore -r {RID} {testAsset.TargetAssetPath}{Path.DirectorySeparatorChar}MSBuildTests.{languageFileExtension}proj", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + await DotnetCli.RunAsync($"restore -r {RID} {testAsset.TargetAssetPath}{Path.DirectorySeparatorChar}MSBuildTests.{languageFileExtension}proj", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); - DotnetMuxerResult buildResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -c {compilationMode} -r {RID} -nodeReuse:false -bl:{binlogFile} {testAsset.TargetAssetPath} -v:n", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult buildResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -c {compilationMode} -r {RID} -nodeReuse:false -bl:{binlogFile} {testAsset.TargetAssetPath} -v:n", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); SL.Build binLog = SL.Serialization.Read(binlogFile); SL.Target generateTestingPlatformEntryPoint = binLog.FindChildrenRecursive().Single(t => t.Name == "_GenerateTestingPlatformEntryPoint"); SL.Task testingPlatformEntryPoint = generateTestingPlatformEntryPoint.FindChildrenRecursive().Single(t => t.Name == "TestingPlatformEntryPointTask"); @@ -141,7 +138,7 @@ private async Task GenerateAndVerifyLanguageSpecificEntryPoint(string assetName, Assert.IsNotNull(sourceFilePathInObj); File.Delete(binlogFile); - await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -c {compilationMode} -r {RID} -nodeReuse:false -bl:{binlogFile} {testAsset.TargetAssetPath} -v:n", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -c {compilationMode} -r {RID} -nodeReuse:false -bl:{binlogFile} {testAsset.TargetAssetPath} -v:n", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); binLog = SL.Serialization.Read(binlogFile); generateTestingPlatformEntryPoint = binLog.FindChildrenRecursive(t => t.Name == "_GenerateTestingPlatformEntryPoint" && t.Children.Count > 0).Single(); Assert.IsNotNull(generateTestingPlatformEntryPoint.FindChildrenRecursive(m => m.Text.Contains("Skipping target \"_GenerateTestingPlatformEntryPoint\" because all output files are up-to-date with respect to the input files.", StringComparison.OrdinalIgnoreCase)).Single()); @@ -158,15 +155,15 @@ private async Task GenerateAndVerifyLanguageSpecificEntryPoint(string assetName, - DummyAdapter - MyNamespaceRoot.Level1.Level2.DummyAdapterRegistration + DummyTestFramework + MyNamespaceRoot.Level1.Level2.DummyTestFrameworkRegistration - DummyAdapter2 - MyNamespaceRoot.Level1.Level2.DummyAdapterRegistration2 + DummyTestFramework2 + MyNamespaceRoot.Level1.Level2.DummyTestFrameworkRegistration2 @@ -181,7 +178,6 @@ private async Task GenerateAndVerifyLanguageSpecificEntryPoint(string assetName, - @@ -195,15 +191,15 @@ private async Task GenerateAndVerifyLanguageSpecificEntryPoint(string assetName, namespace MyNamespaceRoot.Level1.Level2; -public static class DummyAdapterRegistration +public static class DummyTestFrameworkRegistration { public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, string[] args) { - testApplicationBuilder.RegisterTestFramework(_ => new Capabilities(), (_, __) => new DummyAdapter()); + testApplicationBuilder.RegisterTestFramework(_ => new Capabilities(), (_, __) => new DummyTestFramework()); } } -public static class DummyAdapterRegistration2 +public static class DummyTestFrameworkRegistration2 { public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, string[] args) { @@ -211,9 +207,9 @@ public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, } } -internal sealed class DummyAdapter : ITestFramework, IDataProducer +internal sealed class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => string.Empty; @@ -249,15 +245,15 @@ internal sealed class Capabilities : ITestFrameworkCapabilities - DummyAdapter - MyNamespaceRoot.Level1.Level2.DummyAdapterRegistration + DummyTestFramework + MyNamespaceRoot.Level1.Level2.DummyTestFrameworkRegistration - DummyAdapter2 - MyNamespaceRoot.Level1.Level2.DummyAdapterRegistration2 + DummyTestFramework2 + MyNamespaceRoot.Level1.Level2.DummyTestFrameworkRegistration2 @@ -269,7 +265,6 @@ internal sealed class Capabilities : ITestFrameworkCapabilities - @@ -284,18 +279,18 @@ Imports Microsoft.Testing.Platform.Extensions Imports Microsoft.Testing.Platform Namespace MyNamespaceRoot.Level1.Level2 - Public Module DummyAdapterRegistration + Public Module DummyTestFrameworkRegistration Public Sub AddExtensions(builder As ITestApplicationBuilder, args As String()) - builder.RegisterTestFramework(Function() New Capabilities(), Function(cap, services) New DummyAdapter()) + builder.RegisterTestFramework(Function() New Capabilities(), Function(cap, services) New DummyTestFramework()) End Sub End Module - Public Module DummyAdapterRegistration2 + Public Module DummyTestFrameworkRegistration2 Public Sub AddExtensions(builder As ITestApplicationBuilder, args As String()) End Sub End Module - Class DummyAdapter + Class DummyTestFramework Implements ITestFramework Implements IDataProducer @@ -375,15 +370,15 @@ End Namespace - DummyAdapter - MyNamespaceRoot.Level1.Level2.DummyAdapterRegistration + DummyTestFramework + MyNamespaceRoot.Level1.Level2.DummyTestFrameworkRegistration - DummyAdapter2 - MyNamespaceRoot.Level1.Level2.DummyAdapterRegistration2 + DummyTestFramework2 + MyNamespaceRoot.Level1.Level2.DummyTestFrameworkRegistration2 @@ -419,11 +414,11 @@ type Capabilities () = interface ITestFrameworkCapabilities with member _.Capabilities = [||] -type DummyAdapter() = +type DummyTestFramework() = let dataProducer = { new IDataProducer with member _.DataTypesProduced = [| typedefof |] - member _.Uid = nameof(DummyAdapter) + member _.Uid = nameof(DummyTestFramework) member _.Version = "" member _.DisplayName = "" member _.Description = "" @@ -432,7 +427,7 @@ member _.IsEnabledAsync() = Task.FromResult true } interface ITestFramework with - member _.Uid = nameof(DummyAdapter) + member _.Uid = nameof(DummyTestFramework) member _.Version = "" member _.DisplayName = "" member _.Description = "" @@ -449,11 +444,11 @@ member _.IsEnabledAsync() = Task.FromResult true context.Complete() } -module DummyAdapterRegistration = +module DummyTestFrameworkRegistration = let AddExtensions (testApplicationBuilder : ITestApplicationBuilder, args: string[]) = - testApplicationBuilder.RegisterTestFramework((fun _ -> Capabilities()), (fun _ _ -> DummyAdapter())) |> ignore + testApplicationBuilder.RegisterTestFramework((fun _ -> Capabilities()), (fun _ _ -> DummyTestFramework())) |> ignore -module DummyAdapterRegistration2 = +module DummyTestFrameworkRegistration2 = let AddExtensions (_, _) = () """; diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs index 60043750e6..936bc59983 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs @@ -1,22 +1,16 @@ // 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.Testing.Platform.Acceptance.IntegrationTests.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class MSBuildTests_Solution : AcceptanceTestBase +[TestClass] +public class MSBuildTests_Solution : AcceptanceTestBase { - private readonly AcceptanceFixture _acceptanceFixture; private const string AssetName = "MSTestProject"; - public MSBuildTests_Solution(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - - internal static IEnumerable> GetBuildMatrix() + internal static IEnumerable<(string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm, string Command)> GetBuildMatrix() { - foreach (TestArgumentsEntry<(string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm)> entry in GetBuildMatrixSingleAndMultiTfmBuildConfiguration()) + foreach ((string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm) entry in GetBuildMatrixSingleAndMultiTfmBuildConfiguration()) { foreach (string command in new string[] { @@ -24,13 +18,13 @@ public MSBuildTests_Solution(ITestExecutionContext testExecutionContext, Accepta "test --no-restore", }) { - yield return new TestArgumentsEntry<(string SingleTfmOrMultiTfm, BuildConfiguration BuildConfiguration, bool IsMultiTfm, string Command)>( - (entry.Arguments.SingleTfmOrMultiTfm, entry.Arguments.BuildConfiguration, entry.Arguments.IsMultiTfm, command), $"{(entry.Arguments.IsMultiTfm ? "multitfm" : entry.Arguments.SingleTfmOrMultiTfm)},{entry.Arguments.BuildConfiguration},{command}"); + yield return new(entry.SingleTfmOrMultiTfm, entry.BuildConfiguration, entry.IsMultiTfm, command); } } } - [ArgumentsProvider(nameof(GetBuildMatrix))] + [DynamicData(nameof(GetBuildMatrix), DynamicDataSourceType.Method)] + [TestMethod] public async Task MSBuildTests_UseMSBuildTestInfrastructure_Should_Run_Solution_Tests(string singleTfmOrMultiTfm, BuildConfiguration _, bool isMultiTfm, string command) { using TestAsset generator = await TestAsset.GenerateAssetAsync( @@ -38,13 +32,10 @@ public async Task MSBuildTests_UseMSBuildTestInfrastructure_Should_Run_Solution_ SourceCode .PatchCodeWithReplace("$TargetFrameworks$", isMultiTfm ? $"{singleTfmOrMultiTfm}" : $"{singleTfmOrMultiTfm}") .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); string projectContent = File.ReadAllText(Directory.GetFiles(generator.TargetAssetPath, "MSBuildTests.csproj", SearchOption.AllDirectories).Single()); string programSourceContent = File.ReadAllText(Directory.GetFiles(generator.TargetAssetPath, "Program.cs", SearchOption.AllDirectories).Single()); - string unitTestSourceContent = File.ReadAllText(Directory.GetFiles(generator.TargetAssetPath, "UnitTest1.cs", SearchOption.AllDirectories).Single()); - string usingsSourceContent = File.ReadAllText(Directory.GetFiles(generator.TargetAssetPath, "Usings.cs", SearchOption.AllDirectories).Single()); string nugetConfigContent = File.ReadAllText(Directory.GetFiles(generator.TargetAssetPath, "NuGet.config", SearchOption.AllDirectories).Single()); // Create a solution with 3 projects @@ -57,32 +48,30 @@ public async Task MSBuildTests_UseMSBuildTestInfrastructure_Should_Run_Solution_ CSharpProject project = solution.CreateCSharpProject($"TestProject{i}", isMultiTfm ? singleTfmOrMultiTfm.Split(';') : [singleTfmOrMultiTfm]); File.WriteAllText(project.ProjectFile, projectContent); project.AddOrUpdateFileContent("Program.cs", programSourceContent.PatchCodeWithReplace("$ProjectName$", $"TestProject{i}")); - project.AddOrUpdateFileContent("UnitTest1.cs", unitTestSourceContent); - project.AddOrUpdateFileContent("Usings.cs", usingsSourceContent); CSharpProject project2 = solution.CreateCSharpProject($"Project{i}", isMultiTfm ? singleTfmOrMultiTfm.Split(';') : [singleTfmOrMultiTfm]); project.AddProjectReference(project2.ProjectFile); } // Build the solution - DotnetMuxerResult restoreResult = await DotnetCli.RunAsync($"restore -nodeReuse:false {solution.SolutionFile} --configfile {nugetFile}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); - restoreResult.AssertOutputNotContains("An approximate best match of"); - DotnetMuxerResult testResult = await DotnetCli.RunAsync($"{command} -nodeReuse:false {solution.SolutionFile}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + DotnetMuxerResult restoreResult = await DotnetCli.RunAsync($"restore -nodeReuse:false {solution.SolutionFile} --configfile {nugetFile}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); + restoreResult.AssertOutputDoesNotContain("An approximate best match of"); + DotnetMuxerResult testResult = await DotnetCli.RunAsync($"{command} -nodeReuse:false {solution.SolutionFile}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); if (isMultiTfm) { foreach (string tfm in singleTfmOrMultiTfm.Split(';')) { - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject0\..*' \[{tfm}\|x64\]"); - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject1\..*' \[{tfm}\|x64\]"); - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject2\..*' \[{tfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject0\..*' \[{tfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject1\..*' \[{tfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject2\..*' \[{tfm}\|x64\]"); } } else { - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject0\..*' \[{singleTfmOrMultiTfm}\|x64\]"); - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject1\..*' \[{singleTfmOrMultiTfm}\|x64\]"); - testResult.AssertOutputRegEx($@"Tests succeeded: '.*TestProject2\..*' \[{singleTfmOrMultiTfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject0\..*' \[{singleTfmOrMultiTfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject1\..*' \[{singleTfmOrMultiTfm}\|x64\]"); + testResult.AssertOutputMatchesRegex($@"Tests succeeded: '.*TestProject2\..*' \[{singleTfmOrMultiTfm}\|x64\]"); } } @@ -102,38 +91,61 @@ public async Task MSBuildTests_UseMSBuildTestInfrastructure_Should_Run_Solution_ - - - - #file Program.cs -using MSBuildTests; -using $ProjectName$; -ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new SourceGeneratedTestNodesBuilder()); -builder.AddMSBuild(); -using ITestApplication app = await builder.BuildAsync(); -return await app.RunAsync(); - -#file UnitTest1.cs -namespace MSBuildTests; - -[TestGroup] -public class UnitTest1 +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.MSBuild; +using Microsoft.Testing.Platform.Services; + +public class Program { - public void TestMethod1() + public static async Task Main(string[] args) { - Assert.IsTrue(true); + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + builder.RegisterTestFramework( + sp => new TestFrameworkCapabilities(), + (_,__) => new DummyTestFramework()); + builder.AddMSBuild(); + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); } } -#file Usings.cs -global using Microsoft.Testing.Platform.Builder; -global using Microsoft.Testing.Internal.Framework; -global using Microsoft.Testing.Platform.MSBuild; +public class DummyTestFramework : ITestFramework, IDataProducer +{ + public string Uid => nameof(DummyTestFramework); + + public string Version => "2.0.0"; + + public string DisplayName => nameof(DummyTestFramework); + + public string Description => nameof(DummyTestFramework); + + public Type[] DataTypesProduced => [typeof(TestNodeUpdateMessage)]; + + public Task IsEnabledAsync() => Task.FromResult(true); + + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + + public async Task ExecuteRequestAsync(ExecuteRequestContext context) + { + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "1", DisplayName = "Test1", Properties = new(DiscoveredTestNodeStateProperty.CachedInstance) })); + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "1", DisplayName = "Test1", Properties = new(PassedTestNodeStateProperty.CachedInstance) })); + + context.Complete(); + } +} """; } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs index d057c61852..796bcfffe2 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs @@ -1,45 +1,27 @@ // 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.Reflection; using System.Runtime.InteropServices; using System.Text.RegularExpressions; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class MSBuildTests_Test : AcceptanceTestBase +[TestClass] +public class MSBuildTests_Test : AcceptanceTestBase { private const string AssetName = "MSBuildTests"; - private readonly AcceptanceFixture _acceptanceFixture; - - public MSBuildTests_Test(ITestExecutionContext testExecutionContext, AcceptanceFixture acceptanceFixture) - : base(testExecutionContext) => _acceptanceFixture = acceptanceFixture; - internal static TestArgumentsEntry<(string BuildCommand, string TargetFramework, BuildConfiguration BuildConfiguration, bool TestSucceeded)> FormatBuildMatrixEntry(TestArgumentsContext ctx) - { - var entry = ((string, string, BuildConfiguration, bool))ctx.Arguments; - return new TestArgumentsEntry<(string, string, BuildConfiguration, bool)>(entry, $"{entry.Item1},{(TargetFrameworks.All.ToMSBuildTargetFrameworks() == entry.Item2 ? "multitfm" : entry.Item2)},{entry.Item3},{(entry.Item4 ? "Succeeded" : "Failed")}"); - } + public static string? FormatBuildMatrixEntry(MethodInfo method, object?[]? data) + => $"{data![0]},{(string.Equals(TargetFrameworks.All.ToMSBuildTargetFrameworks(), data[1]) ? "multitfm" : data[1])},{data[2]},{((bool)data[3]! ? "Succeeded" : "Failed")}"; internal static IEnumerable<(string BuildCommand, string TargetFramework, BuildConfiguration BuildConfiguration, bool TestSucceeded)> GetBuildMatrix() { - foreach (TestArgumentsEntry tfm in TargetFrameworks.All) + foreach (string tfm in TargetFrameworks.All) { - foreach (BuildConfiguration compilationMode in Enum.GetValues()) + foreach ((string buildCommand, _, BuildConfiguration buildConfiguration, bool testSucceeded) in GetBuildMatrixMultiTfm()) { - foreach (bool testSucceeded in new bool[] { true, false }) - { - foreach (string buildCommand in new string[] - { - "build -t:Test", - "test -p:TestingPlatformDotnetTestSupport=True", - }) - { - yield return (buildCommand, tfm.Arguments, compilationMode, testSucceeded); - } - } + yield return (buildCommand, tfm, buildConfiguration, testSucceeded); } } } @@ -50,25 +32,21 @@ public MSBuildTests_Test(ITestExecutionContext testExecutionContext, AcceptanceF { foreach (bool testSucceeded in new bool[] { true, false }) { - foreach (string buildCommand in new string[] - { - "build -t:Test", - "test -p:TestingPlatformDotnetTestSupport=True", - }) - { - yield return (buildCommand, TargetFrameworks.All.ToMSBuildTargetFrameworks(), compilationMode, testSucceeded); - } + yield return ("build -t:Test", TargetFrameworks.All.ToMSBuildTargetFrameworks(), compilationMode, testSucceeded); + yield return ("test -p:TestingPlatformDotnetTestSupport=True", TargetFrameworks.All.ToMSBuildTargetFrameworks(), compilationMode, testSucceeded); } } } - [ArgumentsProvider(nameof(GetBuildMatrix), TestArgumentsEntryProviderMethodName = nameof(FormatBuildMatrixEntry))] + [DynamicData(nameof(GetBuildMatrix), DynamicDataSourceType.Method, DynamicDataDisplayName = nameof(FormatBuildMatrixEntry))] + [TestMethod] public async Task InvokeTestingPlatform_Target_Should_Execute_Tests_Without_Showing_Error_Detail_SingleTfm(string testCommand, string tfm, BuildConfiguration compilationMode, bool testSucceeded) => await InvokeTestingPlatform_Target_Should_Execute_Tests_Without_Showing_Error_Detail(testCommand, tfm, false, [tfm], compilationMode, testSucceeded); - [ArgumentsProvider(nameof(GetBuildMatrixMultiTfm), TestArgumentsEntryProviderMethodName = nameof(FormatBuildMatrixEntry))] + [DynamicData(nameof(GetBuildMatrixMultiTfm), DynamicDataSourceType.Method, DynamicDataDisplayName = nameof(FormatBuildMatrixEntry))] + [TestMethod] public async Task InvokeTestingPlatform_Target_Should_Execute_Tests_Without_Showing_Error_Detail_MultiTfm(string testCommand, string multiTfm, BuildConfiguration compilationMode, bool testSucceeded) - => await InvokeTestingPlatform_Target_Should_Execute_Tests_Without_Showing_Error_Detail(testCommand, multiTfm, true, TargetFrameworks.All.Select(x => x.Arguments).ToArray(), compilationMode, testSucceeded); + => await InvokeTestingPlatform_Target_Should_Execute_Tests_Without_Showing_Error_Detail(testCommand, multiTfm, true, TargetFrameworks.All, compilationMode, testSucceeded); private async Task InvokeTestingPlatform_Target_Should_Execute_Tests_Without_Showing_Error_Detail(string testCommand, string tfm, bool isMultiTfm, string[] tfmsToAssert, BuildConfiguration compilationMode, bool testSucceeded) { @@ -78,12 +56,10 @@ private async Task InvokeTestingPlatform_Target_Should_Execute_Tests_Without_Sho .PatchCodeWithReplace("$PlatformTarget$", "x64") .PatchCodeWithReplace("$TargetFrameworks$", isMultiTfm ? $"{tfm}" : $"{tfm}") .PatchCodeWithReplace("$AssertValue$", testSucceeded.ToString().ToLowerInvariant()) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); string testResultFolder = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N")); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{testCommand} -p:TestingPlatformCommandLineArguments=\"--results-directory %22{testResultFolder}%22\" -p:Configuration={compilationMode} -p:nodeReuse=false -bl:{binlogFile} \"{testAsset.TargetAssetPath}\"", _acceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{testCommand} -p:TestingPlatformCommandLineArguments=\"--results-directory %22{testResultFolder}%22\" -p:Configuration={compilationMode} -p:nodeReuse=false -bl:{binlogFile} \"{testAsset.TargetAssetPath}\"", AcceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); foreach (string tfmToAssert in tfmsToAssert) { @@ -91,13 +67,15 @@ private async Task InvokeTestingPlatform_Target_Should_Execute_Tests_Without_Sho } } - [ArgumentsProvider(nameof(GetBuildMatrix), TestArgumentsEntryProviderMethodName = nameof(FormatBuildMatrixEntry))] + [DynamicData(nameof(GetBuildMatrix), DynamicDataSourceType.Method, DynamicDataDisplayName = nameof(FormatBuildMatrixEntry))] + [TestMethod] public async Task InvokeTestingPlatform_Target_Should_Build_Without_Warnings_And_Execute_Passing_Test_And_Pass_TheRun_SingleTfm(string testCommand, string tfm, BuildConfiguration compilationMode, bool testSucceeded) => await InvokeTestingPlatform_Target_Should_Build_Without_Warnings_And_Execute_Passing_Test_And_Pass_TheRun_Detail(testCommand, tfm, false, [tfm], compilationMode, testSucceeded); - [ArgumentsProvider(nameof(GetBuildMatrixMultiTfm), TestArgumentsEntryProviderMethodName = nameof(FormatBuildMatrixEntry))] + [DynamicData(nameof(GetBuildMatrixMultiTfm), DynamicDataSourceType.Method, DynamicDataDisplayName = nameof(FormatBuildMatrixEntry))] + [TestMethod] public async Task InvokeTestingPlatform_Target_Should_Build_Without_Warnings_And_Execute_Passing_Test_And_Pass_TheRun_MultiTfm(string testCommand, string multiTfm, BuildConfiguration compilationMode, bool testSucceeded) - => await InvokeTestingPlatform_Target_Should_Build_Without_Warnings_And_Execute_Passing_Test_And_Pass_TheRun_Detail(testCommand, multiTfm, true, TargetFrameworks.All.Select(x => x.Arguments).ToArray(), compilationMode, testSucceeded); + => await InvokeTestingPlatform_Target_Should_Build_Without_Warnings_And_Execute_Passing_Test_And_Pass_TheRun_Detail(testCommand, multiTfm, true, TargetFrameworks.All, compilationMode, testSucceeded); private async Task InvokeTestingPlatform_Target_Should_Build_Without_Warnings_And_Execute_Passing_Test_And_Pass_TheRun_Detail(string testCommand, string tfm, bool isMultiTfm, string[] tfmsToAssert, BuildConfiguration compilationMode, bool testSucceeded) { @@ -107,19 +85,17 @@ private async Task InvokeTestingPlatform_Target_Should_Build_Without_Warnings_An .PatchCodeWithReplace("$PlatformTarget$", "x64") .PatchCodeWithReplace("$TargetFrameworks$", isMultiTfm ? $"{tfm}" : $"{tfm}") .PatchCodeWithReplace("$AssertValue$", testSucceeded.ToString().ToLowerInvariant()) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); string testResultFolder = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N")); DotnetMuxerResult compilationResult = testCommand.StartsWith("test", StringComparison.OrdinalIgnoreCase) ? await DotnetCli.RunAsync( - $"{testCommand} -p:Configuration={compilationMode} -p:nodeReuse=false -bl:{binlogFile} \"{testAsset.TargetAssetPath}\" -- --treenode-filter /*/*/*/TestMethod1 --results-directory \"{testResultFolder}\"", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path) + $"{testCommand} -p:Configuration={compilationMode} -p:nodeReuse=false -bl:{binlogFile} \"{testAsset.TargetAssetPath}\" -- --treenode-filter --results-directory \"{testResultFolder}\"", + AcceptanceFixture.NuGetGlobalPackagesFolder.Path) : await DotnetCli.RunAsync( - $"{testCommand} -p:TestingPlatformCommandLineArguments=\"--treenode-filter /*/*/*/TestMethod1 --results-directory \"{testResultFolder}\"\" -p:Configuration={compilationMode} -p:nodeReuse=false -bl:{binlogFile} \"{testAsset.TargetAssetPath}\"", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path); + $"{testCommand} -p:TestingPlatformCommandLineArguments=\"--treenode-filter --results-directory \"{testResultFolder}\"\" -p:Configuration={compilationMode} -p:nodeReuse=false -bl:{binlogFile} \"{testAsset.TargetAssetPath}\"", + AcceptanceFixture.NuGetGlobalPackagesFolder.Path); foreach (string tfmToAssert in tfmsToAssert) { @@ -127,6 +103,7 @@ private async Task InvokeTestingPlatform_Target_Should_Build_Without_Warnings_An } } + [TestMethod] public async Task Invoke_DotnetTest_With_Arch_Switch_x86_Should_Work() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -145,15 +122,13 @@ public async Task Invoke_DotnetTest_With_Arch_Switch_x86_Should_Work() AssetName, SourceCode .PatchCodeWithReplace("$PlatformTarget$", string.Empty) - .PatchCodeWithReplace("$TargetFrameworks$", $"{TargetFrameworks.NetCurrent.Arguments}") + .PatchCodeWithReplace("$TargetFrameworks$", $"{TargetFrameworks.NetCurrent}") .PatchCodeWithReplace("$AssertValue$", bool.TrueString.ToLowerInvariant()) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); await DotnetCli.RunAsync( $"test --arch x86 -p:TestingPlatformDotnetTestSupport=True -p:Configuration=Release -p:nodeReuse=false -bl:{binlogFile} \"{testAsset.TargetAssetPath}\"", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + AcceptanceFixture.NuGetGlobalPackagesFolder.Path, environmentVariables: dotnetRootX86, failIfReturnValueIsNotZero: false); @@ -164,6 +139,7 @@ await DotnetCli.RunAsync( Assert.IsTrue(Regex.IsMatch(logFileContent, @"\.dotnet\\x86\\dotnet\.exe"), logFileContent); } + [TestMethod] public async Task Invoke_DotnetTest_With_Incompatible_Arch() { Architecture currentArchitecture = RuntimeInformation.ProcessArchitecture; @@ -177,14 +153,12 @@ public async Task Invoke_DotnetTest_With_Incompatible_Arch() AssetName, SourceCode .PatchCodeWithReplace("$PlatformTarget$", string.Empty) - .PatchCodeWithReplace("$TargetFrameworks$", $"{TargetFrameworks.NetCurrent.Arguments}") + .PatchCodeWithReplace("$TargetFrameworks$", $"{TargetFrameworks.NetCurrent}") .PatchCodeWithReplace("$AssertValue$", bool.TrueString.ToLowerInvariant()) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); DotnetMuxerResult result = await DotnetCli.RunAsync( $"test --arch {incompatibleArchitecture} -p:TestingPlatformDotnetTestSupport=True \"{testAsset.TargetAssetPath}\"", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + AcceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); // The output looks like: /* @@ -202,6 +176,7 @@ public async Task Invoke_DotnetTest_With_Incompatible_Arch() result.AssertOutputContains(" - https://aka.ms/dotnet-download"); } + [TestMethod] public async Task Invoke_DotnetTest_With_DOTNET_HOST_PATH_Should_Work() { if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) @@ -220,15 +195,13 @@ public async Task Invoke_DotnetTest_With_DOTNET_HOST_PATH_Should_Work() AssetName, SourceCode .PatchCodeWithReplace("$PlatformTarget$", string.Empty) - .PatchCodeWithReplace("$TargetFrameworks$", $"{TargetFrameworks.NetCurrent.Arguments}") + .PatchCodeWithReplace("$TargetFrameworks$", $"{TargetFrameworks.NetCurrent}") .PatchCodeWithReplace("$AssertValue$", bool.TrueString.ToLowerInvariant()) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); await DotnetCli.RunAsync( $"test -p:TestingPlatformDotnetTestSupport=True -p:Configuration=Release -p:nodeReuse=false -bl:{binlogFile} \"{testAsset.TargetAssetPath}\"", - _acceptanceFixture.NuGetGlobalPackagesFolder.Path, + AcceptanceFixture.NuGetGlobalPackagesFolder.Path, environmentVariables: dotnetHostPathEnvVar, failIfReturnValueIsNotZero: false); @@ -255,9 +228,11 @@ private static void CommonAssert(DotnetMuxerResult compilationResult, string tfm Assert.IsFalse(string.IsNullOrEmpty(File.ReadAllText(outputFileLog)), $"Content of file '{File.ReadAllText(outputFileLog)}'"); } - // We avoid to test the multi-tfm because it's already tested with the above tests and we don't want to have too heavy testing, msbuild is pretty heavy (a lot of processes started due to the no 'nodereuse') and makes tests flaky. + // We avoid to test the multi-tfm because it's already tested with the above tests and we don't want to have too heavy testing, + // msbuild is pretty heavy (a lot of processes started due to the no 'nodereuse') and makes tests flaky. // We test two functionality for the same reason, we don't want to load too much the CI only for UX reasons. - [ArgumentsProvider(nameof(GetBuildMatrix), TestArgumentsEntryProviderMethodName = nameof(FormatBuildMatrixEntry))] + [DynamicData(nameof(GetBuildMatrix), DynamicDataSourceType.Method, DynamicDataDisplayName = nameof(FormatBuildMatrixEntry))] + [TestMethod] public async Task InvokeTestingPlatform_Target_Showing_Error_And_Do_Not_Capture_The_Output_SingleTfm(string testCommand, string tfm, BuildConfiguration compilationMode, bool testSucceeded) { // We test only failed but we don't want to have too much argument provider overload. @@ -272,14 +247,13 @@ public async Task InvokeTestingPlatform_Target_Showing_Error_And_Do_Not_Capture_ .PatchCodeWithReplace("$PlatformTarget$", "x64") .PatchCodeWithReplace("$TargetFrameworks$", $"{tfm}") .PatchCodeWithReplace("$AssertValue$", testSucceeded.ToString().ToLowerInvariant()) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); - DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{testCommand} -p:TestingPlatformShowTestsFailure=True -p:TestingPlatformCaptureOutput=False -p:Configuration={compilationMode} -p:nodeReuse=false -bl:{binlogFile} {testAsset.TargetAssetPath}", _acceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); - Assert.Contains("error test failed: TestMethod2 (", compilationResult.StandardOutput); - Assert.Contains("Assert.IsTrue: Expected 'true', but got 'false'.", compilationResult.StandardOutput); - Assert.Contains(".NET Testing Platform", compilationResult.StandardOutput); + DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{testCommand} -p:TestingPlatformShowTestsFailure=True -p:TestingPlatformCaptureOutput=False -p:Configuration={compilationMode} -p:nodeReuse=false -bl:{binlogFile} {testAsset.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path, failIfReturnValueIsNotZero: false); + + compilationResult.AssertOutputContains("error test failed: Test2 ("); + compilationResult.AssertOutputContains("FAILED: Expected 'true', but got 'false'."); + compilationResult.AssertOutputContains(".NET Testing Platform"); } private const string SourceCode = """ @@ -298,42 +272,93 @@ public async Task InvokeTestingPlatform_Target_Showing_Error_And_Do_Not_Capture_ - - - - #file Program.cs -using MSBuildTests; -ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new MSBuild_Tests.SourceGeneratedTestNodesBuilder()); -builder.AddMSBuild(); -using ITestApplication app = await builder.BuildAsync(); -return await app.RunAsync(); - -#file UnitTest1.cs -namespace MSBuildTests; - -[TestGroup] -public class UnitTest1 +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions; +using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.MSBuild; +using Microsoft.Testing.Platform.Services; + +public class Program { - public void TestMethod1() + public static async Task Main(string[] args) { - Assert.IsTrue(true); + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + MyExtension myExtension = new(); + builder.RegisterTestFramework( + sp => new TestFrameworkCapabilities(), + (_,sp) => new DummyTestFramework(sp, myExtension)); + builder.AddTreeNodeFilterService(myExtension); + builder.AddMSBuild(); + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); } +} - public void TestMethod2() +public class MyExtension : IExtension +{ + public string Uid => "MyExtension"; + public string Version => "1.0.0"; + public string DisplayName => "My Extension"; + public string Description => "My Extension Description"; + public Task IsEnabledAsync() => Task.FromResult(true); +} + +public class DummyTestFramework : ITestFramework, IDataProducer +{ + private IServiceProvider _sp; + private MyExtension _myExtension; + + public DummyTestFramework(IServiceProvider sp, MyExtension myExtension) { - Assert.IsTrue($AssertValue$); + _sp = sp; + _myExtension = myExtension; } -} -#file Usings.cs -global using Microsoft.Testing.Platform.Builder; -global using Microsoft.Testing.Internal.Framework; -global using Microsoft.Testing.Platform.MSBuild; + public string Uid => _myExtension.Uid; + + public string Version => _myExtension.Version; + + public string DisplayName => _myExtension.DisplayName; + + public string Description => _myExtension.Description; + + public Type[] DataTypesProduced => [typeof(TestNodeUpdateMessage)]; + + public Task IsEnabledAsync() => _myExtension.IsEnabledAsync(); + + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + + public async Task ExecuteRequestAsync(ExecuteRequestContext context) + { + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode { Uid = "1", DisplayName = "Test1", Properties = new(DiscoveredTestNodeStateProperty.CachedInstance) })); + + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode { Uid = "1", DisplayName = "Test1", Properties = new(PassedTestNodeStateProperty.CachedInstance) })); + + if (!_sp.GetCommandLineOptions().TryGetOptionArgumentList("--treenode-filter", out _)) + { + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode { Uid = "2", DisplayName = "Test2", Properties = new(DiscoveredTestNodeStateProperty.CachedInstance) })); + + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode { Uid = "2", DisplayName = "Test2", Properties = new($AssertValue$ ? PassedTestNodeStateProperty.CachedInstance : new FailedTestNodeStateProperty("FAILED: Expected 'true', but got 'false'.")) })); + } + + context.Complete(); + } +} """; } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs index 7456dea256..44ebf81d34 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs @@ -1,23 +1,17 @@ // 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.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class MaxFailedTestsExtensionTests : AcceptanceTestBase +[TestClass] +public class MaxFailedTestsExtensionTests : AcceptanceTestBase { private const string AssetName = nameof(MaxFailedTestsExtensionTests); - private readonly TestAssetFixture _testAssetFixture; - - public MaxFailedTestsExtensionTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; + [TestMethod] public async Task TestMaxFailedTestsShouldCallStopTestExecutionAsync() { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--maximum-failed-tests 2"); testHostResult.AssertExitCodeIs(ExitCodes.TestExecutionStoppedForMaxFailedTests); @@ -26,9 +20,10 @@ public async Task TestMaxFailedTestsShouldCallStopTestExecutionAsync() testHostResult.AssertOutputContainsSummary(failed: 3, passed: 3, skipped: 0); } + [TestMethod] public async Task WhenCapabilityIsMissingShouldFail() { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, TargetFrameworks.NetCurrent.Arguments); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, TargetFrameworks.NetCurrent); TestHostResult testHostResult = await testHost.ExecuteAsync("--maximum-failed-tests 2", environmentVariables: new() { ["DO_NOT_ADD_CAPABILITY"] = "1", @@ -38,8 +33,7 @@ public async Task WhenCapabilityIsMissingShouldFail() testHostResult.AssertOutputContains("The current test framework does not implement 'IGracefulStopTestExecutionCapability' which is required for '--maximum-failed-tests' feature."); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string Sources = """ #file MaxFailedTestsExtensionTests.csproj @@ -74,11 +68,11 @@ internal sealed class Program public static async Task Main(string[] args) { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); - var adapter = new DummyAdapter(); - builder.RegisterTestFramework(_ => new Capabilities(), (_, __) => adapter); + var testFramework = new DummyTestFramework(); + builder.RegisterTestFramework(_ => new Capabilities(), (_, __) => testFramework); #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. - builder.AddMaximumFailedTestsService(adapter); + builder.AddMaximumFailedTestsService(testFramework); #pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. using ITestApplication app = await builder.BuildAsync(); @@ -86,9 +80,9 @@ public static async Task Main(string[] args) } } -internal class DummyAdapter : ITestFramework, IDataProducer +internal class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => string.Empty; diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj index 45b3af34c2..8e13bcf2f9 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj @@ -4,9 +4,9 @@ $(NetCurrent) $(TestRunnerAdditionalArguments) --retry-failed-tests 3 false + true $(DefineConstants);SKIP_INTERMEDIATE_TARGET_FRAMEWORKS Exe - true @@ -24,21 +24,15 @@ - + + + - - - - - - - - diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/NoBannerTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/NoBannerTests.cs index 599edb8d81..9e7308c844 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/NoBannerTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/NoBannerTests.cs @@ -1,35 +1,30 @@ // 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.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class NoBannerTests : AcceptanceTestBase +[TestClass] +public class NoBannerTests : AcceptanceTestBase { private const string AssetName = "NoBannerTest"; - private readonly TestAssetFixture _testAssetFixture; private readonly string _bannerRegexMatchPattern = @".NET Testing Platform v.+ \[.+\]"; - public NoBannerTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task UsingNoBanner_TheBannerDoesNotAppear(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--no-banner"); testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); testHostResult.AssertOutputDoesNotMatchRegex(_bannerRegexMatchPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task UsingNoBanner_InTheEnvironmentVars_TheBannerDoesNotAppear(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( null, new Dictionary @@ -41,10 +36,11 @@ public async Task UsingNoBanner_InTheEnvironmentVars_TheBannerDoesNotAppear(stri testHostResult.AssertOutputDoesNotMatchRegex(_bannerRegexMatchPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task UsingDotnetNoLogo_InTheEnvironmentVars_TheBannerDoesNotAppear(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( null, new Dictionary @@ -56,18 +52,18 @@ public async Task UsingDotnetNoLogo_InTheEnvironmentVars_TheBannerDoesNotAppear( testHostResult.AssertOutputDoesNotMatchRegex(_bannerRegexMatchPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task WithoutUsingNoBanner_TheBannerAppears(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); testHostResult.AssertOutputMatchesRegex(_bannerRegexMatchPattern); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string NoBannerTestCode = """ #file NoBannerTest.csproj @@ -96,21 +92,21 @@ public class Program public static async Task Main(string[] args) { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); - builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestAdapter()); + builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestFramework()); using ITestApplication app = await builder.BuildAsync(); return await app.RunAsync(); } } -public class DummyTestAdapter : ITestFramework +public class DummyTestFramework : ITestFramework { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs index f78a15125c..4514fbbfd0 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs @@ -2,10 +2,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Diagnostics; +using System.Reflection; using Microsoft.Testing.Extensions; -using Microsoft.Testing.Internal.Framework.Configurations; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests; + +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] +[assembly: ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] // Opt-out telemetry Environment.SetEnvironmentVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1"); @@ -15,7 +17,7 @@ ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new TestFrameworkConfiguration(Debugger.IsAttached ? 1 : Environment.ProcessorCount), new SourceGeneratedTestNodesBuilder()); +builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]); #if ENABLE_CODECOVERAGE builder.AddCodeCoverageProvider(); #endif diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Properties/launchSettings.json b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Properties/launchSettings.json index 2610486891..aefd9415fa 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Properties/launchSettings.json +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Microsoft.Testing.Platform.Acceptance.IntegrationTests": { "commandName": "Project", - "commandLineArgs": "--treenode-filter /*/*/*/**", + "commandLineArgs": "", "environmentVariables": { //"TESTINGPLATFORM_HOTRELOAD_ENABLED": "1" } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs index fc136a2958..3215b5ad54 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs @@ -9,19 +9,15 @@ namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public sealed partial class ServerLoggingTests : ServerModeTestsBase +[TestClass] +public sealed partial class ServerLoggingTests : ServerModeTestsBase { - private readonly TestAssetFixture _testAssetFixture; - - public ServerLoggingTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - + [TestMethod] public async Task RunningInServerJsonRpcModeShouldHaveOutputDeviceLogsPushedToTestExplorer() { - string tfm = TargetFrameworks.NetCurrent.Arguments; - string resultDirectory = Path.Combine(_testAssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), tfm); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "ServerLoggingTests", tfm); + string tfm = TargetFrameworks.NetCurrent; + string resultDirectory = Path.Combine(AssetFixture.TargetAssetPath, Guid.NewGuid().ToString("N"), tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "ServerLoggingTests", tfm); using TestingPlatformClient jsonClient = await StartAsServerAndConnectToTheClientAsync(testHost); LogsCollector logs = new(); jsonClient.RegisterLogListener(logs); @@ -43,27 +39,26 @@ public async Task RunningInServerJsonRpcModeShouldHaveOutputDeviceLogsPushedToTe Assert.AreEqual( $$""" Log { LogLevel = Information, Message = Connecting to client host '127.0.0.1' port '{{port}}' } - Log { LogLevel = Trace, Message = Starting test session. Log file path is '{{logPath}}'. } + Log { LogLevel = Trace, Message = Starting test session. The log file path is '{{logPath}}'. } Log { LogLevel = Error, Message = System.Exception: This is an exception output } - Log { LogLevel = Error, Message = This is a red output with padding set to 3 } - Log { LogLevel = Warning, Message = This is a yellow output with padding set to 2 } + Log { LogLevel = Information, Message = This is a red output with padding set to 3 } + Log { LogLevel = Information, Message = This is a yellow output with padding set to 2 } Log { LogLevel = Information, Message = This is a blue output with padding set to 1 } Log { LogLevel = Information, Message = This is normal text output. } - Log { LogLevel = Trace, Message = Finished test session } - Log { LogLevel = Trace, Message = Starting test session. Log file path is '{{logPath}}'. } + Log { LogLevel = Trace, Message = Finished test session. } + Log { LogLevel = Trace, Message = Starting test session. The log file path is '{{logPath}}'. } Log { LogLevel = Error, Message = System.Exception: This is an exception output } - Log { LogLevel = Error, Message = This is a red output with padding set to 3 } - Log { LogLevel = Warning, Message = This is a yellow output with padding set to 2 } + Log { LogLevel = Information, Message = This is a red output with padding set to 3 } + Log { LogLevel = Information, Message = This is a yellow output with padding set to 2 } Log { LogLevel = Information, Message = This is a blue output with padding set to 1 } Log { LogLevel = Information, Message = This is normal text output. } - Log { LogLevel = Trace, Message = Finished test session } + Log { LogLevel = Trace, Message = Finished test session. } """, logsString); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { - private const string AssetName = "TestAssetFixture"; + private const string AssetName = "AssetFixture"; public string TargetAssetPath => GetAssetPath(AssetName); @@ -109,28 +104,28 @@ public class Startup public static async Task Main(string[] args) { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); - builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, serviceProvider) => new DummyTestAdapter(serviceProvider)); + builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, serviceProvider) => new DummyTestFramework(serviceProvider)); using ITestApplication app = await builder.BuildAsync(); return await app.RunAsync(); } } -public class DummyTestAdapter : ITestFramework, IDataProducer, IOutputDeviceDataProducer +public class DummyTestFramework : ITestFramework, IDataProducer, IOutputDeviceDataProducer { private readonly IOutputDevice _outputDevice; - public DummyTestAdapter(IServiceProvider serviceProvider) + public DummyTestFramework(IServiceProvider serviceProvider) { _outputDevice = serviceProvider.GetOutputDevice(); } - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs index 48cafde0c2..4c8706a742 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs @@ -3,29 +3,23 @@ using System.Text.RegularExpressions; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; using Microsoft.Testing.Platform.Configurations; -using Microsoft.Testing.Platform.Helpers; namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class TelemetryTests : AcceptanceTestBase +[TestClass] +public class TelemetryTests : AcceptanceTestBase { private const string AssetName = "TelemetryTest"; - private readonly TestAssetFixture _testAssetFixture; - - public TelemetryTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Telemetry_ByDefault_TelemetryIsEnabled(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); + string diagPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); string diagPathPattern = Path.Combine(diagPath, @"log_.*.diag").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--diagnostic", disableTelemetry: false); testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); @@ -40,13 +34,14 @@ public async Task Telemetry_ByDefault_TelemetryIsEnabled(string tfm) await AssertDiagnosticReportAsync(testHostResult, diagPathPattern, diagContentsPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Telemetry_WhenOptingOutTelemetry_WithEnvironmentVariable_TelemetryIsDisabled(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); + string diagPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); string diagPathPattern = Path.Combine(diagPath, @"log_.*.diag").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--diagnostic", new Dictionary @@ -67,13 +62,14 @@ public async Task Telemetry_WhenOptingOutTelemetry_WithEnvironmentVariable_Telem await AssertDiagnosticReportAsync(testHostResult, diagPathPattern, diagContentsPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Telemetry_WhenOptingOutTelemetry_With_DOTNET_CLI_EnvironmentVariable_TelemetryIsDisabled(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); + string diagPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); string diagPathPattern = Path.Combine(diagPath, @"log_.*.diag").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( "--diagnostic", new Dictionary @@ -94,13 +90,14 @@ public async Task Telemetry_WhenOptingOutTelemetry_With_DOTNET_CLI_EnvironmentVa await AssertDiagnosticReportAsync(testHostResult, diagPathPattern, diagContentsPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Telemetry_WhenEnableTelemetryIsFalse_WithTestApplicationOptions_TelemetryIsDisabled(string tfm) { - string diagPath = Path.Combine(_testAssetFixture.TargetAssetPathWithDisableTelemetry, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); + string diagPath = Path.Combine(AssetFixture.TargetAssetPathWithDisableTelemetry, "bin", "Release", tfm, AggregatedConfiguration.DefaultTestResultFolderName); string diagPathPattern = Path.Combine(diagPath, @"log_.*.diag").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPathWithDisableTelemetry, AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPathWithDisableTelemetry, AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--diagnostic", disableTelemetry: false); testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); @@ -138,8 +135,7 @@ private async Task AssertDiagnosticReportAsync(TestHostResult testHostRe return (Regex.IsMatch(content, pattern), content); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string WithTelemetry = nameof(WithTelemetry); private const string WithoutTelemetry = nameof(WithoutTelemetry); @@ -171,21 +167,21 @@ public class Program public static async Task Main(string[] args) { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args$TelemetryArg$); - builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestAdapter()); + builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestFramework()); using ITestApplication app = await builder.BuildAsync(); return await app.RunAsync(); } } -public class DummyTestAdapter : ITestFramework +public class DummyTestFramework : ITestFramework { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs index a2bcd24716..ea7644e892 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TestHostProcessLifetimeHandlerTests.cs @@ -1,34 +1,26 @@ // 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.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public sealed class TestHostProcessLifetimeHandlerTests : AcceptanceTestBase +[TestClass] +public sealed class TestHostProcessLifetimeHandlerTests : AcceptanceTestBase { private const string AssetName = "TestHostProcessLifetimeHandler"; - private readonly TestAssetFixture _testAssetFixture; - - public TestHostProcessLifetimeHandlerTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task All_Interface_Methods_ShouldBe_Invoked(string currentTfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, AssetName, currentTfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, currentTfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertExitCodeIs(ExitCodes.Success); - Assert.AreEqual(File.ReadAllText(Path.Combine(testHost.DirectoryName, "BeforeTestHostProcessStartAsync.txt")), "TestHostProcessLifetimeHandler.BeforeTestHostProcessStartAsync"); - Assert.AreEqual(File.ReadAllText(Path.Combine(testHost.DirectoryName, "OnTestHostProcessStartedAsync.txt")), "TestHostProcessLifetimeHandler.OnTestHostProcessStartedAsync"); - Assert.AreEqual(File.ReadAllText(Path.Combine(testHost.DirectoryName, "OnTestHostProcessExitedAsync.txt")), "TestHostProcessLifetimeHandler.OnTestHostProcessExitedAsync"); + Assert.AreEqual("TestHostProcessLifetimeHandler.BeforeTestHostProcessStartAsync", File.ReadAllText(Path.Combine(testHost.DirectoryName, "BeforeTestHostProcessStartAsync.txt"))); + Assert.AreEqual("TestHostProcessLifetimeHandler.OnTestHostProcessStartedAsync", File.ReadAllText(Path.Combine(testHost.DirectoryName, "OnTestHostProcessStartedAsync.txt"))); + Assert.AreEqual("TestHostProcessLifetimeHandler.OnTestHostProcessExitedAsync", File.ReadAllText(Path.Combine(testHost.DirectoryName, "OnTestHostProcessExitedAsync.txt"))); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) - : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string Sources = """ #file TestHostProcessLifetimeHandler.csproj @@ -66,7 +58,7 @@ public class Startup public static async Task Main(string[] args) { var testApplicationBuilder = await TestApplication.CreateBuilderAsync(args); - testApplicationBuilder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestAdapter()); + testApplicationBuilder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestFramework()); testApplicationBuilder.TestHostControllers.AddProcessLifetimeHandler(_ => new TestHostProcessLifetimeHandler()); using ITestApplication app = await testApplicationBuilder.BuildAsync(); return await app.RunAsync(); @@ -107,15 +99,15 @@ public Task OnTestHostProcessStartedAsync(ITestHostProcessInformation testHostPr } } -public class DummyTestAdapter : ITestFramework, IDataProducer +public class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs index fb370f1722..91a7a293f8 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs @@ -1,97 +1,95 @@ // 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.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class TimeoutTests : AcceptanceTestBase +[TestClass] +public class TimeoutTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public TimeoutTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task TimeoutWithInvalidArg_WithoutLetterSuffix_OutputInvalidMessage(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 5"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.StandardError.Contains("'timeout' option should have one argument as string in the format [h|m|s] where 'value' is float"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task TimeoutWithInvalidArg_WithInvalidLetterSuffix_OutputInvalidMessage(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 5y"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.StandardError.Contains("'timeout' option should have one argument as string in the format [h|m|s] where 'value' is float"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task TimeoutWithInvalidArg_WithInvalidFormat_OutputInvalidMessage(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 5h6m"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.StandardError.Contains("'timeout' option should have one argument as string in the format [h|m|s] where 'value' is float"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task TimeoutWithValidArg_WithTestTimeOut_OutputContainsCancelingMessage(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 1s"); testHostResult.AssertExitCodeIsNot(ExitCodes.Success); testHostResult.StandardOutput.Contains("Canceling the test session"); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task TimeoutWithValidArg_WithSecondAsSuffix_WithTestNotTimeOut_OutputDoesNotContainCancelingMessage(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 12.5s"); - testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); string output = testHostResult.StandardOutput; Assert.IsFalse(output.Contains("Canceling the test session")); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task TimeoutWithValidArg_WithMinuteAsSuffix_WithTestNotTimeOut_OutputDoesNotContainCancelingMessage(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 1m"); - testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); string output = testHostResult.StandardOutput; Assert.IsFalse(output.Contains("Canceling the test session")); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task TimeoutWithValidArg_WithHourAsSuffix_WithTestNotTimeOut_OutputDoesNotContainCancelingMessage(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.NoExtensionTargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--timeout 1h"); - testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); string output = testHostResult.StandardOutput; Assert.IsFalse(output.Contains("Canceling the test session")); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string AssetName = "TimeoutTest"; @@ -107,38 +105,52 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test preview - - - - #file Program.cs -using TimeoutTest; -ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new SourceGeneratedTestNodesBuilder()); -using ITestApplication app = await builder.BuildAsync(); -return await app.RunAsync(); - -#file UnitTest1.cs -namespace TimeoutTest; +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.Services; -[TestGroup] -public class UnitTest1 +public class Program { - public void TestMethod1() + public static async Task Main(string[] args) { - Assert.IsTrue(true); - Thread.Sleep(10000); + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + builder.RegisterTestFramework( + sp => new TestFrameworkCapabilities(), + (_,__) => new DummyTestFramework()); + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); } } -#file Usings.cs -global using Microsoft.Testing.Platform.Builder; -global using Microsoft.Testing.Internal.Framework; -global using Microsoft.Testing.Extensions; +public class DummyTestFramework : ITestFramework +{ + public string Uid => nameof(DummyTestFramework); + + public string Version => "2.0.0"; + + public string DisplayName => nameof(DummyTestFramework); + + public string Description => nameof(DummyTestFramework); + + public Task IsEnabledAsync() => Task.FromResult(true); + + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + public Task ExecuteRequestAsync(ExecuteRequestContext context) + { + Thread.Sleep(10000); + context.Complete(); + return Task.CompletedTask; + } +} """; public string NoExtensionTargetAssetPath => GetAssetPath(AssetName); @@ -149,8 +161,7 @@ public void TestMethod1() TestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); } } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs index 4fd844ccc6..9c86e5770a 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs @@ -4,23 +4,16 @@ using System.Runtime.InteropServices; using System.Text.RegularExpressions; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class TrxTests : AcceptanceTestBase +[TestClass] +public class TrxTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public TrxTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Trx_WhenReportTrxIsNotSpecified_TrxReportIsNotGenerated(string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(); testHostResult.AssertExitCodeIs(ExitCodes.Success); @@ -32,20 +25,22 @@ public async Task Trx_WhenReportTrxIsNotSpecified_TrxReportIsNotGenerated(string testHostResult.AssertOutputDoesNotMatchRegex(outputPattern); } - [ArgumentsProvider(nameof(TargetFrameworks.All), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Trx_WhenReportTrxIsSpecified_TrxReportIsGeneratedInDefaultLocation(string tfm) { - string testResultsPath = Path.Combine(_testAssetFixture.TargetAssetPath, "bin", "Release", tfm, "TestResults"); + string testResultsPath = Path.Combine(AssetFixture.TargetAssetPath, "bin", "Release", tfm, "TestResults"); string trxPathPattern = Path.Combine(testResultsPath, ".*.trx").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--report-trx"); // number of test is the third param because we have two different test code with different number of tests. await AssertTrxReportWasGeneratedAsync(testHostResult, trxPathPattern, 1); } - [ArgumentsProvider(nameof(TargetFrameworks.Net), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.NetForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Trx_WhenTestHostCrash_ErrorIsDisplayedInsideTheTrx(string tfm) { if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) @@ -55,7 +50,7 @@ public async Task Trx_WhenTestHostCrash_ErrorIsDisplayedInsideTheTrx(string tfm) } string fileName = Guid.NewGuid().ToString("N"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, TestAssetFixture.AssetName, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, TestAssetFixture.AssetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync( $"--crashdump --report-trx --report-trx-filename {fileName}.trx", new() { { "CRASHPROCESS", "1" } }); @@ -64,15 +59,16 @@ public async Task Trx_WhenTestHostCrash_ErrorIsDisplayedInsideTheTrx(string tfm) string trxFile = Directory.GetFiles(testHost.DirectoryName, $"{fileName}.trx", SearchOption.AllDirectories).Single(); string trxContent = File.ReadAllText(trxFile); - Assert.That(Regex.IsMatch(trxContent, @"Test host process pid: .* crashed\."), trxContent); - Assert.That(trxContent.Contains(""""""), trxContent); + Assert.IsTrue(Regex.IsMatch(trxContent, @"Test host process pid: .* crashed\."), trxContent); + StringAssert.Contains(trxContent, """""", trxContent); } - [ArgumentsProvider(nameof(TargetFrameworks.Net), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.NetForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Trx_WhenSkipTest_ItAppearsAsExpectedInsideTheTrx(string tfm) { string fileName = Guid.NewGuid().ToString("N"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPathWithSkippedTest, TestAssetFixture.AssetNameUsingMSTest, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPathWithSkippedTest, TestAssetFixture.AssetNameUsingMSTest, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync($"--report-trx --report-trx-filename {fileName}.trx"); testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); @@ -82,33 +78,34 @@ public async Task Trx_WhenSkipTest_ItAppearsAsExpectedInsideTheTrx(string tfm) string trxContent = File.ReadAllText(trxFile); // check if the tests have been added to Results, TestDefinitions, TestEntries and ResultSummary. - Assert.That(trxContent.Contains(@""""), trxContent); - Assert.That(trxContent.Contains(""""""), trxContent); + StringAssert.Contains(trxContent, @"""", trxContent); + StringAssert.Contains(trxContent, """""", trxContent); } - [ArgumentsProvider(nameof(TargetFrameworks.Net), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.NetForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Trx_WhenTheTestNameHasInvalidXmlChar_TheTrxCreatedSuccessfully(string tfm) { - string testResultsPath = Path.Combine(_testAssetFixture.TargetAssetPathWithDataRow, "bin", "Release", tfm, "TestResults"); + string testResultsPath = Path.Combine(AssetFixture.TargetAssetPathWithDataRow, "bin", "Release", tfm, "TestResults"); string trxPathPattern = Path.Combine(testResultsPath, ".*.trx").Replace(@"\", @"\\"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPathWithDataRow, TestAssetFixture.AssetNameUsingMSTest, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPathWithDataRow, TestAssetFixture.AssetNameUsingMSTest, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync("--report-trx"); // number of test is the third param because we have two different test code with different number of tests. await AssertTrxReportWasGeneratedAsync(testHostResult, trxPathPattern, 2); } - [ArgumentsProvider(nameof(TargetFrameworks.Net), typeof(TargetFrameworks))] + [DynamicData(nameof(TargetFrameworks.NetForDynamicData), typeof(TargetFrameworks))] + [TestMethod] public async Task Trx_UsingDataDriven_CreatesUnitTestTagForEachOneInsideTheTrx(string tfm) { string fileName = Guid.NewGuid().ToString("N"); - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPathWithSkippedTest, TestAssetFixture.AssetNameUsingMSTest, tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPathWithSkippedTest, TestAssetFixture.AssetNameUsingMSTest, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync($"--report-trx --report-trx-filename {fileName}.trx"); testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); @@ -122,47 +119,51 @@ public async Task Trx_UsingDataDriven_CreatesUnitTestTagForEachOneInsideTheTrx(s \s* CheckTrxContentsMatchAsync(string path, string pattern) return Regex.IsMatch(await reader.ReadToEndAsync(), pattern); } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string AssetName = "TrxTest"; public const string AssetNameUsingMSTest = "TrxTestUsingMSTest"; @@ -218,45 +218,73 @@ public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : Test - - - - - #file Program.cs -using TrxTest; -ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new SourceGeneratedTestNodesBuilder()); -builder.AddCrashDumpProvider(); -builder.AddTrxReportProvider(); -using ITestApplication app = await builder.BuildAsync(); -return await app.RunAsync(); +using Microsoft.Testing.Extensions; +using Microsoft.Testing.Extensions.TrxReport.Abstractions; +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.Services; + +public class Program +{ + public static async Task Main(string[] args) + { + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + builder.RegisterTestFramework( + sp => new TestFrameworkCapabilities(new TrxReportCapability()), + (_,__) => new DummyTestFramework()); + builder.AddCrashDumpProvider(); + builder.AddTrxReportProvider(); + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); + } +} -#file UnitTest1.cs -namespace TrxTest; +public class TrxReportCapability : ITrxReportCapability +{ + bool ITrxReportCapability.IsSupported { get; } = true; + void ITrxReportCapability.Enable() + { + } +} -[TestGroup] -public class UnitTest1 +public class DummyTestFramework : ITestFramework, IDataProducer { - public void TestMethod1() + public string Uid => nameof(DummyTestFramework); + + public string Version => "2.0.0"; + + public string DisplayName => nameof(DummyTestFramework); + + public string Description => nameof(DummyTestFramework); + + public Type[] DataTypesProduced => new[] { typeof(TestNodeUpdateMessage) }; + + public Task IsEnabledAsync() => Task.FromResult(true); + + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + + public async Task ExecuteRequestAsync(ExecuteRequestContext context) { if (Environment.GetEnvironmentVariable("CRASHPROCESS") == "1") { Environment.FailFast("CRASHPROCESS"); } - Assert.IsTrue(true); + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "0", DisplayName = "Test", Properties = new(PassedTestNodeStateProperty.CachedInstance) })); + context.Complete(); } } - -#file Usings.cs -global using System; -global using Microsoft.Testing.Platform.Builder; -global using Microsoft.Testing.Internal.Framework; -global using Microsoft.Testing.Extensions; """; private const string MSTestCode = """ @@ -270,6 +298,7 @@ public void TestMethod1() true preview true + false @@ -319,8 +348,7 @@ public void TestMethod1(string s) TestCode .PatchTargetFrameworks(TargetFrameworks.All) .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) - .PatchCodeWithReplace("$MicrosoftTestingInternalFrameworkVersion$", MicrosoftTestingInternalFrameworkVersion)); + .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); yield return (WithSkippedTest, AssetNameUsingMSTest, MSTestCode .PatchTargetFrameworks(TargetFrameworks.All) diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/UnhandledExceptionPolicyTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/UnhandledExceptionPolicyTests.cs index 209cd2005f..004d1aeb94 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/UnhandledExceptionPolicyTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/UnhandledExceptionPolicyTests.cs @@ -3,19 +3,11 @@ using System.Runtime.InteropServices; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; -using Microsoft.Testing.Platform.Helpers; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; -[TestGroup] -public class UnhandledExceptionPolicyTests : AcceptanceTestBase +[TestClass] +public class UnhandledExceptionPolicyTests : AcceptanceTestBase { - private readonly TestAssetFixture _testAssetFixture; - - public UnhandledExceptionPolicyTests(ITestExecutionContext testExecutionContext, TestAssetFixture testAssetFixture) - : base(testExecutionContext) => _testAssetFixture = testAssetFixture; - public enum Mode { Enabled, @@ -25,22 +17,23 @@ public enum Mode Default, } - internal static IEnumerable> ModeProvider() + internal static IEnumerable<(Mode Mode, string Arguments)> ModeProvider() { - foreach (TestArgumentsEntry tfm in TargetFrameworks.All) + foreach (string tfm in TargetFrameworks.All) { - yield return new TestArgumentsEntry<(Mode, string)>((Mode.Enabled, tfm.Arguments), $"Enabled - {tfm.Arguments}"); - yield return new TestArgumentsEntry<(Mode, string)>((Mode.Disabled, tfm.Arguments), $"Disabled - {tfm.Arguments}"); - yield return new TestArgumentsEntry<(Mode, string)>((Mode.DisabledByEnvironmentVariable, tfm.Arguments), $"DisabledByEnvironmentVariable - {tfm.Arguments}"); - yield return new TestArgumentsEntry<(Mode, string)>((Mode.EnabledByEnvironmentVariable, tfm.Arguments), $"EnabledByEnvironmentVariable - {tfm.Arguments}"); - yield return new TestArgumentsEntry<(Mode, string)>((Mode.Default, tfm.Arguments), $"Default - ({tfm.Arguments})"); + yield return new(Mode.Enabled, tfm); + yield return new(Mode.Disabled, tfm); + yield return new(Mode.DisabledByEnvironmentVariable, tfm); + yield return new(Mode.EnabledByEnvironmentVariable, tfm); + yield return new(Mode.Default, tfm); } } - [ArgumentsProvider(nameof(ModeProvider))] + [DynamicData(nameof(ModeProvider), DynamicDataSourceType.Method)] + [TestMethod] public async Task UnhandledExceptionPolicy_ConfigFile_UnobservedTaskException_ShouldCrashProcessIfEnabled(Mode mode, string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "UnhandledExceptionPolicyTests", tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "UnhandledExceptionPolicyTests", tfm); using TempDirectory clone = new(); await clone.CopyDirectoryAsync(testHost.DirectoryName, clone.Path, retainAttributes: !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); testHost = TestInfrastructure.TestHost.LocateFrom(clone.Path, "UnhandledExceptionPolicyTests"); @@ -93,10 +86,11 @@ public async Task UnhandledExceptionPolicy_ConfigFile_UnobservedTaskException_Sh } } - [ArgumentsProvider(nameof(ModeProvider))] + [DynamicData(nameof(ModeProvider), DynamicDataSourceType.Method)] + [TestMethod] public async Task UnhandledExceptionPolicy_EnvironmentVariable_UnhandledException_ShouldCrashProcessIfEnabled(Mode mode, string tfm) { - var testHost = TestInfrastructure.TestHost.LocateFrom(_testAssetFixture.TargetAssetPath, "UnhandledExceptionPolicyTests", tfm); + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, "UnhandledExceptionPolicyTests", tfm); using TempDirectory clone = new(); await clone.CopyDirectoryAsync(testHost.DirectoryName, clone.Path, retainAttributes: !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); testHost = TestInfrastructure.TestHost.LocateFrom(clone.Path, "UnhandledExceptionPolicyTests"); @@ -151,8 +145,7 @@ public async Task UnhandledExceptionPolicy_EnvironmentVariable_UnhandledExceptio } } - [TestFixture(TestFixtureSharingStrategy.PerTestGroup)] - public sealed class TestAssetFixture(AcceptanceFixture acceptanceFixture) : TestAssetFixtureBase(acceptanceFixture.NuGetGlobalPackagesFolder) + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { private const string AssetName = "UnhandledExceptionPolicyTests"; @@ -208,21 +201,21 @@ public class Startup public static async Task Main(string[] args) { ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); - builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestAdapter()); + builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_,__) => new DummyTestFramework()); using ITestApplication app = await builder.BuildAsync(); return await app.RunAsync(); } } -public class DummyTestAdapter : ITestFramework, IDataProducer +public class DummyTestFramework : ITestFramework, IDataProducer { - public string Uid => nameof(DummyTestAdapter); + public string Uid => nameof(DummyTestFramework); public string Version => "2.0.0"; - public string DisplayName => nameof(DummyTestAdapter); + public string DisplayName => nameof(DummyTestFramework); - public string Description => nameof(DummyTestAdapter); + public string Description => nameof(DummyTestFramework); public Task IsEnabledAsync() => Task.FromResult(true); diff --git a/test/Performance/MSTest.Performance.Runner/Program.cs b/test/Performance/MSTest.Performance.Runner/Program.cs index c5e424ee05..11775c0650 100644 --- a/test/Performance/MSTest.Performance.Runner/Program.cs +++ b/test/Performance/MSTest.Performance.Runner/Program.cs @@ -5,10 +5,15 @@ using System.Runtime.InteropServices; using Microsoft.Testing.TestInfrastructure; +using Microsoft.VisualStudio.TestTools.UnitTesting; using MSTest.Performance.Runner.Steps; using DotnetMuxer = MSTest.Performance.Runner.Steps.DotnetMuxer; +using ExecutionScope = MSTest.Performance.Runner.Steps.ExecutionScope; + +// TODO: this should not be required +[assembly: Parallelize(Scope = Microsoft.VisualStudio.TestTools.UnitTesting.ExecutionScope.MethodLevel, Workers = 0)] namespace MSTest.Performance.Runner; diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyCleanupShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyCleanupShouldBeValidAnalyzerTests.cs index ad6c0b52bb..895d940aad 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyCleanupShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyCleanupShouldBeValidAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class AssemblyCleanupShouldBeValidAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class AssemblyCleanupShouldBeValidAnalyzerTests { + [TestMethod] public async Task WhenAssemblyCleanupIsPublic_NoDiagnostic() { string code = """ @@ -28,6 +29,7 @@ public static void AssemblyCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAssemblyCleanIsInsideAGenericClass_Diagnostic() { string code = """ @@ -49,6 +51,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenAssemblyCleanupIsNotOrdinary_Diagnostic() { string code = """ @@ -70,6 +73,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenAssemblyCleanupIsPublic_InsideInternalClassWithDiscoverInternals_NoDiagnostic() { string code = """ @@ -90,6 +94,7 @@ public static void AssemblyCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAssemblyCleanupIsInternal_InsidePublicClassWithDiscoverInternals_Diagnostic() { string code = """ @@ -128,10 +133,11 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } - [Arguments("protected")] - [Arguments("internal")] - [Arguments("internal protected")] - [Arguments("private")] + [DataRow("protected")] + [DataRow("internal")] + [DataRow("internal protected")] + [DataRow("private")] + [TestMethod] public async Task WhenAssemblyCleanupIsNotPublic_Diagnostic(string accessibility) { string code = $$""" @@ -166,6 +172,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyCleanupIsGeneric_Diagnostic() { string code = """ @@ -200,6 +207,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyCleanupIsNotStatic_Diagnostic() { string code = """ @@ -234,6 +242,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyCleanupHasParameters_Diagnostic() { string code = """ @@ -268,6 +277,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyCleanupReturnTypeIsNotValid_Diagnostic() { string code = """ @@ -375,6 +385,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyCleanupReturnTypeIsValid_NoDiagnostic() { string code = """ @@ -406,6 +417,7 @@ public static ValueTask AssemblyCleanup2() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAssemblyCleanupIsAsyncVoid_Diagnostic() { string code = """ @@ -444,6 +456,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenMultipleViolations_TheyAllGetFixed() { string code = """ @@ -482,6 +495,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyCleanupIsNotOnClass_Diagnostic() { string code = """ @@ -499,6 +513,7 @@ public struct MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAssemblyCleanupIsOnClassNotMarkedWithTestClass_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyInitializeShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyInitializeShouldBeValidAnalyzerTests.cs index b6d2a58b3f..e7ffa9a0fe 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyInitializeShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyInitializeShouldBeValidAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class AssemblyInitializeShouldBeValidAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class AssemblyInitializeShouldBeValidAnalyzerTests { + [TestMethod] public async Task WhenAssemblyInitializeIsPublic_NoDiagnostic() { string code = """ @@ -28,6 +29,7 @@ public static void AssemblyInitialize(TestContext testContext) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAssemblyInitializeIsPublic_InsideInternalClassWithDiscoverInternals_NoDiagnostic() { string code = """ @@ -48,6 +50,7 @@ public static void AssemblyInitialize(TestContext testContext) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAssemblyInitializeIsInsideAGenericClass_Diagnostic() { string code = """ @@ -69,6 +72,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenAssemblyInitializeIsInternal_InsidePublicClassWithDiscoverInternals_Diagnostic() { string code = """ @@ -107,10 +111,11 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } - [Arguments("protected")] - [Arguments("internal")] - [Arguments("internal protected")] - [Arguments("private")] + [DataRow("protected")] + [DataRow("internal")] + [DataRow("internal protected")] + [DataRow("private")] + [TestMethod] public async Task WhenAssemblyInitializeIsNotPublic_Diagnostic(string accessibility) { string code = $$""" @@ -145,6 +150,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyInitializeIsNotOrdinary_Diagnostic() { string code = """ @@ -166,6 +172,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenAssemblyInitializeIsGeneric_Diagnostic() { string code = """ @@ -200,6 +207,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyInitializeIsNotStatic_Diagnostic() { string code = """ @@ -234,6 +242,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyInitializeDoesNotHaveParameters_Diagnostic() { string code = """ @@ -268,6 +277,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyInitializeReturnTypeIsNotValid_Diagnostic() { string code = """ @@ -371,6 +381,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyInitializeReturnTypeIsValid_NoDiagnostic() { string code = """ @@ -402,6 +413,7 @@ public static ValueTask AssemblyInitialize2(TestContext testContext) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAssemblyInitializeIsAsyncVoid_Diagnostic() { string code = """ @@ -440,6 +452,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenMultipleViolations_TheyAllGetFixed() { string code = """ @@ -478,6 +491,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssemblyInitializeIsNotOnClass_Diagnostic() { string code = """ @@ -495,6 +509,7 @@ public struct MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAssemblyInitializeIsOnClassNotMarkedWithTestClass_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldAvoidConditionalAccessAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldAvoidConditionalAccessAnalyzerTests.cs index f045776241..2a7f2b5ecc 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldAvoidConditionalAccessAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldAvoidConditionalAccessAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.UnitTests; -[TestGroup] -public sealed class AssertionArgsShouldAvoidConditionalAccessAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class AssertionArgsShouldAvoidConditionalAccessAnalyzerTests { + [TestMethod] public async Task WhenUsingConditionalsAccess_In_Assert_Equal() { string code = """ @@ -99,6 +100,7 @@ public void Compliant() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenUsingConditionalsAccess_In_Assert_Boolean() { string code = """ @@ -158,6 +160,7 @@ public void Compliant() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenUsingConditionalsAccess_In_NullAssertions_Gives_NoWarning() { string code = """ @@ -187,6 +190,7 @@ public void Compliant() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenUsingConditionalsAccess_In_CollectionAssert() { string code = """ @@ -258,6 +262,7 @@ public void Compliant() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenUsingConditionalsAccess_In_StringAssert() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldBePassedInCorrectOrderAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldBePassedInCorrectOrderAnalyzerTests.cs index 413be9c844..2084f21415 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldBePassedInCorrectOrderAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldBePassedInCorrectOrderAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.UnitTests; -[TestGroup] -public sealed class AssertionArgsShouldBePassedInCorrectOrderAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class AssertionArgsShouldBePassedInCorrectOrderAnalyzerTests { + [TestMethod] public async Task WhenUsingLiterals() { string code = """ @@ -161,6 +162,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task LiteralUsingNamedArgument() { string code = """ @@ -292,6 +294,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task ConstantValue() { string code = """ @@ -437,6 +440,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task ActualAsLocalVariableOrNot() { string code = """ @@ -501,6 +505,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task ActualOrExpectedPrefix() { string code = """ @@ -702,6 +707,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task MethodCalls() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs index 15e99f9f67..f194c77ce6 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs @@ -9,9 +9,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class AvoidExpectedExceptionAttributeAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class AvoidExpectedExceptionAttributeAnalyzerTests { + [TestMethod] public async Task WhenUsed_Diagnostic() { string code = """ @@ -121,6 +122,7 @@ public void TestMethod2() await test.RunAsync(CancellationToken.None); } + [TestMethod] public async Task When_Statement_Block_Diagnostic() { string code = """ @@ -157,6 +159,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task When_Statement_ExpressionBody_Diagnostic() { string code = """ @@ -189,6 +192,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task When_Expression_Block_Diagnostic() { string code = """ @@ -229,6 +233,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task When_Expression_ExpressionBody_Diagnostic() { string code = """ @@ -264,6 +269,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task When_Async_Block_Diagnostic() { string code = """ @@ -302,6 +308,7 @@ public async Task TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task When_Async_ExpressionBody_Diagnostic() { string code = """ @@ -336,6 +343,7 @@ public async Task TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task When_TestMethodIsAsyncButLastStatementIsSynchronous_Diagnostic() { string code = """ @@ -380,6 +388,7 @@ public async Task TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task When_LastStatementHasDeepAwait_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/ClassCleanupShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/ClassCleanupShouldBeValidAnalyzerTests.cs index 7fee442876..5c202bd625 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/ClassCleanupShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/ClassCleanupShouldBeValidAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class ClassCleanupShouldBeValidAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class ClassCleanupShouldBeValidAnalyzerTests { + [TestMethod] public async Task WhenClassCleanupIsPublic_NoDiagnostic() { string code = """ @@ -28,6 +29,7 @@ public static void ClassCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsGenericWithInheritanceModeSet_NoDiagnostic() { string code = """ @@ -46,6 +48,7 @@ public static void ClassCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsGenericWithInheritanceModeSetToNone_Diagnostic() { string code = """ @@ -67,6 +70,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenClassCleanupIsGenericWithoutSettingInheritanceMode_Diagnostic() { string code = """ @@ -88,6 +92,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenClassCleanupIsNotOrdinary_Diagnostic() { string code = """ @@ -109,6 +114,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenClassCleanupIsPublic_InsideInternalClassWithDiscoverInternals_NoDiagnostic() { string code = """ @@ -129,6 +135,7 @@ public static void ClassCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsInternal_InsidePublicClassWithDiscoverInternals_Diagnostic() { string code = """ @@ -167,10 +174,11 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } - [Arguments("protected")] - [Arguments("internal")] - [Arguments("internal protected")] - [Arguments("private")] + [DataRow("protected")] + [DataRow("internal")] + [DataRow("internal protected")] + [DataRow("private")] + [TestMethod] public async Task WhenClassCleanupIsNotPublic_Diagnostic(string accessibility) { string code = $$""" @@ -205,6 +213,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassCleanupIsGeneric_Diagnostic() { string code = """ @@ -239,6 +248,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassCleanupIsNotStatic_Diagnostic() { string code = """ @@ -273,6 +283,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassCleanupHasParameters_Diagnostic() { string code = """ @@ -307,6 +318,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassCleanupReturnTypeIsNotValid_Diagnostic() { string code = """ @@ -382,6 +394,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassCleanupReturnTypeIsValid_NoDiagnostic() { string code = """ @@ -413,6 +426,7 @@ public static ValueTask ClassCleanup2() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsAsyncVoid_Diagnostic() { string code = """ @@ -451,6 +465,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenMultipleViolations_TheyAllGetFixed() { string code = """ @@ -489,6 +504,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassCleanupIsNotOnClass_Diagnostic() { string code = """ @@ -506,6 +522,7 @@ public struct MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsOnSealedClassNotMarkedWithTestClass_Diagnostic() { string code = """ @@ -523,6 +540,7 @@ public sealed class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsOnNonSealedClassNotMarkedWithTestClass_NoDiagnostic() { string code = """ @@ -540,6 +558,7 @@ public static void ClassCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsOnAbstractClassNotMarkedWithTestClass_AndWithInheritanceBehavior_NoDiagnostic() { string code = """ @@ -557,6 +576,7 @@ public static void ClassCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsOnAbstractClassMarkedWithTestClass_AndWithInheritanceBehavior_NoDiagnostic() { string code = """ @@ -575,6 +595,7 @@ public static void ClassCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsAbstractClassNotMarkedWithTestClass_AndWithoutInheritanceBehavior_Diagnostic() { string code = """ @@ -592,6 +613,7 @@ public abstract class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsOnAbstractClassMarkedWithTestClass_AndWithoutInheritanceBehavior_Diagnostic() { string code = """ @@ -610,6 +632,7 @@ public abstract class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsOnAbstractClassMarkedWithTestClass_AndWithInheritanceBehaviorNone_Diagnostic() { string code = """ @@ -628,6 +651,7 @@ public abstract class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsOnSealedClassMarkedWithTestClass_AndWithInheritanceBehavior_Diagnostic() { string code = """ @@ -646,6 +670,7 @@ public sealed class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsOnSealedClassMarkedWithTestClass_AndWithInheritanceBehaviorNone_NoDiagnostic() { string code = """ @@ -664,6 +689,7 @@ public static void ClassCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassCleanupIsOnSealedClassMarkedWithTestClass_WithDefaultInheritanceBehavior_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/ClassInitializeShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/ClassInitializeShouldBeValidAnalyzerTests.cs index 171807825d..55cc137e6f 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/ClassInitializeShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/ClassInitializeShouldBeValidAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class ClassInitializeShouldBeValidAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class ClassInitializeShouldBeValidAnalyzerTests { + [TestMethod] public async Task WhenClassInitializeIsPublic_NoDiagnostic() { string code = """ @@ -28,6 +29,7 @@ public static void ClassInitialize(TestContext testContext) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsGenericWithInheritanceModeSet_NoDiagnostic() { string code = """ @@ -46,6 +48,7 @@ public static void ClassInitialize(TestContext testContext) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsGenericWithInheritanceModeSetToNone_Diagnostic() { string code = """ @@ -67,6 +70,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenClassInitializeIsGenericWithoutSettingInheritanceMode_Diagnostic() { string code = """ @@ -88,6 +92,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenClassInitializeIsPublic_InsideInternalClassWithDiscoverInternals_NoDiagnostic() { string code = """ @@ -108,6 +113,7 @@ public static void ClassInitialize(TestContext testContext) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsInternal_InsidePublicClassWithDiscoverInternals_Diagnostic() { string code = """ @@ -148,10 +154,11 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } - [Arguments("protected")] - [Arguments("internal")] - [Arguments("internal protected")] - [Arguments("private")] + [DataRow("protected")] + [DataRow("internal")] + [DataRow("internal protected")] + [DataRow("private")] + [TestMethod] public async Task WhenClassInitializeIsNotPublic_Diagnostic(string accessibility) { string code = $$""" @@ -186,6 +193,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassInitializeIsNotOrdinary_Diagnostic() { string code = """ @@ -207,6 +215,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenClassInitializeIsGeneric_Diagnostic() { string code = """ @@ -241,6 +250,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassInitializeIsNotStatic_Diagnostic() { string code = """ @@ -275,6 +285,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassInitializeDoesNotHaveParameters_Diagnostic() { string code = """ @@ -309,6 +320,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassInitializeReturnTypeIsNotValid_Diagnostic() { string code = """ @@ -384,6 +396,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassInitializeReturnTypeIsValid_NoDiagnostic() { string code = """ @@ -415,6 +428,7 @@ public static ValueTask ClassInitialize2(TestContext testContext) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsAsyncVoid_Diagnostic() { string code = """ @@ -453,6 +467,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenMultipleViolations_TheyAllGetFixed() { string code = """ @@ -491,6 +506,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassInitializeIsNotOnClass_Diagnostic() { string code = """ @@ -508,6 +524,7 @@ public struct MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsOnSealedClassNotMarkedWithTestClass_Diagnostic() { string code = """ @@ -525,6 +542,7 @@ public sealed class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsOnNonSealedClassNotMarkedWithTestClass_NoDiagnostic() { string code = """ @@ -542,6 +560,7 @@ public static void ClassInitialize(TestContext testContext) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsOnAbstractClassNotMarkedWithTestClass_AndWithInheritanceBehavior_NoDiagnostic() { string code = """ @@ -559,6 +578,7 @@ public static void ClassInitialize(TestContext testContext) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsOnAbstractClassMarkedWithTestClass_AndWithInheritanceBehavior_NoDiagnostic() { string code = """ @@ -577,6 +597,7 @@ public static void ClassInitialize(TestContext testContext) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsAbstractClassNotMarkedWithTestClass_AndWithoutInheritanceBehavior_Diagnostic() { string code = """ @@ -594,6 +615,7 @@ public abstract class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsOnAbstractClassMarkedWithTestClass_AndWithoutInheritanceBehavior_Diagnostic() { string code = """ @@ -612,6 +634,7 @@ public abstract class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsOnAbstractClassMarkedWithTestClass_AndWithInheritanceBehaviorNone_Diagnostic() { string code = """ @@ -630,6 +653,7 @@ public abstract class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsOnSealedClassMarkedWithTestClass_AndWithInheritanceBehavior_Diagnostic() { string code = """ @@ -648,6 +672,7 @@ public sealed class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsOnSealedClassMarkedWithTestClass_AndWithInheritanceBehaviorNone_NoDiagnostic() { string code = """ @@ -666,6 +691,7 @@ public static void ClassInitialize(TestContext testContext) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassInitializeIsOnSealedClassMarkedWithTestClass_AndDefaultInheritanceBehavior_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DataRowShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DataRowShouldBeValidAnalyzerTests.cs index c5a50491a8..37e2ced325 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DataRowShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DataRowShouldBeValidAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class DataRowShouldBeValidAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class DataRowShouldBeValidAnalyzerTests { + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithOneArgument_NoDiagnostic() { string code = """ @@ -29,6 +30,7 @@ public void TestMethod1(int a) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithOneArgumentAndWithDataTestMethodAttribute_NoDiagnostic() { string code = """ @@ -48,6 +50,7 @@ public void TestMethod1(int a) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithOneArgumentAndWithDerivedTestMethodAttribute_NoDiagnostic() { string code = """ @@ -71,6 +74,7 @@ public void TestMethod1(int a) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithThreeArguments_NoDiagnostic() { string code = """ @@ -90,6 +94,7 @@ public void TestMethod1(int a, int b, int c) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithThreeArgumentsAndMethodHasParamsArgument_NoDiagnostic() { string code = """ @@ -109,6 +114,7 @@ public void TestMethod1(params object[] o) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithThreeArgumentsAndMethodHasArrayArgument_NoDiagnostic() { string code = """ @@ -128,6 +134,7 @@ public void TestMethod1(object[] o) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowPassesOneItemAndParameterExpectsArray_Diagnostic() { string code = """ @@ -151,6 +158,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments((0, 0))); } + [TestMethod] public async Task WhenDataRowHasThreeArgumentsAndMethodHasAnIntegerAndAnArrayArgument_Diagnostic() { string code = """ @@ -174,6 +182,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments(3, 2)); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithOneArgumentAndMethodHasAPrimitiveTypeAndAParamsArgument_NoDiagnostic() { string code = """ @@ -193,6 +202,7 @@ public void TestMethod1(int a, params object[] o) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithThreeArgumentsAndMethodHasAPrimitiveTypeAndAParamsArgument_NoDiagnostic() { string code = """ @@ -212,6 +222,7 @@ public void TestMethod1(int a, params object[] o) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithOneArgumentAndMethodHasAPrimitiveTypeAndAParamsStringArgument_NoDiagnostic() { string code = """ @@ -231,6 +242,7 @@ public void TestMethod1(int a, params string[] o) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithOneArgumentAndMethodHasAPrimitiveTypeAndADefaultArgument_NoDiagnostic() { string code = """ @@ -252,6 +264,7 @@ public void TestMethod1(int a, object?[]? o = null) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithOneArgumentAndIntegersAreAssignableToDoubles_NoDiagnostic() { string code = """ @@ -271,6 +284,7 @@ public void TestMethod1(double d) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithOneArgumentAndCharsAreAssignableToIntegers_NoDiagnostic() { string code = """ @@ -290,6 +304,7 @@ public void TestMethod1(int i) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowIsCorrectlyDefinedWithOneArgumentAndNullsAreAssignableToIntegers_NoDiagnostic() { string code = """ @@ -309,6 +324,7 @@ public void TestMethod1(int i) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataRowHasOneNullArgumentAndMethodHasNoArguments_Diagnostic() { string code = """ @@ -332,6 +348,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments(1, 0)); } + [TestMethod] public async Task WhenDataRowIsNotSetOnATestMethod_Diagnostic() { string code = """ @@ -351,6 +368,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code, VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.DataRowOnTestMethodRule).WithLocation(0)); } + [TestMethod] public async Task WhenDataRowHasNoArgsButMethodHasOneArgument_Diagnostic() { string code = """ @@ -375,6 +393,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments(0, 1)); } + [TestMethod] public async Task WhenDataRowHasArgumentMismatchWithTestMethod_Diagnostic() { string code = """ @@ -399,6 +418,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments(3, 4)); } + [TestMethod] public async Task WhenDataRowHasArgumentMismatchWithTestMethod2_Diagnostic() { string code = """ @@ -423,6 +443,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments(3, 2)); } + [TestMethod] public async Task WhenDataRowHasArgumentMismatchWithTestMethod3_Diagnostic() { string code = """ @@ -447,6 +468,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments(3, 2)); } + [TestMethod] public async Task WhenDataRowHasTypeMismatchWithTestMethod_Diagnostic() { string code = """ @@ -471,6 +493,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments((2, 2))); } + [TestMethod] public async Task DefaultArguments() { string code = """ @@ -508,6 +531,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DataRowShouldBeValidAnalyzer.ArgumentCountMismatchRule).WithLocation(2).WithArguments(1, 5)); } + [TestMethod] public async Task Testfx_2606_NullArgumentForArray() { string code = """ @@ -540,6 +564,7 @@ public void TestSomething( await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task Issue2856_ArraysInDataRow_NoDiagnostic() { string code = """ @@ -561,6 +586,7 @@ public void ItemsTest(int[] input) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenMethodIsGeneric() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotNegateBooleanAssertionAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotNegateBooleanAssertionAnalyzerTests.cs index efcad90561..f4e145e21e 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotNegateBooleanAssertionAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotNegateBooleanAssertionAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class DoNotNegateBooleanAssertionAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class DoNotNegateBooleanAssertionAnalyzerTests { + [TestMethod] public async Task WhenAssertionIsNotNegated_NoDiagnostic() { string code = """ @@ -41,6 +42,7 @@ public void TestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAssertionIsNegated_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotStoreStaticTestContextAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotStoreStaticTestContextAnalyzerTests.cs index 5cb352dbce..f0c3590176 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotStoreStaticTestContextAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotStoreStaticTestContextAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class DoNotStoreStaticTestContextAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class DoNotStoreStaticTestContextAnalyzerTests { + [TestMethod] public async Task WhenAssemblyInitializeOrClassInitialize_Diagnostic() { string code = """ @@ -87,6 +88,7 @@ public static ValueTask ClassInit(TestContext tc) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenOtherTestContext_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseShadowingAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseShadowingAnalyzerTests.cs index a4196dc747..8b471471e3 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseShadowingAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseShadowingAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class DoNotUseShadowingAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class DoNotUseShadowingAnalyzerTests { + [TestMethod] public async Task WhenTestClassHaveShadowingMethod_Diagnostic() { string code = """ @@ -29,6 +30,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_ButDifferentParameters_NoDiagnostic() { string code = """ @@ -48,6 +50,7 @@ public void Method() { } await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_ButBothArePrivate_NoDiagnostic() { string code = """ @@ -67,6 +70,7 @@ private void Method() { } await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_ButBaseMethodIsPrivate_NoDiagnostic() { string code = """ @@ -86,6 +90,7 @@ public void Method() { } await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_ButDerivedMethodIsPrivate_Diagnostic() { string code = """ @@ -105,6 +110,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_ButDerivedMethodIsProtected_AndBaseMethodIsInternal_Diagnostic() { string code = """ @@ -124,6 +130,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveSamePropertyAsBaseClassMethod__ButBasePropertyIsProtected_AndDerivedPropertyIsInternal_Diagnostic() { string code = """ @@ -143,6 +150,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveSamePropertyAsBaseClassMethod_ButBothArePrivate_NoDiagnostic() { string code = """ @@ -162,6 +170,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveSamePropertyAsBaseClassMethod_ButBasePropertyIsPrivate_NoDiagnostic() { string code = """ @@ -181,6 +190,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveSamePropertyAsBaseClassMethod_ButDerivedPropertyIsPrivate_Diagnostic() { string code = """ @@ -200,6 +210,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_ButOneIsGeneric_NoDiagnostic() { string code = """ @@ -231,6 +242,7 @@ public class SomeType await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveSameMethodAsBaseClassMethod_WithParameters_Diagnostic() { string code = """ @@ -250,6 +262,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveOverrideProperty_NoDiagnostic() { string code = """ @@ -269,6 +282,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassOverrideMethodFromBaseClass_NoDiagnostic() { string code = """ @@ -288,6 +302,7 @@ public override void Method() { } await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveShadowingProperty_Diagnostic() { string code = """ @@ -307,6 +322,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveShadowingMethod_WithoutNewModifier_Diagnostic() { string code = """ @@ -326,6 +342,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassHaveShadowingProperty_WithoutNewModifier_Diagnostic() { string code = """ @@ -345,6 +362,7 @@ public class DerivedClass : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassAndBaseClassHaveStaticCtor_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseSystemDescriptionAttributeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseSystemDescriptionAttributeAnalyzerTests.cs index de809f42f0..e5c2dd3cd7 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseSystemDescriptionAttributeAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DoNotUseSystemDescriptionAttributeAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class DoNotUseSystemDescriptionAttributeAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class DoNotUseSystemDescriptionAttributeAnalyzerTests { + [TestMethod] public async Task WhenTestMethodHasMicrosoftDescriptionAttribute_NoDiagnostic() { string code = """ @@ -29,6 +30,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestMethodHasSystemDescriptionAttribute_Diagnostic() { string code = """ @@ -48,6 +50,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenMethodWithoutTestMethodAttribute_HasSystemDescriptionAttribute_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs index b15c8c2c9d..b572150cc1 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class DynamicDataShouldBeValidAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class DynamicDataShouldBeValidAnalyzerTests { + [TestMethod] public async Task ValidUsages_NoDiagnostic() { string code = """ @@ -290,6 +291,7 @@ public class SomeClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDataSourceMemberDoesNotExist_Diagnostic() { string code = """ @@ -364,6 +366,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberNotFoundRule).WithLocation(7).WithArguments("SomeClass", "MemberNotFound")); } + [TestMethod] public async Task WhenAppliedToNonTestMethod_Diagnostic() { string code = """ @@ -406,6 +409,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.NotTestMethodRule).WithLocation(3)); } + [TestMethod] public async Task WhenDataSourceMemberFoundMultipleTimes_Diagnostic() { string code = """ @@ -458,6 +462,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.FoundTooManyMembersRule).WithLocation(3).WithArguments("SomeClass", "GetSomeData")); } + [TestMethod] public async Task WhenMemberKindIsMixedUp_Diagnostic() { string code = """ @@ -538,6 +543,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.SourceTypePropertyRule).WithLocation(7).WithArguments("SomeClass", "SomeData")); } + [TestMethod] public async Task WhenDataSourceReturnTypeIsInvalid_Diagnostic() { string code = """ @@ -678,6 +684,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(15).WithArguments("SomeClass", "GetSomeDataArray")); } + [TestMethod] public async Task MemberIsNotStatic_Diagnostic() { string code = """ @@ -711,6 +718,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.DataMemberSignatureRule).WithLocation(1).WithArguments("MyTestClass", "GetData")); } + [TestMethod] public async Task MemberIsNotPublic_NoDiagnostic() { string code = """ @@ -741,6 +749,7 @@ public void TestMethod2(object[] o) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task MethodHasParameters_Diagnostic() { string code = """ @@ -774,6 +783,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.DataMemberSignatureRule).WithLocation(1).WithArguments("MyTestClass", "GetData2")); } + [TestMethod] public async Task MethodIsGeneric_Diagnostic() { string code = """ @@ -799,6 +809,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.DataMemberSignatureRule).WithLocation(0).WithArguments("MyTestClass", "GetData")); } + [TestMethod] public async Task WhenDisplayMemberIsValid_NoDiagnostic() { string code = """ @@ -873,6 +884,7 @@ public class SomeClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDisplayMemberIsNotFound_Diagnostic() { string code = """ @@ -924,6 +936,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberNotFoundRule).WithLocation(3).WithArguments("SomeClass", "MemberNotFound")); } + [TestMethod] public async Task WhenDisplayMemberIsNotPublic_Diagnostic() { string code = """ @@ -979,6 +992,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.DisplayMethodSignatureRule).WithLocation(3).WithArguments("SomeClass", "GetSomeDisplayName")); } + [TestMethod] public async Task WhenDisplayMemberIsNotStatic_Diagnostic() { string code = """ @@ -1034,6 +1048,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.DisplayMethodSignatureRule).WithLocation(3).WithArguments("SomeClass", "GetSomeDisplayName")); } + [TestMethod] public async Task WhenDisplayMemberDoesNotReturnString_Diagnostic() { string code = """ @@ -1089,6 +1104,7 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.DisplayMethodSignatureRule).WithLocation(3).WithArguments("SomeClass", "GetSomeDisplayName")); } + [TestMethod] public async Task WhenDisplayMemberInvalidParameters_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj b/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj index b9dbd809a1..48717386f5 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj @@ -3,9 +3,9 @@ net6.0 false + true true true - true diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/NonNullableReferenceNotInitializedSuppressorTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/NonNullableReferenceNotInitializedSuppressorTests.cs index 12c094c2c4..32cff434a9 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/NonNullableReferenceNotInitializedSuppressorTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/NonNullableReferenceNotInitializedSuppressorTests.cs @@ -13,9 +13,10 @@ namespace MSTest.Analyzers.UnitTests; -[TestGroup] -public sealed class NonNullableReferenceNotInitializedSuppressorTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class NonNullableReferenceNotInitializedSuppressorTests { + [TestMethod] public async Task TestContextPropertyOnTestClass_DiagnosticIsSuppressed() { string code = @" @@ -43,6 +44,7 @@ public class SomeClass }.RunAsync(); } + [TestMethod] public async Task TestContextPropertyOnNonTestClass_DiagnosticIsNotSuppressed() { string code = @" diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferAssertFailOverAlwaysFalseConditionsAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferAssertFailOverAlwaysFalseConditionsAnalyzerTests.cs index b2c05361d5..69f3b533a6 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferAssertFailOverAlwaysFalseConditionsAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferAssertFailOverAlwaysFalseConditionsAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class PreferAssertFailOverAlwaysFalseConditionsAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class PreferAssertFailOverAlwaysFalseConditionsAnalyzerTests { + [TestMethod] public async Task WhenIsNullAssertion_ValueParameterIsNullable_NoDiagnostic() { string code = """ @@ -30,6 +31,7 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenIsNullAssertion_ValueParameterIsNotNullable_Diagnostic() { string code = """ @@ -64,6 +66,7 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenIsNullAssertion_ValueParameterAsPropertySymbolIsNotNullable_Diagnostic() { string code = """ @@ -99,6 +102,7 @@ public void Test() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenIsNullAssertion_ValueParameterAsPropertySymbolIsNullable_NoDiagnostic() { string code = """ @@ -120,6 +124,7 @@ public void Test() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenIsNullAssertion_ValueParameterAsReferenceObjectIsNotNullable_Diagnostic() { string code = """ @@ -163,6 +168,7 @@ public class ObjectClass await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenIsNullAssertion_ValueParameterAsReferenceObjectIsNotNullable_WithoutEnableNullable_NoDiagnostic() { string code = """ @@ -187,6 +193,7 @@ public class ObjectClass await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenIsNullAssertion_ValueParameterAsReferenceObjectIsNullable_NoDiagnostic() { string code = """ @@ -213,6 +220,7 @@ public class ObjectClass await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedTrue_NoDiagnostic() { string code = """ @@ -232,6 +240,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedTrue_WithMessage_NoDiagnostic() { string code = """ @@ -251,6 +260,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedTrue_WithMessageFirst_NoDiagnostic() { string code = """ @@ -270,6 +280,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedFalse_Diagnostic() { string code = """ @@ -302,6 +313,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedFalse_WithMessage_Diagnostic() { string code = """ @@ -333,6 +345,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedFalse_WithMessageAndArgsAsParams_Diagnostic() { string code = """ @@ -370,6 +383,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedFalse_WithMessageFirst_Diagnostic() { string code = """ @@ -401,6 +415,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedUnknown_NoDiagnostic() { string code = """ @@ -422,6 +437,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedUnknown_WithMessage_NoDiagnostic() { string code = """ @@ -443,6 +459,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedUnknown_WithMessageFirst_NoDiagnostic() { string code = """ @@ -464,6 +481,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedTrue_Diagnostic() { string code = """ @@ -496,6 +514,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedTrue_WithMessage_Diagnostic() { string code = """ @@ -528,6 +547,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedTrue_WithMessageFirst_Diagnostic() { string code = """ @@ -560,6 +580,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedFalse_NoDiagnostic() { string code = """ @@ -579,6 +600,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedFalse_WithMessage_NoDiagnostic() { string code = """ @@ -598,6 +620,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedFalse_WithMessageFirst_NoDiagnostic() { string code = """ @@ -617,6 +640,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedUnknown_NoDiagnostic() { string code = """ @@ -638,6 +662,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedUnknown_WithMessage_NoDiagnostic() { string code = """ @@ -659,6 +684,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedUnknown_WithMessageFirst_NoDiagnostic() { string code = """ @@ -680,6 +706,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsNotNullIsPassedNull_Diagnostic() { string code = """ @@ -712,6 +739,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertIsNotNullIsPassedNull_WithMessage_Diagnostic() { string code = """ @@ -744,6 +772,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertIsNotNullIsPassedNull_WithMessageFirst_Diagnostic() { string code = """ @@ -776,6 +805,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertIsNotNullIsPassedUnknown_NoDiagnostic() { string code = """ @@ -797,6 +827,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsNotNullIsPassedUnknown_WithMessage_NoDiagnostic() { string code = """ @@ -818,6 +849,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsNotNullIsPassedUnknown_WithMessageFirst_NoDiagnostic() { string code = """ @@ -839,6 +871,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedEqual_NoDiagnostic() { string code = """ @@ -858,6 +891,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedEqual_WithMessage_NoDiagnostic() { string code = """ @@ -877,6 +911,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedEqual_WithMessageFirst_NoDiagnostic() { string code = """ @@ -896,6 +931,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedEqual_WithMessageSecond_NoDiagnostic() { string code = """ @@ -915,6 +951,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedNonEqual_Diagnostic() { string code = """ @@ -947,6 +984,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedNonEqual_WithMessage_Diagnostic() { string code = """ @@ -979,6 +1017,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedNonEqual_WithMessageFirst_Diagnostic() { string code = """ @@ -1011,6 +1050,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedNonEqual_WithMessageSecond_Diagnostic() { string code = """ @@ -1043,6 +1083,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedUnknown_NoDiagnostic() { string code = """ @@ -1064,6 +1105,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedUnknown_WithMessage_NoDiagnostic() { string code = """ @@ -1085,6 +1127,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedUnknown_WithMessageFirst_NoDiagnostic() { string code = """ @@ -1106,6 +1149,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedUnknown_WithMessageSecond_NoDiagnostic() { string code = """ @@ -1127,6 +1171,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedEqual_Diagnostic() { string code = """ @@ -1159,6 +1204,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedEqual_WithMessage_Diagnostic() { string code = """ @@ -1191,6 +1237,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedEqual_WithMessageFirst_Diagnostic() { string code = """ @@ -1223,6 +1270,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedEqual_WithMessageSecond_Diagnostic() { string code = """ @@ -1255,6 +1303,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedNonEqual_NoDiagnostic() { string code = """ @@ -1274,6 +1323,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedNonEqual_WithMessage_NoDiagnostic() { string code = """ @@ -1293,6 +1343,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedNonEqual_WithMessageFirst_NoDiagnostic() { string code = """ @@ -1312,6 +1363,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedNonEqual_WithMessageSecond_NoDiagnostic() { string code = """ @@ -1331,6 +1383,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedUnknown_NoDiagnostic() { string code = """ @@ -1352,6 +1405,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedUnknown_WithMessage_NoDiagnostic() { string code = """ @@ -1373,6 +1427,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedUnknown_WithMessageFirst_NoDiagnostic() { string code = """ @@ -1394,6 +1449,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedUnknown_WithMessageSecond_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferConstructorOverTestInitializeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferConstructorOverTestInitializeAnalyzerTests.cs index 4bead3d728..f6335eedb7 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferConstructorOverTestInitializeAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferConstructorOverTestInitializeAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class PreferConstructorOverTestInitializeAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class PreferConstructorOverTestInitializeAnalyzerTests { + [TestMethod] public async Task WhenTestClassHasCtor_NoDiagnostic() { string code = """ @@ -27,6 +28,7 @@ public MyTestClass() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenTestClassHasTestInitialize_Diagnostic() { string code = """ @@ -56,6 +58,7 @@ public MyTestClass() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHasTestInitializeAsync_NoDiagnostic() { string code = """ @@ -76,6 +79,7 @@ public Task MyTestInit() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenTestClassHasTestInitializeAndCtor_Diagnostic() { string code = """ @@ -110,6 +114,7 @@ public MyTestClass() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHasTestInitializeAndCtorWithBody_Diagnostic() { string code = """ @@ -150,6 +155,7 @@ public MyTestClass() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHasTestInitializeAndCtorWithBothHavingBody_Diagnostic() { string code = """ @@ -196,6 +202,7 @@ public MyTestClass() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHasTestInitializeAndTwoCtor_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferDisposeOverTestCleanupAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferDisposeOverTestCleanupAnalyzerTests.cs index 4c93ee48f4..65bb4d83c5 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferDisposeOverTestCleanupAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferDisposeOverTestCleanupAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class PreferDisposeOverTestCleanupAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class PreferDisposeOverTestCleanupAnalyzerTests { + [TestMethod] public async Task WhenTestClassHasDispose_NoDiagnostic() { string code = """ @@ -28,6 +29,7 @@ public void Dispose() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenTestClassHasDisposeAsync_NoDiagnostic() { string code = """ @@ -48,6 +50,7 @@ public ValueTask DisposeAsync() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenTestClassHasTestCleanup_Diagnostic() { string code = """ @@ -79,6 +82,7 @@ public void Dispose() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHasTestCleanup_WithAnotherBaseClass_Diagnostic() { string code = """ @@ -113,6 +117,7 @@ public void Dispose() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHasTestCleanup_AndHasDispose_Diagnostic() { string code = """ @@ -151,6 +156,7 @@ public void Dispose() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHasTestCleanup_AndHasDisposeInAnotherPartial_Diagnostic() { // This scenario is currently broken. The test is to document the current behavior @@ -201,6 +207,7 @@ public partial class MyTestClass : IDisposable await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHasTestCleanupTask_Diagnostic() { string code = """ @@ -223,6 +230,7 @@ public class MyTestClass await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenTestClassHasTestCleanupValueTask_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestCleanupOverDisposeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestCleanupOverDisposeAnalyzerTests.cs index 278c0a417f..6681623645 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestCleanupOverDisposeAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestCleanupOverDisposeAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class PreferTestCleanupOverDisposeAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class PreferTestCleanupOverDisposeAnalyzerTests { + [TestMethod] public async Task WhenTestClassHasDispose_Diagnostic() { string code = """ @@ -49,6 +50,7 @@ public interface IMyInterface { } await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHasDisposeAsync_Diagnostic() { string code = """ @@ -84,6 +86,7 @@ public ValueTask TestCleanup() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHasTestCleanup_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestInitializeOverConstructorAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestInitializeOverConstructorAnalyzerTests.cs index 2b033a31e9..ed62792b41 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestInitializeOverConstructorAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestInitializeOverConstructorAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class PreferTestInitializeOverConstructorAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class PreferTestInitializeOverConstructorAnalyzerTests { + [TestMethod] public async Task WhenTestClassHasCtor_Diagnostic() { string code = """ @@ -39,6 +40,7 @@ public void TestInitialize() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHas_TwoCtorandExsitesTestInitialize_Diagnostic() { string code = """ @@ -97,6 +99,7 @@ public MyTestClass(int i) await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClass_WithLocalTestInitializeAttribute_Diagnostic() { string code = """ @@ -151,6 +154,7 @@ public void TestInitialize() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestClassHasImplicitCtor_NoDiagnostic() { string code = """ @@ -165,6 +169,7 @@ public class MyTestClass await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenTestClassHasParameterizedCtor_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs index 040e4af637..f5a6c5807a 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs @@ -1,15 +1,17 @@ // 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.Diagnostics; +using System.Reflection; using Microsoft.Testing.Extensions; -using Microsoft.Testing.Internal.Framework.Configurations; + +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] +[assembly: ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] // DebuggerUtility.AttachVSToCurrentProcess(); ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new TestFrameworkConfiguration(Debugger.IsAttached ? 1 : Environment.ProcessorCount), new MSTest.Analyzers.UnitTests.SourceGeneratedTestNodesBuilder()); +builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]); #if ENABLE_CODECOVERAGE builder.AddCodeCoverageProvider(); #endif diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/Properties/launchSettings.json b/test/UnitTests/MSTest.Analyzers.UnitTests/Properties/launchSettings.json index d7b9c2736a..485ee85ee1 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/Properties/launchSettings.json +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "MSTest.Analyzers.UnitTests": { "commandName": "Project", - "commandLineArgs": "--treenode-filter /*/*/*/**" + "commandLineArgs": "" } } } diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/PublicMethodShouldBeTestMethodAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/PublicMethodShouldBeTestMethodAnalyzerTests.cs index da6fa23d27..2a7548dbdd 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/PublicMethodShouldBeTestMethodAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/PublicMethodShouldBeTestMethodAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class PublicMethodShouldBeTestMethodAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class PublicMethodShouldBeTestMethodAnalyzerTests { + [TestMethod] public async Task WhenMethodIsPrivate_NoDiagnostic() { string code = """ @@ -27,6 +28,7 @@ private void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenMethodIsPublicButWithInvalidTestMethodSignature_NoDiagnostic() { string code = """ @@ -44,6 +46,7 @@ public static void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenMethodIsPublicAndMarkedAsTestMethod_NoDiagnostic() { string code = """ @@ -62,6 +65,7 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenMethodIsPrivateButNotInsideTestClass_NoDiagnostic() { string code = """ @@ -78,6 +82,7 @@ private void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenMethodIsPublicAndMarkedAsDerivedTestMethodAttribute_NoDiagnostic() { string code = """ @@ -99,6 +104,7 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenMethodIsPublicAndNotMarkedAsTestMethodWithInheritanceFromBaseTestClass_NoDiagnostic() { string code = """ @@ -120,6 +126,7 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenMethodIsPrivateAndNotMarkedAsTestMethodWithInheritedTestClassAttribute_NoDiagnostic() { string code = """ @@ -141,6 +148,7 @@ private void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenMethodIsPublicAndNotMarkedAsTestMethod_Diagnostic() { string code = """ @@ -171,6 +179,7 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenMethodIsPublicAndNotMarkedAsTestMethodWithInheritedTestClassAttribute_Diagnostic() { string code = """ @@ -208,6 +217,7 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenMethodIsPublicAndMarkedAsTestInitialize_NoDiagnostic() { string code = """ @@ -225,6 +235,7 @@ public void TestInitialize() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenMethodIsPublicAndMarkedAsTestCleanup_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/PublicTypeShouldBeTestClassAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/PublicTypeShouldBeTestClassAnalyzerTests.cs index f9d13370ab..5aa41648b9 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/PublicTypeShouldBeTestClassAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/PublicTypeShouldBeTestClassAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.UnitTests; -[TestGroup] -public sealed class PublicTypeShouldBeTestClassAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class PublicTypeShouldBeTestClassAnalyzerTests { + [TestMethod] public async Task WhenClassIsPublicAndNotTestClass_Diagnostic() { string code = """ @@ -34,6 +35,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassIsPublicAndNotTestClassAndHaveAnotherAttribute_Diagnostic() { string code = """ @@ -60,6 +62,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassIsPublicAndNotClass_NoDiagnostic() { string code = """ @@ -79,6 +82,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenClassIsPublicAndAbstract_NoDiagnostic() { string code = """ @@ -94,6 +98,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenClassIsPublicAndStatic_NoDiagnostic() { string code = """ @@ -109,6 +114,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenTypeIsNotPublicAndNotTestClass_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/ReviewAlwaysTrueAssertConditionAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/ReviewAlwaysTrueAssertConditionAnalyzerTests.cs index 3116986593..a4d68420e0 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/ReviewAlwaysTrueAssertConditionAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/ReviewAlwaysTrueAssertConditionAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class ReviewAlwaysTrueAssertConditionAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class ReviewAlwaysTrueAssertConditionAnalyzerTests { + [TestMethod] public async Task WhenIsNotNullAssertion_ValueParameterIsNotNullable_NoDiagnostic() { string code = """ @@ -30,6 +31,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenIsNotNullAssertion_ValueParameterIsNotNullable_Diagnostic() { string code = """ @@ -50,6 +52,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenIsNotNullAssertion_ValueParameterAsPropertySymbolIsNotNullable_Diagnostic() { string code = """ @@ -71,6 +74,7 @@ public void Test() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenIsNotNullAssertion_ValueParameterAsPropertySymbolIsNullable_NoDiagnostic() { string code = """ @@ -92,6 +96,7 @@ public void Test() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenIsNotNullAssertion_ValueParameterAsReferenceObjectIsNotNullable_Diagnostic() { string code = """ @@ -117,6 +122,7 @@ public class ObjectClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenIsNotNullAssertion_ValueParameterAsReferenceObjectIsNotNullable_WithoutEnableNullable_NoDiagnostic() { string code = """ @@ -141,6 +147,7 @@ public class ObjectClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenIsNotNullAssertion_ValueParameterAsReferenceObjectIsNotNullable_NoDiagnostic() { string code = """ @@ -167,6 +174,7 @@ public class ObjectClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedTrue_NoDiagnostic() { string code = """ @@ -186,6 +194,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedTrue_WithMessage_NoDiagnostic() { string code = """ @@ -205,6 +214,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedTrue_WithMessageFirst_NoDiagnostic() { string code = """ @@ -224,6 +234,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedFalse_Diagnostic() { string code = """ @@ -243,6 +254,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedFalse_WithMessage_Diagnostic() { string code = """ @@ -262,6 +274,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedFalse_WithMessageFirst_Diagnostic() { string code = """ @@ -281,6 +294,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedUnknown_NoDiagnostic() { string code = """ @@ -302,6 +316,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedUnknown_WithMessage_NoDiagnostic() { string code = """ @@ -323,6 +338,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsFalseIsPassedUnknown_WithMessageFirst_NoDiagnostic() { string code = """ @@ -344,6 +360,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedTrue_Diagnostic() { string code = """ @@ -363,6 +380,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedTrue_WithMessage_Diagnostic() { string code = """ @@ -382,6 +400,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedTrue_WithMessageFirst_Diagnostic() { string code = """ @@ -401,6 +420,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedFalse_NoDiagnostic() { string code = """ @@ -420,6 +440,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedFalse_WithMessage_NoDiagnostic() { string code = """ @@ -439,6 +460,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedFalse_WithMessageFirst_NoDiagnostic() { string code = """ @@ -458,6 +480,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedUnknown_NoDiagnostic() { string code = """ @@ -479,6 +502,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedUnknown_WithMessage_NoDiagnostic() { string code = """ @@ -500,6 +524,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsTrueIsPassedUnknown_WithMessageFirst_NoDiagnostic() { string code = """ @@ -521,6 +546,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsNullIsPassedNull_Diagnostic() { string code = """ @@ -540,6 +566,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsNullIsPassedNull_WithMessage_Diagnostic() { string code = """ @@ -559,6 +586,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsNullIsPassedNull_WithMessageFirst_Diagnostic() { string code = """ @@ -578,6 +606,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsNullIsPassedUnknown_NoDiagnostic() { string code = """ @@ -599,6 +628,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsNullIsPassedUnknown_WithMessage_NoDiagnostic() { string code = """ @@ -620,6 +650,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertIsNullIsPassedUnknown_WithMessageFirst_NoDiagnostic() { string code = """ @@ -641,6 +672,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedEqual_NoDiagnostic() { string code = """ @@ -660,6 +692,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedEqual_WithMessage_NoDiagnostic() { string code = """ @@ -679,6 +712,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedEqual_WithMessageFirst_NoDiagnostic() { string code = """ @@ -698,6 +732,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedEqual_WithMessageSecond_NoDiagnostic() { string code = """ @@ -717,6 +752,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedNonEqual_Diagnostic() { string code = """ @@ -736,6 +772,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedNonEqual_WithMessage_Diagnostic() { string code = """ @@ -755,6 +792,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedNonEqual_WithMessageFirst_Diagnostic() { string code = """ @@ -774,6 +812,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedNonEqual_WithMessageSecond_Diagnostic() { string code = """ @@ -793,6 +832,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedUnknown_NoDiagnostic() { string code = """ @@ -814,6 +854,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedUnknown_WithMessage_NoDiagnostic() { string code = """ @@ -835,6 +876,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedUnknown_WithMessageFirst_NoDiagnostic() { string code = """ @@ -856,6 +898,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreNotEqualIsPassedUnknown_WithMessageSecond_NoDiagnostic() { string code = """ @@ -877,6 +920,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedEqual_Diagnostic() { string code = """ @@ -896,6 +940,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedEqual_WithMessage_Diagnostic() { string code = """ @@ -915,6 +960,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedEqual_WithMessageFirst_Diagnostic() { string code = """ @@ -934,6 +980,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedEqual_WithMessageSecond_Diagnostic() { string code = """ @@ -953,6 +1000,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedNonEqual_NoDiagnostic() { string code = """ @@ -972,6 +1020,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedNonEqual_WithMessage_NoDiagnostic() { string code = """ @@ -991,6 +1040,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedNonEqual_WithMessageFirst_NoDiagnostic() { string code = """ @@ -1010,6 +1060,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedNonEqual_WithMessageSecond_NoDiagnostic() { string code = """ @@ -1029,6 +1080,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedUnknown_NoDiagnostic() { string code = """ @@ -1050,6 +1102,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedUnknown_WithMessage_NoDiagnostic() { string code = """ @@ -1071,6 +1124,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedUnknown_WithMessageFirst_NoDiagnostic() { string code = """ @@ -1092,6 +1146,7 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenAssertAreEqualIsPassedUnknown_WithMessageSecond_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldBeValidAnalyzerTests.cs index 6e10dd3640..b4b74c293a 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldBeValidAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class TestClassShouldBeValidAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class TestClassShouldBeValidAnalyzerTests { + [TestMethod] public async Task WhenClassIsPublicAndTestClass_NoDiagnostic() { string code = """ @@ -24,6 +25,7 @@ public class MyTestClass await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenClassIsInternalAndTestClass_Diagnostic() { string code = """ @@ -52,8 +54,9 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } - [Arguments("private")] - [Arguments("internal")] + [DataRow("private")] + [DataRow("internal")] + [TestMethod] public async Task WhenClassIsInnerAndNotPublicTestClass_Diagnostic(string accessibility) { string code = $$""" @@ -88,6 +91,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassIsInternalAndNotTestClass_NoDiagnostic() { string code = """ @@ -101,6 +105,7 @@ internal class MyTestClass await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenClassIsPublicAndTestClassAsInnerOfInternalClass_Diagnostic() { string code = """ @@ -122,6 +127,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments("MyTestClass")); } + [TestMethod] public async Task WhenClassIsGeneric_NoDiagnostic() { string code = """ @@ -136,6 +142,7 @@ public class MyTestClass await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenDiscoverInternalsAndTypeIsInternal_NoDiagnostic() { string code = """ @@ -152,6 +159,7 @@ internal class MyTestClass await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenDiscoverInternalsAndTypeIsPrivate_Diagnostic() { string code = """ @@ -190,6 +198,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassIsStaticAndEmpty_NoDiagnostic() { string code = """ @@ -204,6 +213,7 @@ public static class MyTestClass await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenClassIsStaticAndContainsAssemblyInitialize_NoDiagnostic() { string code = """ @@ -222,6 +232,7 @@ public static void AssemblyInit(TestContext context) await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenClassIsStaticAndContainsAssemblyCleanup_NoDiagnostic() { string code = """ @@ -240,6 +251,7 @@ public static void AssemblyCleanup() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenClassIsStaticAndContainsClassInitialize_Diagnostic() { string code = """ @@ -276,6 +288,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassIsStaticAndContainsClassCleanup_Diagnostic() { string code = """ @@ -310,6 +323,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassIsStaticAndContainsTestInitialize_Diagnostic() { string code = """ @@ -345,6 +359,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassIsStaticAndContainsTestCleanup_Diagnostic() { string code = """ @@ -380,6 +395,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenClassIsStaticAndContainsTestMethod_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldHaveTestMethodAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldHaveTestMethodAnalyzerTests.cs index 495665896d..46bff4564b 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldHaveTestMethodAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldHaveTestMethodAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class TestClassShouldHaveTestMethodAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class TestClassShouldHaveTestMethodAnalyzerTests { + [TestMethod] public async Task WhenTestClassHasTestMethod_NoDiagnostic() { string code = """ @@ -28,6 +29,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenStaticTestClassWithAssemblyCleanup_DoesNotHaveTestMethod_NoDiagnostic() { string code = """ @@ -46,6 +48,7 @@ public static void AssemblyCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenStaticTestClassWithAssemblyInitialization_DoesNotHaveTestMethod_NoDiagnostic() { string code = """ @@ -64,6 +67,7 @@ public static void AssemblyInitialize(TestContext context) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassDoesNotHaveTestMethod_Diagnostic() { string code = """ @@ -82,6 +86,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments("MyTestClass")); } + [TestMethod] public async Task WhenStaticTestClassWithoutAssemblyAttributes_DoesNotHaveTestMethod_Diagnostic() { string code = """ @@ -99,6 +104,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments("MyTestClass")); } + [TestMethod] public async Task WhenTestClassWithoutAssemblyAttributesAndTestMethod_InheritsFromAbstractClassHasTestMethod_NoDiagnostic() { string code = """ @@ -118,6 +124,7 @@ public class Derived : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassWithoutAssemblyAttributesAndTestMethod_InheritsFromClassHasTestMethod_NoDiagnostic() { string code = """ @@ -137,6 +144,7 @@ public class Derived : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassWithoutAssemblyAttributesAndTestMethod_InheritsFromTestClassHasTestMethod_NoDiagnostic() { string code = """ @@ -157,6 +165,7 @@ public class Derived : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassWithoutAssemblyAttributesAndTestMethod_InheritsFromAbstractTestClassHasTestMethod_NoDiagnostic() { string code = """ @@ -177,6 +186,7 @@ public class Derived : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassWithoutAssemblyAttributesAndTestMethod_InheritsFromBaseBaseClassHasTestMethod_NoDiagnostic() { string code = """ @@ -200,6 +210,7 @@ public class Derived : BaseClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestClassWithoutAssemblyAttributesAndTestMethod_InheritsFromClassDoesNotHaveTestMethod_Diagnostic() { string code = """ @@ -221,6 +232,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments("Derived")); } + [TestMethod] public async Task WhenTestClassWithoutAssemblyAttributesAndTestMethod_InheritsFromClassHasAssemblyInitialize_Diagnostic() { string code = """ @@ -246,6 +258,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments("Derived")); } + [TestMethod] public async Task WhenTestClassWithoutAssemblyAttributesAndTestMethod_InheritsFromBaseBaseClassHasAssemblyCleanup_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestCleanupShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestCleanupShouldBeValidAnalyzerTests.cs index b30e073f5a..cdfea41d81 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestCleanupShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestCleanupShouldBeValidAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class TestCleanupShouldBeValidAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class TestCleanupShouldBeValidAnalyzerTests { + [TestMethod] public async Task WhenTestCleanupIsPublic_NoDiagnostic() { string code = """ @@ -28,6 +29,7 @@ public void TestCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestCleanupIsPublic_InsideInternalClassWithDiscoverInternals_NoDiagnostic() { string code = """ @@ -48,6 +50,7 @@ public void TestCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestCleanupIsInternal_InsidePublicClassWithDiscoverInternals_Diagnostic() { string code = """ @@ -88,10 +91,11 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } - [Arguments("protected")] - [Arguments("internal")] - [Arguments("internal protected")] - [Arguments("private")] + [DataRow("protected")] + [DataRow("internal")] + [DataRow("internal protected")] + [DataRow("private")] + [TestMethod] public async Task WhenTestCleanupIsNotPublic_Diagnostic(string accessibility) { string code = $$""" @@ -128,6 +132,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestCleanupIsNotOrdinary_Diagnostic() { string code = """ @@ -149,6 +154,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenTestCleanupIsAbstract_Diagnostic() { string code = """ @@ -181,6 +187,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestCleanupIsGeneric_Diagnostic() { string code = """ @@ -215,6 +222,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestCleanupIsStatic_Diagnostic() { string code = """ @@ -249,6 +257,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestCleanupHasParameters_Diagnostic() { string code = """ @@ -283,6 +292,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestCleanupReturnTypeIsNotValid_Diagnostic() { string code = """ @@ -358,6 +368,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestCleanupReturnTypeIsValid_NoDiagnostic() { string code = """ @@ -389,6 +400,7 @@ public ValueTask TestCleanup2() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestCleanupIsAsyncVoid_Diagnostic() { string code = """ @@ -427,6 +439,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenMultipleViolations_TheyAllGetFixed() { string code = """ @@ -465,6 +478,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestCleanupIsNotOnClass_Diagnostic() { string code = """ @@ -482,6 +496,7 @@ public struct MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestCleanupIsOnSealedClassNotMarkedWithTestClass_Diagnostic() { string code = """ @@ -499,6 +514,7 @@ public sealed class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestCleanupIsOnNonSealedClassNotMarkedWithTestClass_NoDiagnostic() { string code = """ @@ -516,6 +532,7 @@ public void TestCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestCleanupIsOnGenericClass_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs index 141b0f0202..e2965c8523 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs @@ -7,25 +7,26 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class TestContextShouldBeValidAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class TestContextShouldBeValidAnalyzerTests { - [Arguments("TestContext", "private")] - [Arguments("TestContext", "public")] - [Arguments("TestContext", "internal")] - [Arguments("TestContext", "protected")] - [Arguments("testcontext", "private")] - [Arguments("testcontext", "public")] - [Arguments("testcontext", "internal")] - [Arguments("testcontext", "protected")] - [Arguments("TESTCONTEXT", "private")] - [Arguments("TESTCONTEXT", "public")] - [Arguments("TESTCONTEXT", "internal")] - [Arguments("TESTCONTEXT", "protected")] - [Arguments("TeStCoNtExT", "private")] - [Arguments("TeStCoNtExT", "public")] - [Arguments("TeStCoNtExT", "internal")] - [Arguments("TeStCoNtExT", "protected")] + [DataRow("TestContext", "private")] + [DataRow("TestContext", "public")] + [DataRow("TestContext", "internal")] + [DataRow("TestContext", "protected")] + [DataRow("testcontext", "private")] + [DataRow("testcontext", "public")] + [DataRow("testcontext", "internal")] + [DataRow("testcontext", "protected")] + [DataRow("TESTCONTEXT", "private")] + [DataRow("TESTCONTEXT", "public")] + [DataRow("TESTCONTEXT", "internal")] + [DataRow("TESTCONTEXT", "protected")] + [DataRow("TeStCoNtExT", "private")] + [DataRow("TeStCoNtExT", "public")] + [DataRow("TeStCoNtExT", "internal")] + [DataRow("TeStCoNtExT", "protected")] + [TestMethod] public async Task WhenTestContextCaseInsensitiveIsField_Diagnostic(string fieldName, string accessibility) { string code = $$""" @@ -52,22 +53,23 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } - [Arguments("TestContext", "private")] - [Arguments("TestContext", "public")] - [Arguments("TestContext", "internal")] - [Arguments("TestContext", "protected")] - [Arguments("testcontext", "private")] - [Arguments("testcontext", "public")] - [Arguments("testcontext", "internal")] - [Arguments("testcontext", "protected")] - [Arguments("TESTCONTEXT", "private")] - [Arguments("TESTCONTEXT", "public")] - [Arguments("TESTCONTEXT", "internal")] - [Arguments("TESTCONTEXT", "protected")] - [Arguments("TeStCoNtExT", "private")] - [Arguments("TeStCoNtExT", "public")] - [Arguments("TeStCoNtExT", "internal")] - [Arguments("TeStCoNtExT", "protected")] + [DataRow("TestContext", "private")] + [DataRow("TestContext", "public")] + [DataRow("TestContext", "internal")] + [DataRow("TestContext", "protected")] + [DataRow("testcontext", "private")] + [DataRow("testcontext", "public")] + [DataRow("testcontext", "internal")] + [DataRow("testcontext", "protected")] + [DataRow("TESTCONTEXT", "private")] + [DataRow("TESTCONTEXT", "public")] + [DataRow("TESTCONTEXT", "internal")] + [DataRow("TESTCONTEXT", "protected")] + [DataRow("TeStCoNtExT", "private")] + [DataRow("TeStCoNtExT", "public")] + [DataRow("TeStCoNtExT", "internal")] + [DataRow("TeStCoNtExT", "protected")] + [TestMethod] public async Task WhenTestContextCaseInsensitiveIsField_AssignedInConstructor_NoDiagnostic(string fieldName, string accessibility) { string code = $$""" @@ -88,14 +90,15 @@ public MyTestClass(TestContext testContext) await VerifyCS.VerifyCodeFixAsync(code, code); } - [Arguments("TestContext", "private")] - [Arguments("TestContext", "internal")] - [Arguments("testcontext", "private")] - [Arguments("testcontext", "internal")] - [Arguments("TESTCONTEXT", "private")] - [Arguments("TESTCONTEXT", "internal")] - [Arguments("TeStCoNtExT", "private")] - [Arguments("TeStCoNtExT", "internal")] + [DataRow("TestContext", "private")] + [DataRow("TestContext", "internal")] + [DataRow("testcontext", "private")] + [DataRow("testcontext", "internal")] + [DataRow("TESTCONTEXT", "private")] + [DataRow("TESTCONTEXT", "internal")] + [DataRow("TeStCoNtExT", "private")] + [DataRow("TeStCoNtExT", "internal")] + [TestMethod] public async Task WhenTestContextPropertyIsPrivateOrInternal_Diagnostic(string propertyName, string accessibility) { string code = $$""" @@ -123,14 +126,15 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } - [Arguments("TestContext", "private")] - [Arguments("TestContext", "internal")] - [Arguments("testcontext", "private")] - [Arguments("testcontext", "internal")] - [Arguments("TESTCONTEXT", "private")] - [Arguments("TESTCONTEXT", "internal")] - [Arguments("TeStCoNtExT", "private")] - [Arguments("TeStCoNtExT", "internal")] + [DataRow("TestContext", "private")] + [DataRow("TestContext", "internal")] + [DataRow("testcontext", "private")] + [DataRow("testcontext", "internal")] + [DataRow("TESTCONTEXT", "private")] + [DataRow("TESTCONTEXT", "internal")] + [DataRow("TeStCoNtExT", "private")] + [DataRow("TeStCoNtExT", "internal")] + [TestMethod] public async Task WhenTestContextPropertyIsPrivateOrInternal_AssignedInConstructor_NoDiagnostic(string propertyName, string accessibility) { string code = $$""" @@ -151,8 +155,9 @@ public MyTestClass(TestContext testContext) await VerifyCS.VerifyCodeFixAsync(code, code); } - [Arguments(true)] - [Arguments(false)] + [DataRow(true)] + [DataRow(false)] + [TestMethod] public async Task WhenTestContextPropertyIsValid_NoDiagnostic(bool discoverInternals) { string code = $$""" @@ -170,6 +175,7 @@ public class MyTestClass await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenDiscoverInternalsTestContextPropertyIsPrivate_Diagnostic() { string code = """ @@ -202,6 +208,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenDiscoverInternalsTestContextPropertyIsPrivate_AssignedInConstructor_NoDiagnostic() { string code = """ @@ -224,6 +231,7 @@ public MyTestClass(TestContext testContext) await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenDiscoverInternalsTestContextPropertyIsInternal_Diagnostic() { string code = """ @@ -253,6 +261,7 @@ public class MyTestClass await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenDiscoverInternalsTestContextPropertyIsInternal_AssignedInConstructor_NoDiagnostic() { string code = """ @@ -275,6 +284,7 @@ public MyTestClass(TestContext testContext) await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenTestContextPropertyIsStatic_Diagnostic() { string code = $$""" @@ -303,6 +313,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestContextPropertyIsReadonly_Diagnostic() { string code = $$""" @@ -331,6 +342,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestContextPropertyIsReadonly_AssignedInConstructor_NoDiagnostic() { string code = $$""" @@ -351,22 +363,23 @@ public MyTestClass(TestContext testContext) await VerifyCS.VerifyCodeFixAsync(code, code); } - [Arguments("TestContext", "private")] - [Arguments("TestContext", "public")] - [Arguments("TestContext", "internal")] - [Arguments("TestContext", "protected")] - [Arguments("testcontext", "private")] - [Arguments("testcontext", "public")] - [Arguments("testcontext", "internal")] - [Arguments("testcontext", "protected")] - [Arguments("TESTCONTEXT", "private")] - [Arguments("TESTCONTEXT", "public")] - [Arguments("TESTCONTEXT", "internal")] - [Arguments("TESTCONTEXT", "protected")] - [Arguments("TeStCoNtExT", "private")] - [Arguments("TeStCoNtExT", "public")] - [Arguments("TeStCoNtExT", "internal")] - [Arguments("TeStCoNtExT", "protected")] + [DataRow("TestContext", "private")] + [DataRow("TestContext", "public")] + [DataRow("TestContext", "internal")] + [DataRow("TestContext", "protected")] + [DataRow("testcontext", "private")] + [DataRow("testcontext", "public")] + [DataRow("testcontext", "internal")] + [DataRow("testcontext", "protected")] + [DataRow("TESTCONTEXT", "private")] + [DataRow("TESTCONTEXT", "public")] + [DataRow("TESTCONTEXT", "internal")] + [DataRow("TESTCONTEXT", "protected")] + [DataRow("TeStCoNtExT", "private")] + [DataRow("TeStCoNtExT", "public")] + [DataRow("TeStCoNtExT", "internal")] + [DataRow("TeStCoNtExT", "protected")] + [TestMethod] public async Task WhenTestContextIsFieldNotOnTestClass_NoDiagnostic(string fieldName, string accessibility) { string code = $$""" diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestInitializeShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestInitializeShouldBeValidAnalyzerTests.cs index e46e21c15e..d8eb9cbe5e 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestInitializeShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestInitializeShouldBeValidAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class TestInitializeShouldBeValidAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class TestInitializeShouldBeValidAnalyzerTests { + [TestMethod] public async Task WhenTestInitializeIsPublic_NoDiagnostic() { string code = """ @@ -28,6 +29,7 @@ public void TestInitialize() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestInitializeIsNotOrdinary_Diagnostic() { string code = """ @@ -49,6 +51,7 @@ await VerifyCS.VerifyCodeFixAsync( code); } + [TestMethod] public async Task WhenTestInitializeIsPublic_InsideInternalClassWithDiscoverInternals_NoDiagnostic() { string code = """ @@ -69,6 +72,7 @@ public void TestInitialize() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestInitializeIsInternal_InsidePublicClassWithDiscoverInternals_Diagnostic() { string code = """ @@ -107,10 +111,11 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } - [Arguments("protected")] - [Arguments("internal")] - [Arguments("internal protected")] - [Arguments("private")] + [DataRow("protected")] + [DataRow("internal")] + [DataRow("internal protected")] + [DataRow("private")] + [TestMethod] public async Task WhenTestInitializeIsNotPublic_Diagnostic(string accessibility) { string code = $$""" @@ -147,6 +152,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestInitializeIsAbstract_Diagnostic() { string code = """ @@ -179,6 +185,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestInitializeIsGeneric_Diagnostic() { string code = """ @@ -213,6 +220,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestInitializeIsStatic_Diagnostic() { string code = """ @@ -247,6 +255,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestInitializeHasParameters_Diagnostic() { string code = """ @@ -281,6 +290,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestInitializeReturnTypeIsNotValid_Diagnostic() { string code = """ @@ -356,6 +366,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestInitializeReturnTypeIsValid_NoDiagnostic() { string code = """ @@ -387,6 +398,7 @@ public ValueTask TestInitialize2() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestInitializeIsAsyncVoid_Diagnostic() { string code = """ @@ -425,6 +437,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenMultipleViolations_TheyAllGetFixed() { string code = """ @@ -463,6 +476,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenTestInitializeIsNotOnClass_Diagnostic() { string code = """ @@ -480,6 +494,7 @@ public struct MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestInitializeIsOnSealedClassNotMarkedWithTestClass_Diagnostic() { string code = """ @@ -497,6 +512,7 @@ public sealed class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestInitializeIsOnNonSealedClassNotMarkedWithTestClass_NoDiagnostic() { string code = """ @@ -514,6 +530,7 @@ public void TestInitialize() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestInitializeIsOnGenericClass_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs index 714c32714f..77323cb892 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class TestMethodShouldBeValidAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class TestMethodShouldBeValidAnalyzerTests { + [TestMethod] public async Task WhenTestMethodIsPublic_NoDiagnostic() { string code = """ @@ -28,10 +29,11 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } - [Arguments("protected")] - [Arguments("internal")] - [Arguments("internal protected")] - [Arguments("private")] + [DataRow("protected")] + [DataRow("internal")] + [DataRow("internal protected")] + [DataRow("private")] + [TestMethod] public async Task WhenTestMethodIsNotPublic_Diagnostic(string accessibility) { string code = $$""" @@ -63,6 +65,7 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenMethodIsNotPublicAndNotTestMethod_NoDiagnostic() { string code = $$""" @@ -92,6 +95,7 @@ internal void InternalMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenTestMethodIsStatic_Diagnostic() { string code = """ @@ -123,6 +127,7 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestMethodIsAbstract_Diagnostic() { string code = """ @@ -152,6 +157,7 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestMethodIsGeneric_Diagnostic() { string code = """ @@ -195,6 +201,7 @@ public void MyTestMethod(T t) await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestMethodIsNotOrdinary_Diagnostic() { string code = """ @@ -213,6 +220,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestMethodReturnTypeIsNotValid_Diagnostic() { string code = """ @@ -280,6 +288,7 @@ public void MyTestMethod3() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestMethodReturnTypeIsValid_NoDiagnostic() { string code = """ @@ -311,6 +320,7 @@ public ValueTask MyTestMethod2() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenTestMethodIsAsyncVoid_Diagnostic() { string code = """ @@ -344,6 +354,7 @@ public async Task MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + [TestMethod] public async Task WhenTestMethodIsInternalAndDiscoverInternals_NoDiagnostic() { string code = """ @@ -383,6 +394,7 @@ public void MyTestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] public async Task WhenTestMethodIsPrivateAndDiscoverInternals_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldNotBeIgnoredAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldNotBeIgnoredAnalyzerTests.cs index 7deb038f4a..9c66e4a8f0 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldNotBeIgnoredAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldNotBeIgnoredAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class TestMethodShouldNotBeIgnoredAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class TestMethodShouldNotBeIgnoredAnalyzerTests { + [TestMethod] public async Task WhenTestMethodIsNotIgnored_NoDiagnostic() { string code = """ @@ -28,6 +29,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingIgnoreWithoutTestMethod_NoDiagnostic() { string code = """ @@ -46,6 +48,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestMethodIsIgnored_Diagnostic() { string code = """ @@ -69,6 +72,7 @@ await VerifyCS.VerifyAnalyzerAsync( .WithArguments("MyTestMethod")); } + [TestMethod] public async Task WhenDerivedTestMethodAttributeIsIgnored_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TypeContainingTestMethodShouldBeATestClassAnalyzer.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TypeContainingTestMethodShouldBeATestClassAnalyzer.cs index a743894786..816b3d6653 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TypeContainingTestMethodShouldBeATestClassAnalyzer.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TypeContainingTestMethodShouldBeATestClassAnalyzer.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class TypeContainingTestMethodShouldBeATestClassAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class TypeContainingTestMethodShouldBeATestClassAnalyzerTests { + [TestMethod] public async Task WhenTestClassHasTestMethod_NoDiagnostic() { string code = """ @@ -28,6 +29,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassWithoutTestAttribute_HaveTestMethod_Diagnostic() { string code = """ @@ -43,6 +45,7 @@ public void TestMethod1() {} await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassWithoutTestAttribute_AndWithoutTestMethods_InheritTestClassWithTestMethods_Diagnostic() { string code = """ @@ -71,6 +74,7 @@ public void TestMethod2() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassWithoutTestAttribute_AndWithTestMethods_InheritTestClass_Diagnostic() { string code = """ @@ -99,6 +103,7 @@ public void TestMethod2() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenInheritedTestClassAttribute_HasInheritedTestMethodAttribute_NoDiagnostic() { string code = """ @@ -125,6 +130,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassWithoutTestAttribute_HasInheritedTestMethodAttribute_Diagnostic() { string code = """ @@ -146,6 +152,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAbstractClassWithoutTestAttribute_HaveTestMethod_NoDiagnostic() { string code = """ @@ -163,6 +170,7 @@ public void TestMethod1() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenClassHasTestInitializeAndThenTestMethod_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs index c9a55fb143..e55bdf9e1a 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs @@ -13,9 +13,10 @@ namespace MSTest.Analyzers.UnitTests; -[TestGroup] -public sealed class UseAsyncSuffixTestFixtureMethodSuppressorTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class UseAsyncSuffixTestFixtureMethodSuppressorTests { + [TestMethod] public async Task AsyncTestFixtureMethodsWithoutSuffix_DiagnosticIsSuppressed() { string code = @" @@ -57,6 +58,7 @@ public class SomeClass }.RunAsync(); } + [TestMethod] public async Task AsyncTestMethodWithSuffix_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs index de624c2e06..f5bced8a52 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs @@ -13,9 +13,10 @@ namespace MSTest.Analyzers.UnitTests; -[TestGroup] -public sealed class UseAsyncSuffixTestMethodSuppressorTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class UseAsyncSuffixTestMethodSuppressorTests { + [TestMethod] public async Task AsyncTestMethodWithoutSuffix_DiagnosticIsSuppressed() { string code = @@ -45,6 +46,7 @@ public class SomeClass }.RunAsync(); } + [TestMethod] public async Task AsyncDataTestMethodWithoutSuffix_DiagnosticIsSuppressed() { string code = @@ -73,6 +75,7 @@ public class SomeClass }.RunAsync(); } + [TestMethod] public async Task AsyncTestMethodWithSuffix_NoDiagnostic() { string code = diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAttributeOnTestMethodAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAttributeOnTestMethodAnalyzerTests.cs index 17f3b8a420..f7353183ad 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAttributeOnTestMethodAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAttributeOnTestMethodAnalyzerTests.cs @@ -9,8 +9,8 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class UseAttributeOnTestMethodAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class UseAttributeOnTestMethodAnalyzerTests { private static readonly List<(DiagnosticDescriptor Rule, string AttributeUsageExample)> RuleUsageExamples = [ @@ -35,11 +35,11 @@ protected override void Verify(System.Exception exception) { } internal static IEnumerable<(DiagnosticDescriptor Rule, string AttributeUsageExample)> GetAttributeUsageExampleAndRuleTuples() => RuleUsageExamples.Select(tuple => (tuple.Rule, tuple.AttributeUsageExample)); - internal static IEnumerable GetAttributeUsageExamples() - => RuleUsageExamples.Select(tuple => tuple.AttributeUsageExample); + internal static IEnumerable GetAttributeUsageExamples() + => RuleUsageExamples.Select(tuple => new object[] { tuple.AttributeUsageExample }); // This generates all possible combinations of any two tuples (Rule, AttributeUsageExample) with the exception of the - // combaination where the two tuples are equal. The result is flattened in a new tuple created from the elements of the + // combination where the two tuples are equal. The result is flattened in a new tuple created from the elements of the // previous two tuples. internal static IEnumerable<(DiagnosticDescriptor Rule1, string AttributeUsageExample1, DiagnosticDescriptor Rule2, string AttributeUsageExample2)> GetAttributeUsageExampleAndRuleTuplesForTwoAttributes() => RuleUsageExamples @@ -47,7 +47,8 @@ internal static IEnumerable GetAttributeUsageExamples() .Where(tuples => !tuples.tuple1.AttributeUsageExample.Equals(tuples.tuple2.AttributeUsageExample, StringComparison.Ordinal)) .Select(tuples => (tuples.tuple1.Rule, tuples.tuple1.AttributeUsageExample, tuples.tuple2.Rule, tuples.tuple2.AttributeUsageExample)); - [ArgumentsProvider(nameof(GetAttributeUsageExamples))] + [DynamicData(nameof(GetAttributeUsageExamples), DynamicDataSourceType.Method)] + [TestMethod] public async Task WhenMethodIsMarkedWithTestMethodAndTestAttributes_NoDiagnosticAsync(string attributeUsageExample) { string code = $$""" @@ -69,7 +70,8 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } - [ArgumentsProvider(nameof(GetAttributeUsageExampleAndRuleTuples))] + [DynamicData(nameof(GetAttributeUsageExampleAndRuleTuples), DynamicDataSourceType.Method)] + [TestMethod] public async Task WhenMethodIsMarkedWithTestAttributeButNotWithTestMethod_DiagnosticAsync(DiagnosticDescriptor rule, string attributeUsageExample) { string code = $$""" @@ -106,7 +108,8 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, VerifyCS.Diagnostic(rule).WithLocation(0), fixedCode); } - [ArgumentsProvider(nameof(GetAttributeUsageExampleAndRuleTuplesForTwoAttributes))] + [DynamicData(nameof(GetAttributeUsageExampleAndRuleTuplesForTwoAttributes), DynamicDataSourceType.Method)] + [TestMethod] public async Task WhenMethodIsMarkedWithMultipleTestAttributesButNotWithTestMethod_DiagnosticOnEachAttributeAsync( DiagnosticDescriptor rule1, string attributeUsageExample1, @@ -149,7 +152,8 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, new[] { VerifyCS.Diagnostic(rule1).WithLocation(0), VerifyCS.Diagnostic(rule2).WithLocation(1) }, fixedCode); } - [ArgumentsProvider(nameof(GetAttributeUsageExamples))] + [DynamicData(nameof(GetAttributeUsageExamples), DynamicDataSourceType.Method)] + [TestMethod] public async Task WhenMethodIsMarkedWithTestAttributeAndCustomTestMethod_NoDiagnosticAsync(string attributeUsageExample) { string code = $$""" diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseClassCleanupBehaviorEndOfClassAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseClassCleanupBehaviorEndOfClassAnalyzerTests.cs index 531bf1886c..6406ceff68 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseClassCleanupBehaviorEndOfClassAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseClassCleanupBehaviorEndOfClassAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class UseClassCleanupBehaviorEndOfClassAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class UseClassCleanupBehaviorEndOfClassAnalyzerTests { + [TestMethod] public async Task UsingClassCleanup_WithoutCleanupBehaviorEndOfClass_AndNotInsideTestClass_NoDiagnostic() { string code = """ @@ -27,6 +28,7 @@ public static void ClassCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingClassCleanup_WithoutCleanupBehaviorEndOfClass_AndInsideTestClass_Diagnostic() { string code = """ @@ -45,6 +47,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingClassCleanup_WithCleanupBehaviorEndOfClass_NoDiagnostic() { string code = """ @@ -63,6 +66,7 @@ public static void ClassCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingClassCleanup_WithCleanupBehaviorEndOfAssembly_Diagnostic() { string code = """ @@ -81,6 +85,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingClassCleanup_WithoutCleanupBehavior_Diagnostic() { string code = """ @@ -99,6 +104,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingClassCleanup_WithoutCleanupBehaviorAndWithInheritanceBehavior_Diagnostic() { string code = """ @@ -117,6 +123,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingClassCleanup_WithCleanupBehaviorEndOFAssemblyAndWithInheritanceBehavior_Diagnostic() { string code = """ @@ -135,6 +142,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingClassCleanup_WithCleanupBehaviorEndOFClassAndWithInheritanceBehavior_NoDiagnostic() { string code = """ @@ -153,6 +161,7 @@ public static void ClassCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingClassCleanup_InsideTestClass_WithClassCleanupExecutionWithEndOfClassBehavior_NoDiagnostic() { string code = """ @@ -172,6 +181,7 @@ public static void ClassCleanup() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingClassCleanup_InsideTestClass_WithClassCleanupExecutionWithEndOfAsseblyBehavior_Diagnostic() { string code = """ @@ -191,6 +201,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingClassCleanup_InsideTestClass_WithClassCleanupExecutionWithEndOfClassBehavior_WithCleanupBehaviorEndOfAssembly_Diagnostic() { string code = """ @@ -210,6 +221,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task UsingClassCleanup_InsideTestClass_WithClassCleanupExecutionWithEndOfAssemblyBehavior_WithCleanupBehaviorEndOfClass_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests.cs index 228f7c2f41..ecfd32451e 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests.cs @@ -7,9 +7,10 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public sealed class UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests { + [TestMethod] public async Task WhenTestClassHasDeploymentItem_NoDiagnostic() { string code = """ @@ -25,6 +26,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenTestMethodHasDeploymentItem_NoDiagnostic() { string code = """ @@ -44,6 +46,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenInheritedTestClassAttributeHasDeploymentItem_NoDiagnostic() { string code = """ @@ -62,6 +65,7 @@ public class MyTestClass await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenInheritedTestMethodAttributeHasDeploymentItem_NoDiagnostic() { string code = """ @@ -84,6 +88,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAClassHasDeploymentItem_Diagnostic() { string code = """ @@ -98,6 +103,7 @@ public class [|MyTestClass|] await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAMethodHasDeploymentItem_Diagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseParallelizeAttributeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseParallelizeAttributeAnalyzerTests.cs index ddc0b5b5b8..7dcf190ed1 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseParallelizeAttributeAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseParallelizeAttributeAnalyzerTests.cs @@ -7,13 +7,15 @@ namespace MSTest.Analyzers.Test; -[TestGroup] -public class UseParallelizeAttributeAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public class UseParallelizeAttributeAnalyzerTests { + [TestMethod] public async Task WhenNoAttributeSpecified_Diagnostic() => await VerifyCS.VerifyAnalyzerAsync( string.Empty, VerifyCS.Diagnostic(UseParallelizeAttributeAnalyzer.Rule).WithNoLocation()); + [TestMethod] public async Task WhenParallelizeAttributeSet_NoDiagnostic() { string code = """ @@ -25,6 +27,7 @@ public async Task WhenParallelizeAttributeSet_NoDiagnostic() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenDoNotParallelizeAttributeSet_NoDiagnostic() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs index 61c1187523..cdb5bfaf7c 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs @@ -8,9 +8,10 @@ namespace MSTest.Analyzers.Test; // NOTE: tests in this class are intentionally not using the [|...|] markup syntax so that we test the arguments -[TestGroup] -public sealed class UseProperAssertMethodsAnalyzerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class UseProperAssertMethodsAnalyzerTests { + [TestMethod] public async Task WhenAssertIsTrueWithEqualsNullArgument() { string code = """ @@ -50,6 +51,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertIsTrueWithIsNullArgument() { string code = """ @@ -89,6 +91,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertIsTrueWithNotEqualsNullArgument() { string code = """ @@ -128,6 +131,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertIsTrueWithIsNotNullArgument() { string code = """ @@ -167,6 +171,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertIsFalseWithEqualsNullArgument() { string code = """ @@ -206,6 +211,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertIsFalseWithIsNullArgument() { string code = """ @@ -245,6 +251,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertIsFalseWithNotEqualsNullArgument() { string code = """ @@ -284,6 +291,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertIsFalseWithIsNotNullArgument() { string code = """ @@ -323,6 +331,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertIsTrueAndArgumentIsEquality() { string code = """ @@ -364,6 +373,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertIsTrueAndArgumentIsInequality() { string code = """ @@ -405,6 +415,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertIsFalseAndArgumentIsEquality() { string code = """ @@ -446,6 +457,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertIsFalseAndArgumentIsInequality() { string code = """ @@ -487,6 +499,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertAreEqualAndExpectedIsNull() { string code = """ @@ -526,6 +539,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertAreNotEqualAndExpectedIsNull() { string code = """ @@ -565,6 +579,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertAreEqualAndExpectedIsTrue() { string code = """ @@ -604,6 +619,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertAreEqualAndExpectedIsTrue_CastNotAddedWhenTypeIsBool() { string code = """ @@ -643,6 +659,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertAreEqualAndExpectedIsTrue_CastNotAddedWhenTypeIsNullableBool() { string code = """ @@ -682,6 +699,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertAreEqualAndExpectedIsTrue_CastShouldBeAddedWithParentheses() { string code = """ @@ -731,6 +749,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertAreNotEqualAndExpectedIsTrue() { string code = """ @@ -754,6 +773,7 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] public async Task WhenAssertAreEqualAndExpectedIsFalse() { string code = """ @@ -793,6 +813,7 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] public async Task WhenAssertAreNotEqualAndExpectedIsFalse() { string code = """ diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2+Test.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2+Test.cs index 9db21ba08b..3fc45b7658 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2+Test.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2+Test.cs @@ -6,7 +6,6 @@ using Microsoft.CodeAnalysis.CSharp.Testing; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Testing; -using Microsoft.VisualStudio.TestTools.UnitTesting; using TestContext = Microsoft.VisualStudio.TestTools.UnitTesting.TestContext; diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AppInsightsProviderTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AppInsightsProviderTests.cs index 2d025fb0ae..41643a7bf0 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AppInsightsProviderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/AppInsightsProviderTests.cs @@ -12,14 +12,10 @@ namespace Microsoft.Testing.Extensions.UnitTests; -[TestGroup] -public sealed class AppInsightsProviderTests : TestBase +[TestClass] +public sealed class AppInsightsProviderTests { - public AppInsightsProviderTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public void Platform_CancellationToken_Cancellation_Should_Exit_Gracefully() { Mock environment = new(); @@ -84,9 +80,10 @@ public void Platform_CancellationToken_Cancellation_Should_Exit_Gracefully() #endif // We expect to not consume the second event because we exit the inner loop for the cancellation token - Assert.IsTrue(events.Single() == "Sample"); + Assert.AreEqual("Sample", events.Single()); } + [TestMethod] public void Timeout_During_Dispose_Should_Exit_Gracefully() { Mock environment = new(); diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.cs index a858eccdf2..065485ff10 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.cs @@ -10,13 +10,14 @@ namespace Microsoft.Testing.Extensions.UnitTests; -[TestGroup] -public class CrashDumpTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class CrashDumpTests { - [Arguments("Mini")] - [Arguments("Heap")] - [Arguments("Triage")] - [Arguments("Full")] + [TestMethod] + [DataRow("Mini")] + [DataRow("Heap")] + [DataRow("Triage")] + [DataRow("Full")] public async Task IsValid_If_CrashDumpType_Has_CorrectValue(string crashDumpType) { var provider = new CrashDumpCommandLineProvider(); @@ -27,6 +28,7 @@ public async Task IsValid_If_CrashDumpType_Has_CorrectValue(string crashDumpType Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } + [TestMethod] public async Task IsInvValid_If_CrashDumpType_Has_IncorrectValue() { var provider = new CrashDumpCommandLineProvider(); @@ -37,6 +39,7 @@ public async Task IsInvValid_If_CrashDumpType_Has_IncorrectValue() Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CrashDumpTypeOptionInvalidType, "invalid"), validateOptionsResult.ErrorMessage); } + [TestMethod] public async Task CrashDump_CommandLineOptions_Are_AlwaysValid() { var provider = new CrashDumpCommandLineProvider(); diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/HangDumpTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/HangDumpTests.cs index c3c239e37f..7c78930cef 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/HangDumpTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/HangDumpTests.cs @@ -14,8 +14,8 @@ namespace Microsoft.Testing.Extensions.UnitTests; -[TestGroup] -public class HangDumpTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class HangDumpTests { private HangDumpCommandLineProvider GetProvider() { @@ -27,6 +27,7 @@ private HangDumpCommandLineProvider GetProvider() "suffix")); } + [TestMethod] public async Task IsValid_If_Timeout_Value_Has_CorrectValue() { HangDumpCommandLineProvider hangDumpCommandLineProvider = GetProvider(); @@ -37,6 +38,7 @@ public async Task IsValid_If_Timeout_Value_Has_CorrectValue() Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } + [TestMethod] public async Task IsInvalid_If_Timeout_Value_Has_IncorrectValue() { HangDumpCommandLineProvider hangDumpCommandLineProvider = GetProvider(); @@ -47,12 +49,13 @@ public async Task IsInvalid_If_Timeout_Value_Has_IncorrectValue() Assert.AreEqual(ExtensionResources.HangDumpTimeoutOptionInvalidArgument, validateOptionsResult.ErrorMessage); } + [TestMethod] #if NETCOREAPP - [Arguments("Triage")] + [DataRow("Triage")] #endif - [Arguments("Mini")] - [Arguments("Heap")] - [Arguments("Full")] + [DataRow("Mini")] + [DataRow("Heap")] + [DataRow("Full")] public async Task IsValid_If_HangDumpType_Has_CorrectValue(string dumpType) { HangDumpCommandLineProvider hangDumpCommandLineProvider = GetProvider(); @@ -63,6 +66,7 @@ public async Task IsValid_If_HangDumpType_Has_CorrectValue(string dumpType) Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } + [TestMethod] public async Task IsInvalid_If_HangDumpType_Has_IncorrectValue() { HangDumpCommandLineProvider hangDumpCommandLineProvider = GetProvider(); @@ -73,9 +77,10 @@ public async Task IsInvalid_If_HangDumpType_Has_IncorrectValue() Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, ExtensionResources.HangDumpTypeOptionInvalidType, "invalid"), validateOptionsResult.ErrorMessage); } - [Arguments(HangDumpCommandLineProvider.HangDumpFileNameOptionName)] - [Arguments(HangDumpCommandLineProvider.HangDumpTimeoutOptionName)] - [Arguments(HangDumpCommandLineProvider.HangDumpTypeOptionName)] + [TestMethod] + [DataRow(HangDumpCommandLineProvider.HangDumpFileNameOptionName)] + [DataRow(HangDumpCommandLineProvider.HangDumpTimeoutOptionName)] + [DataRow(HangDumpCommandLineProvider.HangDumpTypeOptionName)] public async Task Missing_HangDumpMainOption_ShouldReturn_IsInvalid(string hangDumpArgument) { HangDumpCommandLineProvider hangDumpCommandLineProvider = GetProvider(); @@ -86,12 +91,13 @@ public async Task Missing_HangDumpMainOption_ShouldReturn_IsInvalid(string hangD ValidationResult validateOptionsResult = await hangDumpCommandLineProvider.ValidateCommandLineOptionsAsync(new TestCommandLineOptions(options)); Assert.IsFalse(validateOptionsResult.IsValid); - Assert.AreEqual(validateOptionsResult.ErrorMessage, "You specified one or more hang dump parameters but did not enable it, add --hangdump to the command line"); + Assert.AreEqual("You specified one or more hang dump parameters but did not enable it, add --hangdump to the command line", validateOptionsResult.ErrorMessage); } - [Arguments(HangDumpCommandLineProvider.HangDumpFileNameOptionName)] - [Arguments(HangDumpCommandLineProvider.HangDumpTimeoutOptionName)] - [Arguments(HangDumpCommandLineProvider.HangDumpTypeOptionName)] + [TestMethod] + [DataRow(HangDumpCommandLineProvider.HangDumpFileNameOptionName)] + [DataRow(HangDumpCommandLineProvider.HangDumpTimeoutOptionName)] + [DataRow(HangDumpCommandLineProvider.HangDumpTypeOptionName)] public async Task If_HangDumpMainOption_IsSpecified_ShouldReturn_IsValid(string hangDumpArgument) { HangDumpCommandLineProvider hangDumpCommandLineProvider = GetProvider(); diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Microsoft.Testing.Extensions.UnitTests.csproj b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Microsoft.Testing.Extensions.UnitTests.csproj index 1acf72929b..e016c30a3a 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Microsoft.Testing.Extensions.UnitTests.csproj +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Microsoft.Testing.Extensions.UnitTests.csproj @@ -3,8 +3,7 @@ $(MicrosoftTestingTargetFrameworks);net462 false - Exe - true + true diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs index 637390b157..5464028d18 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs @@ -1,10 +1,16 @@ // 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.Reflection; + using Microsoft.Testing.Extensions; +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] +[assembly: ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new Microsoft.Testing.Extensions.UnitTests.SourceGeneratedTestNodesBuilder()); + +builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]); #if ENABLE_CODECOVERAGE builder.AddCodeCoverageProvider(); #endif diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Properties/launchSettings.json b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Properties/launchSettings.json index ebf3f0f011..7195225907 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Properties/launchSettings.json +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Microsoft.Testing.Extensions.UnitTests": { "commandName": "Project", - "commandLineArgs": "--treenode-filter /*/*/*/**" + "commandLineArgs": "" } } } diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxCompareToolCommandLineTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxCompareToolCommandLineTests.cs index ce0d3c10ca..e8e3005358 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxCompareToolCommandLineTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxCompareToolCommandLineTests.cs @@ -9,11 +9,12 @@ namespace Microsoft.Testing.Extensions.UnitTests; -[TestGroup] -public class TrxCompareToolCommandLineTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class TrxCompareToolCommandLineTests { - [Arguments(TrxCompareToolCommandLine.BaselineTrxOptionName)] - [Arguments(TrxCompareToolCommandLine.TrxToCompareOptionName)] + [TestMethod] + [DataRow(TrxCompareToolCommandLine.BaselineTrxOptionName)] + [DataRow(TrxCompareToolCommandLine.TrxToCompareOptionName)] public async Task IsValid_When_Correct_TrxFile_IsProvided_For_Options(string optionName) { var provider = new TrxCompareToolCommandLine(new TestExtension()); @@ -27,10 +28,11 @@ public async Task IsValid_When_Correct_TrxFile_IsProvided_For_Options(string opt File.Delete(filename); } - [Arguments(TrxCompareToolCommandLine.BaselineTrxOptionName, false)] - [Arguments(TrxCompareToolCommandLine.BaselineTrxOptionName, true)] - [Arguments(TrxCompareToolCommandLine.TrxToCompareOptionName, false)] - [Arguments(TrxCompareToolCommandLine.TrxToCompareOptionName, true)] + [TestMethod] + [DataRow(TrxCompareToolCommandLine.BaselineTrxOptionName, false)] + [DataRow(TrxCompareToolCommandLine.BaselineTrxOptionName, true)] + [DataRow(TrxCompareToolCommandLine.TrxToCompareOptionName, false)] + [DataRow(TrxCompareToolCommandLine.TrxToCompareOptionName, true)] public async Task IsInvalid_When_Incorrect_TrxFile_IsProvided_For_Options(string optionName, bool isTrxFile) { var provider = new TrxCompareToolCommandLine(new TestExtension()); @@ -42,6 +44,7 @@ public async Task IsInvalid_When_Incorrect_TrxFile_IsProvided_For_Options(string Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, TestReports.Resources.ExtensionResources.TrxComparerToolOptionExpectsSingleArgument, optionName), validateOptionsResult.ErrorMessage); } + [TestMethod] public async Task IsValid_If_Both_TrxOptions_Are_Provided() { var provider = new TrxCompareToolCommandLine(new TestExtension()); @@ -56,8 +59,9 @@ public async Task IsValid_If_Both_TrxOptions_Are_Provided() Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } - [Arguments(true, false)] - [Arguments(false, true)] + [TestMethod] + [DataRow(true, false)] + [DataRow(false, true)] public async Task IsInvalid_If_Any_TrxOptions_Is_Missing(bool isBaseLineSet, bool isToCompareSet) { var provider = new TrxCompareToolCommandLine(new TestExtension()); diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxReportGeneratorCommandLineTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxReportGeneratorCommandLineTests.cs index 22d7e747f8..11f6621ed1 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxReportGeneratorCommandLineTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxReportGeneratorCommandLineTests.cs @@ -7,9 +7,10 @@ namespace Microsoft.Testing.Extensions.UnitTests; -[TestGroup] -public class TrxReportGeneratorCommandLineTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class TrxReportGeneratorCommandLineTests { + [TestMethod] public async Task IsValid_If_TrxFile_And_Only_TargetFilename_Is_Provided() { var provider = new TrxReportGeneratorCommandLine(); @@ -21,8 +22,9 @@ public async Task IsValid_If_TrxFile_And_Only_TargetFilename_Is_Provided() Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } - [Arguments(false, false)] - [Arguments(true, true)] + [TestMethod] + [DataRow(false, false)] + [DataRow(true, true)] public async Task IsInvalid_If_TrxFile_And_Only_TargetFilename_Are_Not_Provided(bool isTrxFile, bool hasDirectory) { var provider = new TrxReportGeneratorCommandLine(); @@ -39,8 +41,9 @@ public async Task IsInvalid_If_TrxFile_And_Only_TargetFilename_Are_Not_Provided( Assert.AreEqual(isTrxFile ? TestReports.Resources.ExtensionResources.TrxReportFileNameShouldNotContainPath : TestReports.Resources.ExtensionResources.TrxReportFileNameExtensionIsNotTrx, validateOptionsResult.ErrorMessage); } - [Arguments(false, false, true)] - [Arguments(true, true, false)] + [TestMethod] + [DataRow(false, false, true)] + [DataRow(true, true, false)] public async Task IsValid_When_TrxReport_TrxReportFile_Is_Provided_And_DiscoverTests_Not_Provided(bool isFileNameSet, bool isTrxSet, bool isDiscoverTestsSet) { var provider = new TrxReportGeneratorCommandLine(); @@ -65,8 +68,9 @@ public async Task IsValid_When_TrxReport_TrxReportFile_Is_Provided_And_DiscoverT Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } - [Arguments(true, false, false)] - [Arguments(true, true, true)] + [TestMethod] + [DataRow(true, false, false)] + [DataRow(true, true, true)] public async Task IsInvalid_When_TrxReport_TrxReportFile_Is_Provided_And_DiscoverTests_Provided(bool isFileNameSet, bool isTrxSet, bool isDiscoverTestsSet) { var provider = new TrxReportGeneratorCommandLine(); diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxTests.cs index e411f49abc..9ba22507da 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxTests.cs @@ -20,8 +20,8 @@ namespace Microsoft.Testing.Extensions.UnitTests; -[TestGroup] -public class TrxTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public class TrxTests { private readonly Mock _environmentMock = new(); private readonly Mock _commandLineOptionsMock = new(); @@ -33,6 +33,7 @@ public class TrxTests(ITestExecutionContext testExecutionContext) : TestBase(tes private readonly Dictionary> _artifactsByTestNode = new(); private readonly Dictionary> _artifactsByExtension = new(); + [TestMethod] public async Task TrxReportEngine_GenerateReportAsyncWithNullAdapterSupportTrxCapability_TrxDoesNotContainClassName() { // Arrange @@ -51,6 +52,7 @@ public async Task TrxReportEngine_GenerateReportAsyncWithNullAdapterSupportTrxCa Assert.IsFalse(trxContent.Contains(@"className=")); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsyncWithNotExecutedTests_TrxExecutedTestsCountHasIt() { // Arrange @@ -69,6 +71,7 @@ public async Task TrxReportEngine_GenerateReportAsyncWithNotExecutedTests_TrxExe Assert.IsTrue(trxContent.Contains(@"notExecuted=""1""")); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsyncWithTimeoutTests_TrxTimeoutTestsCountHasIt() { // Arrange @@ -87,6 +90,7 @@ public async Task TrxReportEngine_GenerateReportAsyncWithTimeoutTests_TrxTimeout Assert.IsTrue(trxContent.Contains(@"timeout=""1""")); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_WithArgumentTrxReportFileName_FileIsCorrectlyGenerated() { // Arrange @@ -105,6 +109,7 @@ public async Task TrxReportEngine_GenerateReportAsync_WithArgumentTrxReportFileN AssertTrxOutcome(xml, "Completed"); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_WithInvalidArgumentValueForTrxReportFileName_FileIsGeneratedWithNormalizedName() { // Arrange @@ -123,6 +128,7 @@ public async Task TrxReportEngine_GenerateReportAsync_WithInvalidArgumentValueFo AssertTrxOutcome(xml, "Completed"); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_WithTestHostCrash_ResultSummaryOutcomeIsFailed() { // Arrange @@ -139,6 +145,7 @@ public async Task TrxReportEngine_GenerateReportAsync_WithTestHostCrash_ResultSu AssertTrxOutcome(xml, "Failed"); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_WithTestSkipped_ResultSummaryOutcomeIsCompleted() { // Arrange @@ -155,6 +162,7 @@ public async Task TrxReportEngine_GenerateReportAsync_WithTestSkipped_ResultSumm AssertTrxOutcome(xml, "Completed"); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_WithTestFailed_WithStandardErrorTrxMessage_TrxContainsStdErr() { // Arrange @@ -184,9 +192,10 @@ public async Task TrxReportEngine_GenerateReportAsync_WithTestFailed_WithStandar "; - Assert.That(Regex.IsMatch(trxContent, trxContentsPattern)); + Assert.IsTrue(Regex.IsMatch(trxContent, trxContentsPattern)); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_WithTestFailed_WithoutStandardErrorTrxMessage_TrxContainsStdOut() { // Arrange @@ -211,9 +220,10 @@ public async Task TrxReportEngine_GenerateReportAsync_WithTestFailed_WithoutStan "; - Assert.That(Regex.IsMatch(trxContent, trxContentsPattern)); + Assert.IsTrue(Regex.IsMatch(trxContent, trxContentsPattern)); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_WithTestFailed_WithoutStandardErrorTrxMessage_TrxContainsErrorInfo() { // Arrange @@ -241,9 +251,10 @@ public async Task TrxReportEngine_GenerateReportAsync_WithTestFailed_WithoutStan "; - Assert.That(Regex.IsMatch(trxContent, trxContentsPattern)); + Assert.IsTrue(Regex.IsMatch(trxContent, trxContentsPattern)); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_PassedTestWithTestCategory_TrxContainsTestCategory() { // Arrange @@ -267,9 +278,10 @@ public async Task TrxReportEngine_GenerateReportAsync_PassedTestWithTestCategory "; - Assert.That(Regex.IsMatch(trxContent, trxContentsPattern)); + Assert.IsTrue(Regex.IsMatch(trxContent, trxContentsPattern)); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_FailedTestWithTestCategory_TrxContainsTestCategory() { // Arrange @@ -293,9 +305,10 @@ public async Task TrxReportEngine_GenerateReportAsync_FailedTestWithTestCategory "; - Assert.That(Regex.IsMatch(trxContent, trxContentsPattern)); + Assert.IsTrue(Regex.IsMatch(trxContent, trxContentsPattern)); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_WithAdapterSupportTrxCapability_TrxContainsClassName() { // Arrange @@ -314,9 +327,10 @@ public async Task TrxReportEngine_GenerateReportAsync_WithAdapterSupportTrxCapab XDocument xml = GetTrxContent(memoryStream); AssertTrxOutcome(xml, "Completed"); string trxContent = xml.ToString(); - Assert.That(trxContent.Contains(@"className=""TrxFullyQualifiedTypeName"), trxContent); + Assert.IsTrue(trxContent.Contains(@"className=""TrxFullyQualifiedTypeName"), trxContent); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_WithArtifactsByTestNode_TrxContainsResultFile() { // Arrange @@ -340,9 +354,10 @@ public async Task TrxReportEngine_GenerateReportAsync_WithArtifactsByTestNode_Tr "; - Assert.That(Regex.IsMatch(trxContent, trxContentsPattern)); + Assert.IsTrue(Regex.IsMatch(trxContent, trxContentsPattern)); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_WithArtifactsByExtension_TrxContainsCollectorDataEntries() { // Arrange @@ -372,9 +387,10 @@ public async Task TrxReportEngine_GenerateReportAsync_WithArtifactsByExtension_T "; - Assert.That(Regex.IsMatch(trxContent, trxContentsPattern)); + Assert.IsTrue(Regex.IsMatch(trxContent, trxContentsPattern)); } + [TestMethod] public async Task TrxReportEngine_GenerateReportAsync_FileAlreadyExists_WillRetry() { // Arrange @@ -422,7 +438,6 @@ private static void AssertTrxOutcome(XDocument xml, string expectedOutcome) Assert.IsNotNull(resultSummary); XAttribute? outcome = resultSummary.FirstAttribute; Assert.IsNotNull(outcome); - Assert.IsNotNull(outcome.Value); Assert.IsTrue(outcome.Value.Equals(expectedOutcome, StringComparison.Ordinal)); } diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/RunSettingsCommandLineOptionsProviderTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/RunSettingsCommandLineOptionsProviderTests.cs index 03f91ef640..b4e782d03f 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/RunSettingsCommandLineOptionsProviderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/RunSettingsCommandLineOptionsProviderTests.cs @@ -13,10 +13,10 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.UnitTests.CommandLine; -[TestGroup] -public sealed class RunSettingsCommandLineOptionsProviderTests(ITestExecutionContext testExecutionContext) - : TestBase(testExecutionContext) +[TestClass] +public sealed class RunSettingsCommandLineOptionsProviderTests { + [TestMethod] public async Task RunSettingsOption_WhenFileDoesNotExist_IsNotValid() { // Arrange @@ -35,6 +35,7 @@ public async Task RunSettingsOption_WhenFileDoesNotExist_IsNotValid() Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, ExtensionResources.RunsettingsFileDoesNotExist, filePath), result.ErrorMessage); } + [TestMethod] public async Task RunSettingsOption_WhenFileCannotBeOpen_IsNotValid() { // Arrange @@ -54,6 +55,7 @@ public async Task RunSettingsOption_WhenFileCannotBeOpen_IsNotValid() Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, ExtensionResources.RunsettingsFileCannotBeRead, filePath), result.ErrorMessage); } + [TestMethod] public async Task RunSettingsOption_WhenFileExistsAndCanBeOpen_IsValid() { // Arrange diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/TestRunParameterCommandLineOptionsProviderTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/TestRunParameterCommandLineOptionsProviderTests.cs index 7677aef16d..06225f002d 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/TestRunParameterCommandLineOptionsProviderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/TestRunParameterCommandLineOptionsProviderTests.cs @@ -10,10 +10,10 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.UnitTests.CommandLine; -[TestGroup] -public sealed class TestRunParameterCommandLineOptionsProviderTests(ITestExecutionContext testExecutionContext) - : TestBase(testExecutionContext) +[TestClass] +public sealed class TestRunParameterCommandLineOptionsProviderTests { + [TestMethod] public async Task TestRunParameterOption_WhenArgumentDoesNotContainEqual_IsNotValid() { // Arrange @@ -28,6 +28,7 @@ public async Task TestRunParameterOption_WhenArgumentDoesNotContainEqual_IsNotVa Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, ExtensionResources.TestRunParameterOptionArgumentIsNotParameter, "something"), result.ErrorMessage); } + [TestMethod] public async Task TestRunParameterOption_WhenArgumentContainsEqual_IsValid() { // Arrange diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests.csproj b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests.csproj index fa5aae3fee..b7ade1f8e0 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests.csproj +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests.csproj @@ -3,7 +3,7 @@ $(TargetFrameworks);net462 false - true + true Exe diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.cs index ab1f69cd40..c546179a91 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.cs @@ -10,19 +10,17 @@ using Microsoft.Testing.Platform.TestHost; using Microsoft.VisualStudio.TestPlatform.ObjectModel; +using TestResult = Microsoft.VisualStudio.TestPlatform.ObjectModel.TestResult; + namespace Microsoft.Testing.Extensions.VSTestBridge.UnitTests.ObjectModel; -[TestGroup] -public sealed class ObjectModelConvertersTests : TestBase +[TestClass] +public sealed class ObjectModelConvertersTests { private static readonly IClientInfo TestClient = new ClientInfoService("UnitTest", string.Empty); private static readonly IClientInfo VSTestClient = new ClientInfoService(WellKnownClients.VisualStudio, string.Empty); - public ObjectModelConvertersTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public void ToTestNode_WhenTestCaseHasDisplayName_TestNodeDisplayNameUsesIt() { TestCase testCase = new("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs") @@ -34,6 +32,7 @@ public void ToTestNode_WhenTestCaseHasDisplayName_TestNodeDisplayNameUsesIt() Assert.AreEqual("MyDisplayName", testNode.DisplayName); } + [TestMethod] public void ToTestNode_WhenTestCaseHasNoDisplayName_TestNodeDisplayNameUsesIt() { TestCase testCase = new("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs"); @@ -42,6 +41,7 @@ public void ToTestNode_WhenTestCaseHasNoDisplayName_TestNodeDisplayNameUsesIt() Assert.AreEqual("SomeFqn", testNode.DisplayName); } + [TestMethod] public void ToTestNode_WhenTestResultHasCodeFilePath_SetsTestFileLocationProperty() { TestResult testResult = new(new("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs") @@ -52,6 +52,7 @@ public void ToTestNode_WhenTestResultHasCodeFilePath_SetsTestFileLocationPropert Assert.AreEqual("FilePath", testNode.Properties.Single().FilePath); } + [TestMethod] public void ToTestNode_WhenTestResultOutcomeIsFailed_TestNodePropertiesContainFailedTestNodeStateProperty() { TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")) @@ -63,12 +64,13 @@ public void ToTestNode_WhenTestResultOutcomeIsFailed_TestNodePropertiesContainFa var testNode = testResult.ToTestNode(false, TestClient); FailedTestNodeStateProperty[] failedTestNodeStateProperties = testNode.Properties.OfType().ToArray(); - Assert.IsTrue(failedTestNodeStateProperties.Length == 1); + Assert.AreEqual(1, failedTestNodeStateProperties.Length); Assert.IsTrue(failedTestNodeStateProperties[0].Exception is VSTestException); Assert.AreEqual(testResult.ErrorStackTrace, failedTestNodeStateProperties[0].Exception!.StackTrace); Assert.AreEqual(testResult.ErrorMessage, failedTestNodeStateProperties[0].Exception!.Message); } + [TestMethod] public void ToTestNode_WhenTestResultHasMSTestDiscovererTestCategoryTestProperty_TestNodePropertiesContainTheCategoryInTraits() { TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")); @@ -78,12 +80,13 @@ public void ToTestNode_WhenTestResultHasMSTestDiscovererTestCategoryTestProperty var testNode = testResult.ToTestNode(false, VSTestClient); SerializableNamedKeyValuePairsStringProperty[] errorTestNodeStateProperties = testNode.Properties.OfType().ToArray(); - Assert.IsTrue(errorTestNodeStateProperties.Length == 1); - Assert.IsTrue(errorTestNodeStateProperties[0].Name == "traits"); - Assert.IsTrue(errorTestNodeStateProperties[0].Pairs.Length == 1); - Assert.IsTrue(errorTestNodeStateProperties[0].Pairs[0].Key == "category1"); + Assert.AreEqual(1, errorTestNodeStateProperties.Length); + Assert.AreEqual("traits", errorTestNodeStateProperties[0].Name); + Assert.AreEqual(1, errorTestNodeStateProperties[0].Pairs.Length); + Assert.AreEqual("category1", errorTestNodeStateProperties[0].Pairs[0].Key); } + [TestMethod] public void ToTestNode_WhenTestResultHasMSTestDiscovererTestCategoryTestPropertyWithTrxEnabled_TestNodePropertiesContainTrxCategoriesProperty() { TestResult testResult = new(new TestCase("assembly.class.SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")); @@ -93,11 +96,12 @@ public void ToTestNode_WhenTestResultHasMSTestDiscovererTestCategoryTestProperty var testNode = testResult.ToTestNode(true, VSTestClient); TrxCategoriesProperty[] trxCategoriesProperty = testNode.Properties.OfType().ToArray(); - Assert.IsTrue(trxCategoriesProperty.Length == 1); - Assert.IsTrue(trxCategoriesProperty[0].Categories.Length == 1); - Assert.AreEqual(trxCategoriesProperty[0].Categories[0], "category1"); + Assert.AreEqual(1, trxCategoriesProperty.Length); + Assert.AreEqual(1, trxCategoriesProperty[0].Categories.Length); + Assert.AreEqual("category1", trxCategoriesProperty[0].Categories[0]); } + [TestMethod] public void ToTestNode_WhenTestResultHasTestCaseHierarchyTestProperty_TestNodePropertiesContainItInSerializableNamedArrayStringProperty() { TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")); @@ -107,13 +111,14 @@ public void ToTestNode_WhenTestResultHasTestCaseHierarchyTestProperty_TestNodePr var testNode = testResult.ToTestNode(false, VSTestClient); SerializableNamedArrayStringProperty[] trxCategoriesProperty = testNode.Properties.OfType().ToArray(); - Assert.IsTrue(trxCategoriesProperty.Length == 1); - Assert.AreEqual(trxCategoriesProperty[0].Values[0], "assembly"); - Assert.AreEqual(trxCategoriesProperty[0].Values[1], "class"); - Assert.AreEqual(trxCategoriesProperty[0].Values[2], "category"); - Assert.AreEqual(trxCategoriesProperty[0].Values[3], "test"); + Assert.AreEqual(1, trxCategoriesProperty.Length); + Assert.AreEqual("assembly", trxCategoriesProperty[0].Values[0]); + Assert.AreEqual("class", trxCategoriesProperty[0].Values[1]); + Assert.AreEqual("category", trxCategoriesProperty[0].Values[2]); + Assert.AreEqual("test", trxCategoriesProperty[0].Values[3]); } + [TestMethod] public void ToTestNode_WhenTestResultHasOriginalExecutorUriProperty_TestNodePropertiesContainItInSerializableKeyValuePairStringProperty() { TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")); @@ -125,11 +130,12 @@ public void ToTestNode_WhenTestResultHasOriginalExecutorUriProperty_TestNodeProp var testNode = testResult.ToTestNode(false, VSTestClient); SerializableKeyValuePairStringProperty[] serializableKeyValuePairStringProperty = testNode.Properties.OfType().ToArray(); - Assert.IsTrue(serializableKeyValuePairStringProperty.Length == 3); - Assert.AreEqual(serializableKeyValuePairStringProperty[0].Key, VSTestTestNodeProperties.OriginalExecutorUriPropertyName); - Assert.AreEqual(serializableKeyValuePairStringProperty[0].Value, "https://vs.com/"); + Assert.AreEqual(3, serializableKeyValuePairStringProperty.Length); + Assert.AreEqual(VSTestTestNodeProperties.OriginalExecutorUriPropertyName, serializableKeyValuePairStringProperty[0].Key); + Assert.AreEqual("https://vs.com/", serializableKeyValuePairStringProperty[0].Value); } + [TestMethod] public void ToTestNode_WhenTestResultHasFullyQualifiedTypeAndTrxEnabled_TestNodeHasFullyQualifiedTypeName() { TestResult testResult = new(new TestCase("assembly.class.test", new("executor://uri", UriKind.Absolute), "source.cs")); @@ -140,15 +146,17 @@ public void ToTestNode_WhenTestResultHasFullyQualifiedTypeAndTrxEnabled_TestNode Assert.AreEqual("assembly.class", testNode.Properties.Single().FullyQualifiedTypeName); } + [TestMethod] public void ToTestNode_WhenTestResultHasNoFullyQualifiedTypeAndTrxEnabled_Throws() { TestResult testResult = new(new TestCase("test", new("executor://uri", UriKind.Absolute), "source.cs")); - string errorMessage = Assert.Throws(() => testResult.ToTestNode(true, TestClient)).Message; + string errorMessage = Assert.ThrowsException(() => testResult.ToTestNode(true, TestClient)).Message; Assert.IsTrue(errorMessage.Contains("Unable to parse fully qualified type name from test case: ")); } + [TestMethod] public void ToTestNode_FromTestResult_TestNodePropertiesContainCorrectTimingProperty() { var startTime = new DateTime(1996, 8, 22, 20, 30, 5); @@ -167,6 +175,7 @@ public void ToTestNode_FromTestResult_TestNodePropertiesContainCorrectTimingProp Assert.AreEqual(testNode.Properties.OfType()[0], testResultTimingProperty); } + [TestMethod] public void ToTestNode_WhenTestResultOutcomeIsNotFoundWithoutSetErrorMessage_TestNodePropertiesContainErrorTestNodeStatePropertyWithDefaultErrorMessage() { TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")) @@ -177,12 +186,13 @@ public void ToTestNode_WhenTestResultOutcomeIsNotFoundWithoutSetErrorMessage_Tes var testNode = testResult.ToTestNode(false, TestClient); ErrorTestNodeStateProperty[] errorTestNodeStateProperties = testNode.Properties.OfType().ToArray(); - Assert.IsTrue(errorTestNodeStateProperties.Length == 1); + Assert.AreEqual(1, errorTestNodeStateProperties.Length); Assert.IsTrue(errorTestNodeStateProperties[0].Exception is VSTestException); Assert.AreEqual(testResult.ErrorStackTrace, errorTestNodeStateProperties[0].Exception!.StackTrace); Assert.IsTrue(errorTestNodeStateProperties[0].Exception!.Message.Contains("Not found")); } + [TestMethod] public void ToTestNode_WhenTestResultOutcomeIsSkipped_TestNodePropertiesContainSkippedTestNodeStateProperty() { TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")) @@ -192,9 +202,10 @@ public void ToTestNode_WhenTestResultOutcomeIsSkipped_TestNodePropertiesContainS var testNode = testResult.ToTestNode(false, TestClient); SkippedTestNodeStateProperty[] skipTestNodeStateProperties = testNode.Properties.OfType().ToArray(); - Assert.IsTrue(skipTestNodeStateProperties.Length == 1); + Assert.AreEqual(1, skipTestNodeStateProperties.Length); } + [TestMethod] public void ToTestNode_WhenTestResultOutcomeIsNone_TestNodePropertiesContainSkippedTestNodeStateProperty() { TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")) @@ -204,9 +215,10 @@ public void ToTestNode_WhenTestResultOutcomeIsNone_TestNodePropertiesContainSkip var testNode = testResult.ToTestNode(false, TestClient); SkippedTestNodeStateProperty[] skipTestNodeStateProperties = testNode.Properties.OfType().ToArray(); - Assert.IsTrue(skipTestNodeStateProperties.Length == 1); + Assert.AreEqual(1, skipTestNodeStateProperties.Length); } + [TestMethod] public void ToTestNode_WhenTestResultOutcomeIsPassed_TestNodePropertiesContainPassedTestNodeStateProperty() { TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")) @@ -216,9 +228,10 @@ public void ToTestNode_WhenTestResultOutcomeIsPassed_TestNodePropertiesContainPa var testNode = testResult.ToTestNode(false, TestClient); PassedTestNodeStateProperty[] passedTestNodeStateProperties = testNode.Properties.OfType().ToArray(); - Assert.IsTrue(passedTestNodeStateProperties.Length == 1); + Assert.AreEqual(1, passedTestNodeStateProperties.Length); } + [TestMethod] public void ToTestNode_WhenTestResultHasUidAndDisplayNameWithWellKnownClient_TestNodePropertiesContainSerializableKeyValuePairStringPropertyTwice() { TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")) @@ -229,12 +242,13 @@ public void ToTestNode_WhenTestResultHasUidAndDisplayNameWithWellKnownClient_Tes var testNode = testResult.ToTestNode(false, VSTestClient); SerializableKeyValuePairStringProperty[] errorTestNodeStateProperties = testNode.Properties.OfType().ToArray(); - Assert.IsTrue(errorTestNodeStateProperties.Length == 2, "Expected 2 SerializableKeyValuePairStringProperty"); - Assert.IsTrue(errorTestNodeStateProperties[0].Key == "vstest.TestCase.Id"); - Assert.IsTrue(errorTestNodeStateProperties[1].Key == "vstest.TestCase.FullyQualifiedName"); - Assert.IsTrue(errorTestNodeStateProperties[1].Value == "SomeFqn"); + Assert.AreEqual(2, errorTestNodeStateProperties.Length, "Expected 2 SerializableKeyValuePairStringProperty"); + Assert.AreEqual("vstest.TestCase.Id", errorTestNodeStateProperties[0].Key); + Assert.AreEqual("vstest.TestCase.FullyQualifiedName", errorTestNodeStateProperties[1].Key); + Assert.AreEqual("SomeFqn", errorTestNodeStateProperties[1].Value); } + [TestMethod] public void ToTestNode_WhenTestResultHasTraits_TestNodePropertiesContainIt() { TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")) @@ -246,10 +260,10 @@ public void ToTestNode_WhenTestResultHasTraits_TestNodePropertiesContainIt() var testNode = testResult.ToTestNode(false, VSTestClient); SerializableNamedKeyValuePairsStringProperty[] errorTestNodeStateProperties = testNode.Properties.OfType().ToArray(); - Assert.IsTrue(errorTestNodeStateProperties.Length == 1); - Assert.IsTrue(errorTestNodeStateProperties[0].Name == "traits"); - Assert.IsTrue(errorTestNodeStateProperties[0].Pairs.Length == 1); - Assert.IsTrue(errorTestNodeStateProperties[0].Pairs[0].Key == "key"); - Assert.IsTrue(errorTestNodeStateProperties[0].Pairs[0].Value == "value"); + Assert.AreEqual(1, errorTestNodeStateProperties.Length); + Assert.AreEqual("traits", errorTestNodeStateProperties[0].Name); + Assert.AreEqual(1, errorTestNodeStateProperties[0].Pairs.Length); + Assert.AreEqual("key", errorTestNodeStateProperties[0].Pairs[0].Key); + Assert.AreEqual("value", errorTestNodeStateProperties[0].Pairs[0].Value); } } diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunContextAdapterTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunContextAdapterTests.cs index 543e1012bb..20be61bec0 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunContextAdapterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunContextAdapterTests.cs @@ -9,17 +9,13 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.UnitTests.ObjectModel; -[TestGroup] -public class RunContextAdapterTests : TestBase +[TestClass] +public class RunContextAdapterTests { private readonly Mock _commandLineOptions = new(); private readonly Mock _runSettings = new(); - public RunContextAdapterTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public void TestRunDirectory_IsNotNull_If_ResultsDirectory_Is_Provided() { string runSettings = @@ -38,6 +34,7 @@ public void TestRunDirectory_IsNotNull_If_ResultsDirectory_Is_Provided() Assert.IsNotNull(runContextAdapter.RunSettings); } + [TestMethod] public void TestRunDirectory_IsNull_If_ResultsDirectory_IsNot_Provided() { string runSettings = diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs index 224ed9acf9..409834e19e 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs @@ -14,12 +14,13 @@ namespace Microsoft.Testing.Extensions.VSTestBridge.UnitTests.ObjectModel; -[TestGroup] -public class RunSettingsPatcherTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public class RunSettingsPatcherTests { private readonly Mock _configuration = new(); private readonly Mock _commandLineOptions = new(); + [TestMethod] public void Patch_WhenNoRunSettingsProvided_CreateRunSettingsWithResultsDirectoryElement() { _configuration.Setup(x => x[PlatformConfigurationConstants.PlatformResultDirectory]).Returns("/PlatformResultDirectory"); @@ -30,6 +31,7 @@ public void Patch_WhenNoRunSettingsProvided_CreateRunSettingsWithResultsDirector runSettingsDocument.XPathSelectElement("RunSettings/RunConfiguration/ResultsDirectory")!.Value); } + [TestMethod] public void Patch_WithRunSettingsProvidedButMissingResultsDirectory_AddsElement() { string runSettings = """ @@ -49,6 +51,7 @@ public void Patch_WithRunSettingsProvidedButMissingResultsDirectory_AddsElement( Assert.IsTrue(bool.Parse(runSettingsDocument.XPathSelectElement("RunSettings/RunConfiguration/Canary")!.Value)); } + [TestMethod] public void Patch_WithRunSettingsContainingResultsDirectory_EntryIsNotOverridden() { string runSettings = @@ -69,6 +72,7 @@ public void Patch_WithRunSettingsContainingResultsDirectory_EntryIsNotOverridden Assert.IsTrue(bool.Parse(runSettingsDocument.XPathSelectElement("RunSettings/RunConfiguration/Canary")!.Value)); } + [TestMethod] public void Patch_WhenRunSettingsExists_MergesParameters() { string runSettings = """ @@ -94,14 +98,15 @@ public void Patch_WhenRunSettingsExists_MergesParameters() _commandLineOptions.Object); XElement[] testRunParameters = runSettingsDocument.XPathSelectElements("RunSettings/TestRunParameters/Parameter").ToArray(); - Assert.AreEqual(testRunParameters[0].Attribute("name")!.Value, "key1"); - Assert.AreEqual(testRunParameters[0].Attribute("value")!.Value, "value1"); - Assert.AreEqual(testRunParameters[1].Attribute("name")!.Value, "key2"); - Assert.AreEqual(testRunParameters[1].Attribute("value")!.Value, "updated-value"); - Assert.AreEqual(testRunParameters[2].Attribute("name")!.Value, "key3"); - Assert.AreEqual(testRunParameters[2].Attribute("value")!.Value, "value3"); + Assert.AreEqual("key1", testRunParameters[0].Attribute("name")!.Value); + Assert.AreEqual("value1", testRunParameters[0].Attribute("value")!.Value); + Assert.AreEqual("key2", testRunParameters[1].Attribute("name")!.Value); + Assert.AreEqual("updated-value", testRunParameters[1].Attribute("value")!.Value); + Assert.AreEqual("key3", testRunParameters[2].Attribute("name")!.Value); + Assert.AreEqual("value3", testRunParameters[2].Attribute("value")!.Value); } + [TestMethod] public void Patch_WhenRunSettingsDoesNotExist_AddParameters() { string[]? arguments; @@ -117,9 +122,9 @@ public void Patch_WhenRunSettingsDoesNotExist_AddParameters() _commandLineOptions.Object); XElement[] testRunParameters = runSettingsDocument.XPathSelectElements("RunSettings/TestRunParameters/Parameter").ToArray(); - Assert.AreEqual(testRunParameters[0].Attribute("name")!.Value, "key1"); - Assert.AreEqual(testRunParameters[0].Attribute("value")!.Value, "value1"); - Assert.AreEqual(testRunParameters[1].Attribute("name")!.Value, "key2"); - Assert.AreEqual(testRunParameters[1].Attribute("value")!.Value, "value2"); + Assert.AreEqual("key1", testRunParameters[0].Attribute("name")!.Value); + Assert.AreEqual("value1", testRunParameters[0].Attribute("value")!.Value); + Assert.AreEqual("key2", testRunParameters[1].Attribute("name")!.Value); + Assert.AreEqual("value2", testRunParameters[1].Attribute("value")!.Value); } } diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs index 0b997618f7..8c64d561f7 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs @@ -1,16 +1,21 @@ // 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.Reflection; + using Microsoft.Testing.Extensions; -using Microsoft.Testing.Extensions.VSTestBridge.UnitTests; -ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new SourceGeneratedTestNodesBuilder()); +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] +[assembly: ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] #if NETCOREAPP Console.WriteLine("Dynamic code supported: " + System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported); #endif +ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + +builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]); + #if !NATIVE_AOT #if ENABLE_CODECOVERAGE builder.AddCodeCoverageProvider(); diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Properties/launchSettings.json b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Properties/launchSettings.json index ea079cb247..23c4781b41 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Properties/launchSettings.json +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Microsoft.Testing.Extensions.VSTestBridge.UnitTests": { "commandName": "Project", - "commandLineArgs": "--treenode-filter /*/*/*/**", + "commandLineArgs": "", "environmentVariables": { } } diff --git a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/MSBuildTests.cs b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/MSBuildTests.cs index 503931e844..79a669510d 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/MSBuildTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/MSBuildTests.cs @@ -4,38 +4,27 @@ using System.Collections; using Microsoft.Build.Framework; -#if NET8_0_OR_GREATER + using Moq; -#endif namespace Microsoft.Testing.Platform.MSBuild.UnitTests; -[TestGroup] -public class MSBuildTests : TestBase +[TestClass] +public sealed class MSBuildTests { -#if NET8_0_OR_GREATER private readonly Mock _buildEngine; private readonly List _errors; -#endif - public MSBuildTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) + public MSBuildTests() { -#if NET8_0_OR_GREATER _buildEngine = new Mock(); _errors = new List(); _buildEngine.Setup(x => x.LogErrorEvent(It.IsAny())).Callback(e => _errors.Add(e)); -#endif } + [TestMethod] public void Verify_Correct_Registration_Order_For_WellKnown_Extensions() { -#if !NET8_0_OR_GREATER - // On netfx, net6.0, and net7.0 this is failing with: - // Could not load file or assembly 'Microsoft.Build.Framework, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified. - // This is because the NuGet Package is "compatible" with netstandard2.0, so it can be installed everywhere, but it restores dlls only into specific (new) versions of .NET Framework and .NET. - return; -#else InMemoryFileSystem inMemoryFileSystem = new(); TestingPlatformEntryPointTask testingPlatformEntryPoint = new(inMemoryFileSystem) { @@ -69,7 +58,6 @@ internal sealed class TestingPlatformEntryPoint """; Assert.AreEqual(expectedSourceOrder, inMemoryFileSystem.Files["obj/entryPointFile"]); -#endif } private sealed class InMemoryFileSystem : IFileSystem diff --git a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests.csproj b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests.csproj index 87bee4bfd3..d5a6455762 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests.csproj +++ b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests.csproj @@ -1,9 +1,9 @@ - $(MicrosoftTestingTargetFrameworks);net462 + net8.0;net9.0 false - true + true Exe diff --git a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs index 45d399bd11..2057080ba4 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs @@ -1,11 +1,16 @@ // 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.Reflection; + using Microsoft.Testing.Extensions; +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] +[assembly: ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] + // DebuggerUtility.AttachVSToCurrentProcess(); ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new Microsoft.Testing.Platform.MSBuild.UnitTests.SourceGeneratedTestNodesBuilder()); +builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]); #if ENABLE_CODECOVERAGE builder.AddCodeCoverageProvider(); #endif diff --git a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Usings.cs b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Usings.cs index a91def1ab6..10fe4382b8 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Usings.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Usings.cs @@ -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. -global using Microsoft.Testing.Internal.Framework; global using Microsoft.Testing.Platform.Builder; global using Microsoft.Testing.Platform.Extensions; global using Microsoft.Testing.TestInfrastructure; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/ArgumentArityTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/ArgumentArityTests.cs index 33921a8451..5cada34ede 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/ArgumentArityTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/ArgumentArityTests.cs @@ -10,8 +10,8 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class ArgumentArityTests : TestBase +[TestClass] +public sealed class ArgumentArityTests { private readonly ICommandLineOptionsProvider[] _systemCommandLineOptionsProviders = [ @@ -23,11 +23,7 @@ public class ArgumentArityTests : TestBase new ExtensionCommandLineProviderMockOptionsWithDifferentArity() ]; - public ArgumentArityTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public async Task ParseAndValidate_WhenOptionWithArityZeroIsCalledWithOneArgument_ReturnsFalse() { // Arrange @@ -43,6 +39,7 @@ public async Task ParseAndValidate_WhenOptionWithArityZeroIsCalledWithOneArgumen Assert.AreEqual("Option '--zeroArgumentsOption' from provider 'Microsoft Testing Platform command line provider' (UID: PlatformCommandLineProvider) expects no arguments", result.ErrorMessage, StringComparer.Ordinal); } + [TestMethod] public async Task ParseAndValidate_WhenOptionWithArityExactlyOneIsCalledWithTwoArguments_ReturnsFalse() { // Arrange @@ -58,6 +55,7 @@ public async Task ParseAndValidate_WhenOptionWithArityExactlyOneIsCalledWithTwoA Assert.AreEqual("Option '--exactlyOneArgumentsOption' from provider 'Microsoft Testing Platform command line provider' (UID: PlatformCommandLineProvider) expects at most 1 arguments", result.ErrorMessage); } + [TestMethod] public async Task ParseAndValidate_WhenOptionWithArityExactlyOneIsCalledWithoutArguments_ReturnsFalse() { // Arrange @@ -73,6 +71,7 @@ public async Task ParseAndValidate_WhenOptionWithArityExactlyOneIsCalledWithoutA Assert.AreEqual("Option '--exactlyOneArgumentsOption' from provider 'Microsoft Testing Platform command line provider' (UID: PlatformCommandLineProvider) expects at least 1 arguments", result.ErrorMessage); } + [TestMethod] public async Task ParseAndValidate_WhenOptionWithArityZeroOrOneIsCalledWithTwoArguments_ReturnsFalse() { // Arrange @@ -88,6 +87,7 @@ public async Task ParseAndValidate_WhenOptionWithArityZeroOrOneIsCalledWithTwoAr Assert.AreEqual("Option '--zeroOrOneArgumentsOption' from provider 'Microsoft Testing Platform command line provider' (UID: PlatformCommandLineProvider) expects at most 1 arguments", result.ErrorMessage); } + [TestMethod] public async Task ParseAndValidate_WhenOptionWithArityOneOrMoreIsCalledWithoutArguments_ReturnsFalse() { // Arrange @@ -103,6 +103,7 @@ public async Task ParseAndValidate_WhenOptionWithArityOneOrMoreIsCalledWithoutAr Assert.AreEqual("Option '--oneOrMoreArgumentsOption' from provider 'Microsoft Testing Platform command line provider' (UID: PlatformCommandLineProvider) expects at least 1 arguments", result.ErrorMessage); } + [TestMethod] public async Task ParseAndValidate_WhenOptionsGetsTheExpectedNumberOfArguments_ReturnsTrue() { // Arrange diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineHandlerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineHandlerTests.cs index b7544c39ee..c192ec482f 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineHandlerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineHandlerTests.cs @@ -12,8 +12,8 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class CommandLineHandlerTests : TestBase +[TestClass] +public sealed class CommandLineHandlerTests { private readonly Mock _outputDisplayMock = new(); private readonly Mock _testApplicationModuleInfoMock = new(); @@ -25,11 +25,7 @@ public class CommandLineHandlerTests : TestBase private readonly ICommandLineOptionsProvider[] _extensionCommandLineOptionsProviders = []; - public CommandLineHandlerTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public async Task ParseAndValidateAsync_InvalidCommandLineArguments_ReturnsFalse() { // Arrange @@ -42,10 +38,11 @@ public async Task ParseAndValidateAsync_InvalidCommandLineArguments_ReturnsFalse // Assert Assert.IsFalse(result.IsValid); - Assert.Contains("Invalid command line arguments:", result.ErrorMessage); - Assert.Contains("Unexpected argument 'a'", result.ErrorMessage); + StringAssert.Contains(result.ErrorMessage, "Invalid command line arguments:"); + StringAssert.Contains(result.ErrorMessage, "Unexpected argument 'a'"); } + [TestMethod] public async Task ParseAndValidateAsync_EmptyCommandLineArguments_ReturnsTrue() { // Arrange @@ -60,6 +57,7 @@ public async Task ParseAndValidateAsync_EmptyCommandLineArguments_ReturnsTrue() Assert.IsTrue(result.IsValid); } + [TestMethod] public async Task ParseAndValidateAsync_DuplicateOption_ReturnsFalse() { // Arrange @@ -77,9 +75,10 @@ public async Task ParseAndValidateAsync_DuplicateOption_ReturnsFalse() // Assert Assert.IsFalse(result.IsValid); - Assert.Contains("Option '--userOption' is declared by multiple extensions: 'Microsoft Testing Platform command line provider', 'Microsoft Testing Platform command line provider'", result.ErrorMessage); + StringAssert.Contains(result.ErrorMessage, "Option '--userOption' is declared by multiple extensions: 'Microsoft Testing Platform command line provider', 'Microsoft Testing Platform command line provider'"); } + [TestMethod] public async Task ParseAndValidateAsync_InvalidOption_ReturnsFalse() { // Arrange @@ -95,6 +94,7 @@ public async Task ParseAndValidateAsync_InvalidOption_ReturnsFalse() Assert.AreEqual("Option '--diagnostic-verbosity' has invalid arguments: '--diagnostic-verbosity' expects a single level argument ('Trace', 'Debug', 'Information', 'Warning', 'Error', or 'Critical')", result.ErrorMessage); } + [TestMethod] public async Task ParseAndValidateAsync_InvalidArgumentArity_ReturnsFalse() { // Arrange @@ -110,6 +110,7 @@ public async Task ParseAndValidateAsync_InvalidArgumentArity_ReturnsFalse() Assert.AreEqual("Option '--help' from provider 'Platform command line provider' (UID: PlatformCommandLineProvider) expects no arguments", result.ErrorMessage); } + [TestMethod] public async Task ParseAndValidateAsync_ReservedOptions_ReturnsFalse() { // Arrange @@ -129,6 +130,7 @@ public async Task ParseAndValidateAsync_ReservedOptions_ReturnsFalse() Assert.AreEqual("Option '--help' is reserved and cannot be used by providers: 'help'", result.ErrorMessage); } + [TestMethod] public async Task ParseAndValidateAsync_ReservedOptionsPrefix_ReturnsFalse() { // Arrange @@ -148,6 +150,7 @@ public async Task ParseAndValidateAsync_ReservedOptionsPrefix_ReturnsFalse() Assert.AreEqual("Option `--internal-customextension` from provider 'Microsoft Testing Platform command line provider' (UID: PlatformCommandLineProvider) is using the reserved prefix '--internal'", result.ErrorMessage); } + [TestMethod] public async Task ParseAndValidateAsync_UnknownOption_ReturnsFalse() { // Arrange @@ -168,6 +171,7 @@ public async Task ParseAndValidateAsync_UnknownOption_ReturnsFalse() Assert.AreEqual("Unknown option '--x'", result.ErrorMessage); } + [TestMethod] public async Task ParseAndValidateAsync_InvalidValidConfiguration_ReturnsFalse() { // Arrange @@ -187,6 +191,7 @@ public async Task ParseAndValidateAsync_InvalidValidConfiguration_ReturnsFalse() Assert.AreEqual("Invalid configuration for provider 'Microsoft Testing Platform command line provider' (UID: PlatformCommandLineProvider). Error: Invalid configuration errorMessage", result.ErrorMessage); } + [TestMethod] public void IsHelpInvoked_HelpOptionSet_ReturnsTrue() { // Arrange @@ -204,6 +209,7 @@ public void IsHelpInvoked_HelpOptionSet_ReturnsTrue() _outputDisplayMock.Verify(o => o.DisplayBannerAsync(It.IsAny()), Times.Never); } + [TestMethod] public void IsInfoInvoked_InfoOptionSet_ReturnsTrue() { // Arrange @@ -221,6 +227,7 @@ public void IsInfoInvoked_InfoOptionSet_ReturnsTrue() _outputDisplayMock.Verify(o => o.DisplayBannerAsync(It.IsAny()), Times.Never); } + [TestMethod] public void IsVersionInvoked_VersionOptionSet_ReturnsTrue() { // Arrange @@ -238,6 +245,7 @@ public void IsVersionInvoked_VersionOptionSet_ReturnsTrue() _outputDisplayMock.Verify(o => o.DisplayBannerAsync(It.IsAny()), Times.Never); } + [TestMethod] public void GetOptionValue_OptionExists_ReturnsOptionValue() { // Arrange @@ -251,12 +259,13 @@ public void GetOptionValue_OptionExists_ReturnsOptionValue() // Assert Assert.IsTrue(result); - Assert.IsFalse(optionValue is null); + Assert.IsNotNull(optionValue); Assert.AreEqual(optionValue?.Length, 2); Assert.AreEqual("value1", optionValue?[0]); Assert.AreEqual("value2", optionValue?[1]); } + [TestMethod] public void GetOptionValue_OptionDoesNotExist_ReturnsNull() { // Arrange @@ -278,7 +287,7 @@ public void GetOptionValue_OptionDoesNotExist_ReturnsNull() // Assert Assert.IsFalse(result); - Assert.IsTrue(optionValue is null); + Assert.IsNull(optionValue); } private sealed class ExtensionCommandLineProviderMockReservedOptions : ICommandLineOptionsProvider diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineTests.cs index bd1f756bb7..7f426c4ef5 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineTests.cs @@ -1,19 +1,21 @@ // 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.Reflection; + using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions.CommandLine; using Microsoft.Testing.Platform.Helpers; namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class CommandLineTests : TestBase +[TestClass] +public sealed class CommandLineTests { // The test method ParserTests is parameterized and one of the parameter needs to be CommandLineParseResult. // The test method has to be public to be run, but CommandLineParseResult is internal. // So, we introduce this wrapper to be used instead so that the test method can be made public. - public class CommandLineParseResultWrapper + public sealed class CommandLineParseResultWrapper { internal CommandLineParseResultWrapper(string? toolName, IReadOnlyList options, IReadOnlyList errors) => Result = new CommandLineParseResult(toolName, options, errors); @@ -21,12 +23,8 @@ internal CommandLineParseResultWrapper(string? toolName, IReadOnlyList ParserTestDataFormat(TestArgumentsContext ctx) + public static string ParserTestDataFormat(MethodInfo methodInfo, object?[]? data) { - (int TestNum, string[] Args, (string RspFileName, string RspFileContent)[]? RspFiles, CommandLineParseResultWrapper ParseResult) item = ((int, string[], (string, string)[], CommandLineParseResultWrapper))ctx.Arguments; + (int testNum, string[] args, (string RspFileName, string RspFileContent)[]? rspFiles, CommandLineParseResultWrapper parseResult) = ((int)data![0]!, (string[])data[1]!, ((string, string)[])data[2]!, (CommandLineParseResultWrapper)data[3]!); - return item.TestNum == 13 - ? new(item, $"\"--option1\", $@\" \"\" \\{{Environment.NewLine}} \"\" \" {item.TestNum}") - : new(item, $"{item.Args.Aggregate((a, b) => $"{a} {b}")} {item.TestNum}"); + return testNum == 13 + ? $"\"--option1\", $@\" \"\" \\{{Environment.NewLine}} \"\" \" {testNum}" + : $"{args.Aggregate((a, b) => $"{a} {b}")} {testNum}"; } internal static IEnumerable<(int TestNum, string[] Args, (string RspFileName, string RspFileContent)[]? RspFiles, CommandLineParseResultWrapper ParseResult)> ParserTestsData() @@ -204,6 +202,7 @@ public void ParserTests(int testNum, string[] args, (string RspFileName, string }.ToArray(), [])); } + [TestMethod] public void CommandLineOptionWithNumber_IsSupported() { _ = new CommandLineOption("123", "sample", ArgumentArity.ZeroOrOne, false); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs index b108c5ed59..bc1fb5ee9b 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs @@ -10,20 +10,16 @@ namespace Microsoft.Testing.Platform.UnitTests.CommandLine; -[TestGroup] -public class PlatformCommandLineProviderTests : TestBase +[TestClass] +public sealed class PlatformCommandLineProviderTests { - public PlatformCommandLineProviderTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - - [Arguments("Trace")] - [Arguments("Debug")] - [Arguments("Information")] - [Arguments("Warning")] - [Arguments("Error")] - [Arguments("Critical")] + [TestMethod] + [DataRow("Trace")] + [DataRow("Debug")] + [DataRow("Information")] + [DataRow("Warning")] + [DataRow("Error")] + [DataRow("Critical")] public async Task IsValid_If_Verbosity_Has_CorrectValue(string dumpType) { var provider = new PlatformCommandLineProvider(); @@ -34,6 +30,7 @@ public async Task IsValid_If_Verbosity_Has_CorrectValue(string dumpType) Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } + [TestMethod] public async Task IsInvalid_If_Verbosity_Has_IncorrectValue() { var provider = new PlatformCommandLineProvider(); @@ -44,6 +41,7 @@ public async Task IsInvalid_If_Verbosity_Has_IncorrectValue() Assert.AreEqual(PlatformResources.PlatformCommandLineDiagnosticOptionExpectsSingleArgumentErrorMessage, validateOptionsResult.ErrorMessage); } + [TestMethod] public async Task IsValid_If_ClientPort_Is_Integer() { var provider = new PlatformCommandLineProvider(); @@ -54,8 +52,9 @@ public async Task IsValid_If_ClientPort_Is_Integer() Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } - [Arguments("32.32")] - [Arguments("invalid")] + [TestMethod] + [DataRow("32.32")] + [DataRow("invalid")] public async Task IsInvalid_If_ClientPort_Is_Not_Integer(string clientPort) { var provider = new PlatformCommandLineProvider(); @@ -66,6 +65,7 @@ public async Task IsInvalid_If_ClientPort_Is_Not_Integer(string clientPort) Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, PlatformResources.PlatformCommandLinePortOptionSingleArgument, PlatformCommandLineProvider.ClientPortOptionKey), validateOptionsResult.ErrorMessage); } + [TestMethod] public async Task IsValid_If_ExitOnProcessExit_Is_Integer() { var provider = new PlatformCommandLineProvider(); @@ -76,8 +76,9 @@ public async Task IsValid_If_ExitOnProcessExit_Is_Integer() Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } - [Arguments("32.32")] - [Arguments("invalid")] + [TestMethod] + [DataRow("32.32")] + [DataRow("invalid")] public async Task IsInvalid_If_ExitOnProcessExit_Is_Not_Integer(string pid) { var provider = new PlatformCommandLineProvider(); @@ -88,6 +89,7 @@ public async Task IsInvalid_If_ExitOnProcessExit_Is_Not_Integer(string pid) Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, PlatformResources.PlatformCommandLineExitOnProcessExitSingleArgument, PlatformCommandLineProvider.ExitOnProcessExitOptionKey), validateOptionsResult.ErrorMessage); } + [TestMethod] public async Task IsValid_If_Diagnostics_Provided_With_Other_Diagnostics_Provided() { var provider = new PlatformCommandLineProvider(); @@ -103,6 +105,7 @@ public async Task IsValid_If_Diagnostics_Provided_With_Other_Diagnostics_Provide Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } + [TestMethod] public async Task IsValid_When_NoOptionSpecified() { var provider = new PlatformCommandLineProvider(); @@ -112,9 +115,10 @@ public async Task IsValid_When_NoOptionSpecified() Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } - [Arguments(PlatformCommandLineProvider.DiagnosticOutputDirectoryOptionKey)] - [Arguments(PlatformCommandLineProvider.DiagnosticOutputFilePrefixOptionKey)] + [DataRow(PlatformCommandLineProvider.DiagnosticOutputDirectoryOptionKey)] + [DataRow(PlatformCommandLineProvider.DiagnosticOutputFilePrefixOptionKey)] + [TestMethod] public async Task IsNotValid_If_Diagnostics_Missing_When_OthersDiagnostics_Provided(string optionName) { var provider = new PlatformCommandLineProvider(); @@ -128,9 +132,10 @@ public async Task IsNotValid_If_Diagnostics_Missing_When_OthersDiagnostics_Provi Assert.AreEqual(string.Format(CultureInfo.InvariantCulture, PlatformResources.PlatformCommandLineDiagnosticOptionIsMissing, optionName), validateOptionsResult.ErrorMessage); } - [Arguments(true, false)] - [Arguments(false, true)] - [Arguments(false, false)] + [TestMethod] + [DataRow(true, false)] + [DataRow(false, true)] + [DataRow(false, false)] public async Task IsValid_When_Both_DiscoverTests_MinimumExpectedTests_NotProvided(bool discoverTestsSet, bool minimumExpectedTestsSet) { var provider = new PlatformCommandLineProvider(); @@ -150,6 +155,7 @@ public async Task IsValid_When_Both_DiscoverTests_MinimumExpectedTests_NotProvid Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); } + [TestMethod] public async Task IsInvalid_When_Both_DiscoverTests_MinimumExpectedTests_Provided() { var provider = new PlatformCommandLineProvider(); @@ -164,6 +170,7 @@ public async Task IsInvalid_When_Both_DiscoverTests_MinimumExpectedTests_Provide Assert.AreEqual(PlatformResources.PlatformCommandLineMinimumExpectedTestsIncompatibleDiscoverTests, validateOptionsResult.ErrorMessage); } + [TestMethod] public async Task IsNotValid_If_ExitOnProcess_Not_Running() { var provider = new PlatformCommandLineProvider(); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/TreeNodeFilterCommandLineOptionsProviderTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/TreeNodeFilterCommandLineOptionsProviderTests.cs index 2b865e70f2..873a57df4f 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/TreeNodeFilterCommandLineOptionsProviderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/TreeNodeFilterCommandLineOptionsProviderTests.cs @@ -7,14 +7,10 @@ namespace Microsoft.Testing.Platform.UnitTests.CommandLine; -[TestGroup] -public class TreeNodeFilterCommandLineOptionsProviderTests : TestBase +[TestClass] +public sealed class TreeNodeFilterCommandLineOptionsProviderTests { - public TreeNodeFilterCommandLineOptionsProviderTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public async Task TreenodeFilter_AlwaysValid() { var provider = new TreeNodeFilterCommandLineOptionsProvider(new TestExtension()); @@ -24,6 +20,7 @@ public async Task TreenodeFilter_AlwaysValid() Assert.IsTrue(validateOptionsResult.IsValid); } + [TestMethod] public async Task CommandLineOptions_AlwaysValid() { var provider = new TreeNodeFilterCommandLineOptionsProvider(new TestExtension()); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/AggregatedConfigurationTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/AggregatedConfigurationTests.cs index 7d41698231..925ef3073f 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/AggregatedConfigurationTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/AggregatedConfigurationTests.cs @@ -13,21 +13,24 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class AggregatedConfigurationTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class AggregatedConfigurationTests { private const string ExpectedPath = "a/b/c"; private readonly Mock _testApplicationModuleInfoMock = new(); private readonly Mock _fileSystemMock = new(); - [Arguments(PlatformConfigurationConstants.PlatformResultDirectory)] - [Arguments(PlatformConfigurationConstants.PlatformCurrentWorkingDirectory)] - [Arguments(PlatformConfigurationConstants.PlatformTestHostWorkingDirectory)] - public void IndexerTest_DirectoryNotSetAndNoConfigurationProviders_DirectoryIsNull(string key) => Assert.IsNull(new AggregatedConfiguration([], _testApplicationModuleInfoMock.Object, _fileSystemMock.Object)[key]); - - [Arguments(PlatformConfigurationConstants.PlatformResultDirectory)] - [Arguments(PlatformConfigurationConstants.PlatformCurrentWorkingDirectory)] - [Arguments(PlatformConfigurationConstants.PlatformTestHostWorkingDirectory)] + [TestMethod] + [DataRow(PlatformConfigurationConstants.PlatformResultDirectory)] + [DataRow(PlatformConfigurationConstants.PlatformCurrentWorkingDirectory)] + [DataRow(PlatformConfigurationConstants.PlatformTestHostWorkingDirectory)] + public void IndexerTest_DirectoryNotSetAndNoConfigurationProviders_DirectoryIsNull(string key) + => Assert.IsNull(new AggregatedConfiguration([], _testApplicationModuleInfoMock.Object, _fileSystemMock.Object)[key]); + + [TestMethod] + [DataRow(PlatformConfigurationConstants.PlatformResultDirectory)] + [DataRow(PlatformConfigurationConstants.PlatformCurrentWorkingDirectory)] + [DataRow(PlatformConfigurationConstants.PlatformTestHostWorkingDirectory)] public void IndexerTest_DirectoryNotSetButConfigurationProvidersPresent_DirectoryIsNull(string key) { Mock mockProvider = new(); @@ -36,15 +39,17 @@ public void IndexerTest_DirectoryNotSetButConfigurationProvidersPresent_Director Assert.IsNull(aggregatedConfiguration[key]); } - [Arguments(PlatformConfigurationConstants.PlatformResultDirectory)] - [Arguments(PlatformConfigurationConstants.PlatformCurrentWorkingDirectory)] - [Arguments(PlatformConfigurationConstants.PlatformTestHostWorkingDirectory)] + [TestMethod] + [DataRow(PlatformConfigurationConstants.PlatformResultDirectory)] + [DataRow(PlatformConfigurationConstants.PlatformCurrentWorkingDirectory)] + [DataRow(PlatformConfigurationConstants.PlatformTestHostWorkingDirectory)] public void IndexerTest_DirectoryNotSetButConfigurationProvidersPresent_DirectoryIsNotNull(string key) { AggregatedConfiguration aggregatedConfiguration = new([new FakeConfigurationProvider(ExpectedPath)], _testApplicationModuleInfoMock.Object, _fileSystemMock.Object); Assert.AreEqual(ExpectedPath, aggregatedConfiguration[key]); } + [TestMethod] public void IndexerTest_ResultDirectorySet_DirectoryIsNotNull() { AggregatedConfiguration aggregatedConfiguration = new([], _testApplicationModuleInfoMock.Object, _fileSystemMock.Object); @@ -53,6 +58,7 @@ public void IndexerTest_ResultDirectorySet_DirectoryIsNotNull() Assert.AreEqual(ExpectedPath, aggregatedConfiguration[PlatformConfigurationConstants.PlatformResultDirectory]); } + [TestMethod] public void IndexerTest_CurrentWorkingDirectorySet_DirectoryIsNotNull() { AggregatedConfiguration aggregatedConfiguration = new([], _testApplicationModuleInfoMock.Object, _fileSystemMock.Object); @@ -61,6 +67,7 @@ public void IndexerTest_CurrentWorkingDirectorySet_DirectoryIsNotNull() Assert.AreEqual(ExpectedPath, aggregatedConfiguration[PlatformConfigurationConstants.PlatformCurrentWorkingDirectory]); } + [TestMethod] public void IndexerTest_TestHostWorkingDirectorySet_DirectoryIsNotNull() { AggregatedConfiguration aggregatedConfiguration = new([], _testApplicationModuleInfoMock.Object, _fileSystemMock.Object); @@ -69,6 +76,7 @@ public void IndexerTest_TestHostWorkingDirectorySet_DirectoryIsNotNull() Assert.AreEqual(ExpectedPath, aggregatedConfiguration[PlatformConfigurationConstants.PlatformTestHostWorkingDirectory]); } + [TestMethod] public async ValueTask CheckTestResultsDirectoryOverrideAndCreateItAsync_ResultsDirectoryIsNull_GetDirectoryFromCommandLineProvider() { Mock mockTestApplicationModuleInfo = new(); @@ -90,6 +98,7 @@ await aggregatedConfiguration.CheckTestResultsDirectoryOverrideAndCreateItAsync( Assert.AreEqual("a" + Path.DirectorySeparatorChar + "b", aggregatedConfiguration[PlatformConfigurationConstants.PlatformCurrentWorkingDirectory]); } + [TestMethod] public async ValueTask CheckTestResultsDirectoryOverrideAndCreateItAsync_ResultsDirectoryIsNull_GetDirectoryFromStore() { Mock mockTestApplicationModuleInfo = new(); @@ -111,6 +120,7 @@ public async ValueTask CheckTestResultsDirectoryOverrideAndCreateItAsync_Results Assert.AreEqual("a" + Path.DirectorySeparatorChar + "b", aggregatedConfiguration[PlatformConfigurationConstants.PlatformCurrentWorkingDirectory]); } + [TestMethod] public async ValueTask CheckTestResultsDirectoryOverrideAndCreateItAsync_ResultsDirectoryIsNull_GetDefaultDirectory() { Mock mockTestApplicationModuleInfo = new(); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationExtensionsTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationExtensionsTests.cs index ead1f42c3d..0727d1d90b 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationExtensionsTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationExtensionsTests.cs @@ -7,14 +7,9 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class ConfigurationExtensionsTests : TestBase +[TestClass] +public sealed class ConfigurationExtensionsTests { - public ConfigurationExtensionsTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - private string GetActualValueFromConfiguration(IConfiguration configuration, string key) => key switch { PlatformConfigurationConstants.PlatformResultDirectory => configuration.GetTestResultDirectory(), @@ -23,9 +18,10 @@ public ConfigurationExtensionsTests(ITestExecutionContext testExecutionContext) _ => throw new ArgumentException("Unsupported key."), }; - [Arguments(PlatformConfigurationConstants.PlatformResultDirectory)] - [Arguments(PlatformConfigurationConstants.PlatformCurrentWorkingDirectory)] - [Arguments(PlatformConfigurationConstants.PlatformTestHostWorkingDirectory)] + [TestMethod] + [DataRow(PlatformConfigurationConstants.PlatformResultDirectory)] + [DataRow(PlatformConfigurationConstants.PlatformCurrentWorkingDirectory)] + [DataRow(PlatformConfigurationConstants.PlatformTestHostWorkingDirectory)] public void ConfigurationExtensions_TestedMethod_ReturnsExpectedPath(string key) { string expectedPath = Path.Combine("a", "b", "c"); @@ -38,9 +34,10 @@ public void ConfigurationExtensions_TestedMethod_ReturnsExpectedPath(string key) Assert.AreEqual(expectedPath, GetActualValueFromConfiguration(configuration.Object, key)); } - [Arguments(PlatformConfigurationConstants.PlatformResultDirectory)] - [Arguments(PlatformConfigurationConstants.PlatformCurrentWorkingDirectory)] - [Arguments(PlatformConfigurationConstants.PlatformTestHostWorkingDirectory)] + [TestMethod] + [DataRow(PlatformConfigurationConstants.PlatformResultDirectory)] + [DataRow(PlatformConfigurationConstants.PlatformCurrentWorkingDirectory)] + [DataRow(PlatformConfigurationConstants.PlatformTestHostWorkingDirectory)] public void ConfigurationExtensions_TestedMethod_ThrowsArgumentNullException(string key) { Mock configuration = new(); @@ -48,6 +45,6 @@ public void ConfigurationExtensions_TestedMethod_ThrowsArgumentNullException(str .Setup(configuration => configuration[key]) .Returns(value: null); - Assert.Throws(() => GetActualValueFromConfiguration(configuration.Object, key)); + Assert.ThrowsException(() => GetActualValueFromConfiguration(configuration.Object, key)); } } diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationManagerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationManagerTests.cs index 8b516c7269..18faf51a91 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationManagerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationManagerTests.cs @@ -13,19 +13,19 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class ConfigurationManagerTests : TestBase +[TestClass] +public sealed class ConfigurationManagerTests { private readonly ServiceProvider _serviceProvider; - public ConfigurationManagerTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) + public ConfigurationManagerTests() { _serviceProvider = new(); _serviceProvider.AddService(new SystemFileSystem()); } - [ArgumentsProvider(nameof(GetConfigurationValueFromJsonData))] + [TestMethod] + [DynamicData(nameof(GetConfigurationValueFromJsonData), DynamicDataSourceType.Method)] public async ValueTask GetConfigurationValueFromJson(string jsonFileConfig, string key, string? result) { Mock fileSystem = new(); @@ -56,6 +56,7 @@ public async ValueTask GetConfigurationValueFromJson(string jsonFileConfig, stri yield return ("{\"platformOptions\": { \"Array\" : [ {\"Key\" : \"Value\"} , {\"Key\" : 3} ] } }", "platformOptions:Array:1:Key", "3"); } + [TestMethod] public async ValueTask InvalidJson_Fail() { Mock fileSystem = new(); @@ -65,10 +66,11 @@ public async ValueTask InvalidJson_Fail() ConfigurationManager configurationManager = new(fileSystem.Object, testApplicationModuleInfo); configurationManager.AddConfigurationSource(() => new JsonConfigurationSource(testApplicationModuleInfo, fileSystem.Object, null)); - await Assert.ThrowsAsync(() => configurationManager.BuildAsync(null, new CommandLineParseResult(null, new List(), Array.Empty()))); + await Assert.ThrowsAsync(() => configurationManager.BuildAsync(null, new CommandLineParseResult(null, new List(), Array.Empty()))); } - [ArgumentsProvider(nameof(GetConfigurationValueFromJsonData))] + [TestMethod] + [DynamicData(nameof(GetConfigurationValueFromJsonData), DynamicDataSourceType.Method)] public async ValueTask GetConfigurationValueFromJsonWithFileLoggerProvider(string jsonFileConfig, string key, string? result) { byte[] bytes = Encoding.UTF8.GetBytes(jsonFileConfig); @@ -97,6 +99,7 @@ public async ValueTask GetConfigurationValueFromJsonWithFileLoggerProvider(strin loggerMock.Verify(x => x.LogAsync(LogLevel.Trace, It.IsAny(), null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public async ValueTask BuildAsync_EmptyConfigurationSources_ThrowsException() { CurrentTestApplicationModuleInfo testApplicationModuleInfo = new(new SystemEnvironment(), new SystemProcessHandler()); @@ -104,6 +107,7 @@ public async ValueTask BuildAsync_EmptyConfigurationSources_ThrowsException() await Assert.ThrowsAsync(() => configurationManager.BuildAsync(null, new CommandLineParseResult(null, new List(), Array.Empty()))); } + [TestMethod] public async ValueTask BuildAsync_ConfigurationSourcesNotEnabledAsync_ThrowsException() { Mock mockConfigurationSource = new(); @@ -118,6 +122,7 @@ public async ValueTask BuildAsync_ConfigurationSourcesNotEnabledAsync_ThrowsExce mockConfigurationSource.Verify(x => x.IsEnabledAsync(), Times.Once); } + [TestMethod] public async ValueTask BuildAsync_ConfigurationSourceIsAsyncInitializableExtension_InitializeAsyncIsCalled() { Mock mockConfigurationProvider = new(); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/CountDownEventTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/CountDownEventTests.cs index e1cad5c9e3..484bbc5890 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/CountDownEventTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/CountDownEventTests.cs @@ -5,14 +5,10 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class CountDownEventTests : TestBase +[TestClass] +public sealed class CountDownEventTests { - public CountDownEventTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public async Task CountDownEvent_WaitAsync_Succeeded() { CountdownEvent countdownEvent = new(3); @@ -36,6 +32,7 @@ public async Task CountDownEvent_WaitAsync_Succeeded() Assert.IsTrue(await waiter1); } + [TestMethod] public async Task CountDownEvent_WaitAsyncCanceled_Succeeded() { CountdownEvent countdownEvent = new(1); @@ -46,6 +43,7 @@ public async Task CountDownEvent_WaitAsyncCanceled_Succeeded() await Assert.ThrowsAsync(async () => await waiter); } + [TestMethod] public async Task CountDownEvent_WaitAsyncCanceledByTimeout_Succeeded() { CountdownEvent countdownEvent = new(1); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/SystemAsyncMonitorTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/SystemAsyncMonitorTests.cs index bba20c5da7..a62f3bb5ed 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/SystemAsyncMonitorTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/SystemAsyncMonitorTests.cs @@ -7,14 +7,10 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class SystemAsyncMonitorTests : TestBase +[TestClass] +public sealed class SystemAsyncMonitorTests { - public SystemAsyncMonitorTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public async Task AsyncMonitor_ShouldCorrectlyLock() { var asyncSystemMonitor = (SystemAsyncMonitor)new SystemMonitorAsyncFactory().Create(); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/TaskExtensionsTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/TaskExtensionsTests.cs index d857372c67..e1c27f56f8 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/TaskExtensionsTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/TaskExtensionsTests.cs @@ -5,27 +5,29 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class TaskExtensionsTests : TestBase +[TestClass] +public sealed class TaskExtensionsTests { - public TaskExtensionsTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - - public async Task TimeoutAfterAsync_Succeeds() => await Assert.ThrowsAsync(async () - => await Task.Delay(TimeSpan.FromSeconds(60)).TimeoutAfterAsync(TimeSpan.FromSeconds(2))); + [TestMethod] + public async Task TimeoutAfterAsync_Succeeds() + => await Assert.ThrowsAsync(async () => + await Task.Delay(TimeSpan.FromSeconds(60)).TimeoutAfterAsync(TimeSpan.FromSeconds(2))); - public async Task TimeoutAfterAsync_CancellationToken_Succeeds() => await Assert.ThrowsAsync(async () => - await Task.Delay(TimeSpan.FromSeconds(60)).TimeoutAfterAsync( - TimeSpan.FromSeconds(30), - new CancellationTokenSource(TimeSpan.FromSeconds(2)).Token)); + [TestMethod] + public async Task TimeoutAfterAsync_CancellationToken_Succeeds() + => await Assert.ThrowsAsync(async () => + await Task.Delay(TimeSpan.FromSeconds(60)).TimeoutAfterAsync( + TimeSpan.FromSeconds(30), + new CancellationTokenSource(TimeSpan.FromSeconds(2)).Token)); - public async Task TimeoutAfterAsync_CancellationTokenNone_Succeeds() => await Assert.ThrowsAsync(async () => - await Task.Delay(TimeSpan.FromSeconds(60)).TimeoutAfterAsync( - TimeSpan.FromSeconds(2), - CancellationToken.None)); + [TestMethod] + public async Task TimeoutAfterAsync_CancellationTokenNone_Succeeds() + => await Assert.ThrowsAsync(async () => + await Task.Delay(TimeSpan.FromSeconds(60)).TimeoutAfterAsync( + TimeSpan.FromSeconds(2), + CancellationToken.None)); + [TestMethod] public async Task CancellationAsync_Cancellation_Succeeds() { CancellationTokenSource cancellationTokenSource = new(); @@ -38,6 +40,7 @@ public async Task CancellationAsync_Cancellation_Succeeds() Assert.AreEqual(cancelToken, exception.CancellationToken); } + [TestMethod] public async Task CancellationAsync_CancellationWithArgument_Succeeds() { CancellationTokenSource cancellationTokenSource = new(); @@ -50,6 +53,7 @@ public async Task CancellationAsync_CancellationWithArgument_Succeeds() Assert.AreEqual(cancelToken, exception.CancellationToken); } + [TestMethod] public async Task CancellationAsync_NonCanceled_Succeeds() { CancellationTokenSource cancellationTokenSource = new(); @@ -57,54 +61,59 @@ public async Task CancellationAsync_NonCanceled_Succeeds() await Task.Delay(TimeSpan.FromSeconds(1), cancelToken).WithCancellationAsync(cancelToken); } + [TestMethod] public async Task CancellationAsync_NonCanceledWithArgument_Succeeds() { CancellationTokenSource cancellationTokenSource = new(); Assert.AreEqual("Hello", await DoSomething().WithCancellationAsync(cancellationTokenSource.Token)); } - public async Task CancellationAsync_ObserveException_Succeeds() => await RetryHelper.RetryAsync( - async () => - { - ManualResetEvent waitException = new(false); - await Assert.ThrowsAsync(async () - => await Task.Run(async () => - { - await Task.Delay(TimeSpan.FromSeconds(10)); - waitException.Set(); - throw new InvalidOperationException(); - }).WithCancellationAsync(new CancellationTokenSource(TimeSpan.FromSeconds(1)).Token)); + [TestMethod] + public async Task CancellationAsync_ObserveException_Succeeds() + => await RetryHelper.RetryAsync( + async () => + { + ManualResetEvent waitException = new(false); + await Assert.ThrowsAsync(async () + => await Task.Run(async () => + { + await Task.Delay(TimeSpan.FromSeconds(10)); + waitException.Set(); + throw new InvalidOperationException(); + }).WithCancellationAsync(new CancellationTokenSource(TimeSpan.FromSeconds(1)).Token)); - waitException.WaitOne(); - await Task.Delay(TimeSpan.FromSeconds(4)); - }, 3, TimeSpan.FromSeconds(3), _ => true); + waitException.WaitOne(); + await Task.Delay(TimeSpan.FromSeconds(4)); + }, 3, TimeSpan.FromSeconds(3), _ => true); - public async Task CancellationAsyncWithReturnValue_ObserveException_Succeeds() => await RetryHelper.RetryAsync( - async () => - { - ManualResetEvent waitException = new(false); - await Assert.ThrowsAsync(async () - => await Task.Run(async () => + [TestMethod] + public async Task CancellationAsyncWithReturnValue_ObserveException_Succeeds() + => await RetryHelper.RetryAsync( + async () => + { + ManualResetEvent waitException = new(false); + await Assert.ThrowsAsync(async () + => await Task.Run(async () => + { + await Task.Delay(TimeSpan.FromSeconds(10)); + try + { + return 2; + } + finally { - await Task.Delay(TimeSpan.FromSeconds(10)); - try - { - return 2; - } - finally - { - waitException.Set(); + waitException.Set(); #pragma warning disable CA2219 // Do not raise exceptions in finally clauses - throw new InvalidOperationException(); + throw new InvalidOperationException(); #pragma warning restore CA2219 // Do not raise exceptions in finally clauses - } - }).WithCancellationAsync(new CancellationTokenSource(TimeSpan.FromSeconds(1)).Token)); + } + }).WithCancellationAsync(new CancellationTokenSource(TimeSpan.FromSeconds(1)).Token)); - waitException.WaitOne(); - await Task.Delay(TimeSpan.FromSeconds(4)); - }, 3, TimeSpan.FromSeconds(3), _ => true); + waitException.WaitOne(); + await Task.Delay(TimeSpan.FromSeconds(4)); + }, 3, TimeSpan.FromSeconds(3), _ => true); - private async Task DoSomething() + private static async Task DoSomething() { await Task.Delay(TimeSpan.FromSeconds(1)); return "Hello"; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs index 591542bc78..fea23a67d7 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/IPCTests.cs @@ -11,14 +11,15 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class IPCTests : TestBase +[TestClass] +public sealed class IPCTests { - private readonly ITestExecutionContext _testExecutionContext; + private readonly TestContext _testContext; - public IPCTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) => _testExecutionContext = testExecutionContext; + public IPCTests(TestContext testContext) + => _testContext = testContext; + [TestMethod] public async Task SingleConnectionNamedPipeServer_MultipleConnection_Fails() { PipeNameDescription pipeNameDescription = NamedPipeServer.GetPipeName(Guid.NewGuid().ToString("N")); @@ -39,9 +40,9 @@ public async Task SingleConnectionNamedPipeServer_MultipleConnection_Fails() new SystemEnvironment(), new Mock().Object, new SystemTask(), - _testExecutionContext.CancellationToken); + _testContext.CancellationTokenSource.Token); - await singleConnectionNamedPipeServer.WaitConnectionAsync(_testExecutionContext.CancellationToken); + await singleConnectionNamedPipeServer.WaitConnectionAsync(_testContext.CancellationTokenSource.Token); openedPipe.Add(singleConnectionNamedPipeServer); } } @@ -53,7 +54,7 @@ public async Task SingleConnectionNamedPipeServer_MultipleConnection_Fails() }); NamedPipeClient namedPipeClient1 = new(pipeNameDescription.Name); - await namedPipeClient1.ConnectAsync(_testExecutionContext.CancellationToken); + await namedPipeClient1.ConnectAsync(_testContext.CancellationTokenSource.Token); waitException.Wait(); Assert.AreEqual(1, openedPipe.Count); @@ -82,6 +83,7 @@ public async Task SingleConnectionNamedPipeServer_MultipleConnection_Fails() pipeNameDescription.Dispose(); } + [TestMethod] public async Task SingleConnectionNamedPipeServer_RequestReplySerialization_Succeeded() { Queue receivedMessages = new(); @@ -103,9 +105,9 @@ public async Task SingleConnectionNamedPipeServer_RequestReplySerialization_Succ manualResetEventSlim.Set(); break; } - catch (OperationCanceledException ct) when (ct.CancellationToken == _testExecutionContext.CancellationToken) + catch (OperationCanceledException ct) when (ct.CancellationToken == _testContext.CancellationTokenSource.Token) { - throw new OperationCanceledException("SingleConnectionNamedPipeServer_RequestReplySerialization_Succeeded cancellation during connect, _testExecutionContext.CancellationToken"); + throw new OperationCanceledException("SingleConnectionNamedPipeServer_RequestReplySerialization_Succeeded cancellation during connect, testContext.CancellationTokenSource.Token"); } catch (OperationCanceledException) { @@ -166,7 +168,8 @@ public async Task SingleConnectionNamedPipeServer_RequestReplySerialization_Succ pipeNameDescription.Dispose(); } - public async Task ConnectionNamedPipeServer_MultipleConnection_Succeded() + [TestMethod] + public async Task ConnectionNamedPipeServer_MultipleConnection_Succeeds() { PipeNameDescription pipeNameDescription = NamedPipeServer.GetPipeName(Guid.NewGuid().ToString("N")); @@ -174,17 +177,16 @@ public async Task ConnectionNamedPipeServer_MultipleConnection_Succeded() for (int i = 0; i < 3; i++) { pipes.Add(new( - pipeNameDescription, - async _ => await Task.FromResult(VoidResponse.CachedInstance), - new SystemEnvironment(), - new Mock().Object, - new SystemTask(), - maxNumberOfServerInstances: 3, - _testExecutionContext.CancellationToken)); + pipeNameDescription, + async _ => await Task.FromResult(VoidResponse.CachedInstance), + new SystemEnvironment(), + new Mock().Object, + new SystemTask(), + maxNumberOfServerInstances: 3, + _testContext.CancellationTokenSource.Token)); } -#pragma warning disable CA1806 // Do not ignore method results - IOException exception = Assert.Throws(() => + IOException exception = Assert.ThrowsException(() => new NamedPipeServer( pipeNameDescription, async _ => await Task.FromResult(VoidResponse.CachedInstance), @@ -192,9 +194,8 @@ public async Task ConnectionNamedPipeServer_MultipleConnection_Succeded() new Mock().Object, new SystemTask(), maxNumberOfServerInstances: 3, - _testExecutionContext.CancellationToken)); - Assert.Contains("All pipe instances are busy.", exception.Message); -#pragma warning restore CA1806 // Do not ignore method results + _testContext.CancellationTokenSource.Token)); + StringAssert.Contains(exception.Message, "All pipe instances are busy."); List waitConnectionTask = new(); int connectionCompleted = 0; @@ -202,7 +203,7 @@ public async Task ConnectionNamedPipeServer_MultipleConnection_Succeded() { waitConnectionTask.Add(Task.Run(async () => { - await namedPipeServer.WaitConnectionAsync(_testExecutionContext.CancellationToken); + await namedPipeServer.WaitConnectionAsync(_testContext.CancellationTokenSource.Token); Interlocked.Increment(ref connectionCompleted); })); } @@ -212,7 +213,7 @@ public async Task ConnectionNamedPipeServer_MultipleConnection_Succeded() { NamedPipeClient namedPipeClient = new(pipeNameDescription.Name); connectedClients.Add(namedPipeClient); - await namedPipeClient.ConnectAsync(_testExecutionContext.CancellationToken); + await namedPipeClient.ConnectAsync(_testContext.CancellationTokenSource.Token); } await Task.WhenAll(waitConnectionTask.ToArray()); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/ProtocolTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/ProtocolTests.cs index 9928d95bff..aae141f46a 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/ProtocolTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/IPC/ProtocolTests.cs @@ -6,14 +6,10 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class ProtocolTests : TestBase +[TestClass] +public sealed class ProtocolTests { - public ProtocolTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public void TestResultMessagesSerializeDeserialize() { var success = new SuccessfulTestResultMessage("uid", "displayName", 1, 100, "reason", "standardOutput", "errorOutput", "sessionUid"); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs index e770711541..e5d53c93e6 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs @@ -11,8 +11,8 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class FileLoggerTests : TestBase, IDisposable +[TestClass] +public sealed class FileLoggerTests : IDisposable { private const string LogFolder = "aaa"; private const string LogPrefix = "bbb"; @@ -33,8 +33,7 @@ public class FileLoggerTests : TestBase, IDisposable private readonly Mock _mockFileStreamFactory = new(); private readonly MemoryStream _memoryStream; - public FileLoggerTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) + public FileLoggerTests() { _mockStream.Setup(x => x.Dispose()); #if NETCOREAPP @@ -46,6 +45,7 @@ public FileLoggerTests(ITestExecutionContext testExecutionContext) _mockStream.Setup(x => x.Stream).Returns(_memoryStream); } + [TestMethod] public void Write_IfMalformedUTF8_ShouldNotCrash() { using TempDirectory tempDirectory = new(nameof(Write_IfMalformedUTF8_ShouldNotCrash)); @@ -60,6 +60,7 @@ public void Write_IfMalformedUTF8_ShouldNotCrash() fileLogger.Log(LogLevel.Trace, "\uD886", null, LoggingExtensions.Formatter, "Category"); } + [TestMethod] public void FileLogger_NullFileSyncFlush_FileStreamCreated() { // First return is to compute the expected file name. It's ok that first time is greater @@ -98,6 +99,7 @@ public void FileLogger_NullFileSyncFlush_FileStreamCreated() Assert.AreEqual(expectedFileName, fileLoggerName); } + [TestMethod] public void FileLogger_NullFileSyncFlush_FileStreamCreationThrows() { // First return is to compute the expected file name. It's ok that first time is greater @@ -111,7 +113,7 @@ public void FileLogger_NullFileSyncFlush_FileStreamCreationThrows() .Throws() .Returns(_mockStream.Object); - Assert.Throws(() => _ = new FileLogger( + Assert.ThrowsException(() => _ = new FileLogger( new(LogFolder, LogPrefix, fileName: null, syncFlush: true), LogLevel.Trace, _mockClock.Object, @@ -121,10 +123,11 @@ public void FileLogger_NullFileSyncFlush_FileStreamCreationThrows() _mockFileStreamFactory.Object)); } - [Arguments(true, true)] - [Arguments(true, false)] - [Arguments(false, true)] - [Arguments(false, false)] + [DataRow(true, true)] + [DataRow(true, false)] + [DataRow(false, true)] + [DataRow(false, false)] + [TestMethod] public void FileLogger_ValidFileName_FileStreamCreatedSuccessfully(bool syncFlush, bool fileExists) { string expectedPath = Path.Combine(LogFolder, FileName); @@ -152,7 +155,8 @@ public void FileLogger_ValidFileName_FileStreamCreatedSuccessfully(bool syncFlus Assert.AreEqual(FileName, fileLoggerName); } - [ArgumentsProvider(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers))] + [TestMethod] + [DynamicData(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers), DynamicDataSourceType.Method)] public async Task Log_WhenSyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsIt(LogLevel defaultLogLevel, LogLevel currentLogLevel) { _mockFileSystem.Setup(x => x.Exists(It.IsAny())).Returns(false); @@ -186,7 +190,8 @@ public async Task Log_WhenSyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsIt } } - [ArgumentsProvider(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers))] + [TestMethod] + [DynamicData(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers), DynamicDataSourceType.Method)] public async Task Log_WhenAsyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsIt(LogLevel defaultLogLevel, LogLevel currentLogLevel) { _mockFileSystem.Setup(x => x.Exists(It.IsAny())).Returns(false); @@ -219,5 +224,6 @@ public async Task Log_WhenAsyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsI } } - public void Dispose() => _memoryStream.Dispose(); + void IDisposable.Dispose() + => _memoryStream.Dispose(); } diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LogTestHelpers.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LogTestHelpers.cs index e0dc034294..571f312dff 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LogTestHelpers.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LogTestHelpers.cs @@ -16,6 +16,9 @@ public static IEnumerable GetLogLevels() => typeof(LogLevel).GetEnumValues().Cast(); #endif + public static IEnumerable GetLogLevelsForDynamicData() + => GetLogLevels().Select(x => new object[] { x }); + public static IEnumerable<(LogLevel DefaultLevel, LogLevel CurrentLevel)> GetLogLevelCombinations() { List<(LogLevel, LogLevel)> logLevelCombinations = new(); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerFactoryTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerFactoryTests.cs index 8322b1c830..d257ecf3d4 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerFactoryTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerFactoryTests.cs @@ -8,16 +8,15 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class LoggerFactoryTests : TestBase +[TestClass] +public sealed class LoggerFactoryTests { private readonly Mock _mockLogger = new(); private readonly Mock _mockMonitor = new(); private readonly Mock _mockLoggerProvider = new(); private readonly ILoggerProvider[] _loggerProviders; - public LoggerFactoryTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) + public LoggerFactoryTests() { _mockMonitor.Setup(x => x.Lock(It.IsAny())).Returns(new Mock().Object); _mockLoggerProvider.Setup(x => x.CreateLogger(It.IsAny())).Returns(_mockLogger.Object); @@ -28,6 +27,7 @@ public LoggerFactoryTests(ITestExecutionContext testExecutionContext) ]; } + [TestMethod] public void LoggerFactory_LoggerCreatedOnlyOnce() { using LoggerFactory loggerFactory = new(_loggerProviders, LogLevel.Information, _mockMonitor.Object); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerTests.cs index d4be4a9dc2..97852718f0 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerTests.cs @@ -9,8 +9,8 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class LoggerTests : TestBase +[TestClass] +public sealed class LoggerTests { private static readonly Func Formatter = (state, exception) => @@ -20,8 +20,7 @@ public class LoggerTests : TestBase private readonly Exception _exception = new("TestException"); private readonly Mock _mockLogger = new(); - public LoggerTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) + public LoggerTests() { _mockLogger.Setup(x => x.Log(It.IsAny(), It.IsAny(), It.IsAny(), Formatter)); _mockLogger.Setup(x => x.LogAsync(It.IsAny(), It.IsAny(), It.IsAny(), Formatter)); @@ -38,14 +37,16 @@ private Logger CreateLogger(LogLevel logLevel) return new Logger(mockLoggerFactory.Object); } - [ArgumentsProvider(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers))] + [DynamicData(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers), DynamicDataSourceType.Method)] + [TestMethod] public void Logger_CheckEnabled(LogLevel defaultLogLevel, LogLevel currentLogLevel) { Logger logger = CreateLogger(defaultLogLevel); Assert.AreEqual(logger.IsEnabled(currentLogLevel), LogTestHelpers.IsLogEnabled(defaultLogLevel, currentLogLevel)); } - [ArgumentsProvider(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers))] + [DynamicData(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers), DynamicDataSourceType.Method)] + [TestMethod] public void Logger_Log_FormattedStringIsCorrect(LogLevel defaultLogLevel, LogLevel currentLogLevel) { Logger logger = CreateLogger(defaultLogLevel); @@ -56,7 +57,8 @@ public void Logger_Log_FormattedStringIsCorrect(LogLevel defaultLogLevel, LogLev LogTestHelpers.GetExpectedLogCallTimes(defaultLogLevel, currentLogLevel)); } - [ArgumentsProvider(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers))] + [DynamicData(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers), DynamicDataSourceType.Method)] + [TestMethod] public async ValueTask Logger_LogAsync_FormattedStringIsCorrect(LogLevel defaultLogLevel, LogLevel currentLogLevel) { Logger logger = CreateLogger(defaultLogLevel); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingExtensionsTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingExtensionsTests.cs index ac6b5d61bc..194d2c5e80 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingExtensionsTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggingExtensionsTests.cs @@ -7,8 +7,8 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class LoggingExtensionsTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class LoggingExtensionsTest { private const string Message = "Test"; private readonly Exception _exception = new("TestException"); @@ -16,6 +16,7 @@ public class LoggingExtensionsTests(ITestExecutionContext testExecutionContext) // Use strict mock to ensure that only the expected methods are called private readonly Mock _mockLogger = new(MockBehavior.Strict); + [TestMethod] public void LoggerExtensions_LogTrace_CallsLogWithLogLevelTrace() { _mockLogger.Setup(x => x.Log(LogLevel.Trace, Message, null, LoggingExtensions.Formatter)); @@ -23,6 +24,7 @@ public void LoggerExtensions_LogTrace_CallsLogWithLogLevelTrace() _mockLogger.Verify(x => x.Log(LogLevel.Trace, Message, null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public void LoggerExtensions_LogDebug_CallsLogWithLogLevelDebug() { _mockLogger.Setup(x => x.Log(LogLevel.Debug, Message, null, LoggingExtensions.Formatter)); @@ -30,6 +32,7 @@ public void LoggerExtensions_LogDebug_CallsLogWithLogLevelDebug() _mockLogger.Verify(x => x.Log(LogLevel.Debug, Message, null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public void LoggerExtensions_LogInformation_CallsLogWithLogLevelInformation() { _mockLogger.Setup(x => x.Log(LogLevel.Information, Message, null, LoggingExtensions.Formatter)); @@ -37,6 +40,7 @@ public void LoggerExtensions_LogInformation_CallsLogWithLogLevelInformation() _mockLogger.Verify(x => x.Log(LogLevel.Information, Message, null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public void LoggerExtensions_LogWarning_CallsLogWithLogLevelWarning() { _mockLogger.Setup(x => x.Log(LogLevel.Warning, Message, null, LoggingExtensions.Formatter)); @@ -44,6 +48,7 @@ public void LoggerExtensions_LogWarning_CallsLogWithLogLevelWarning() _mockLogger.Verify(x => x.Log(LogLevel.Warning, Message, null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public void LoggerExtensions_LogError_CallsLogWithLogLevelError() { _mockLogger.Setup(x => x.Log(LogLevel.Error, Message, null, LoggingExtensions.Formatter)); @@ -51,6 +56,7 @@ public void LoggerExtensions_LogError_CallsLogWithLogLevelError() _mockLogger.Verify(x => x.Log(LogLevel.Error, Message, null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public void LoggerExtensions_LogError_CallsLogWithLogLevelErrorAndMessageAndException() { _mockLogger.Setup(x => x.Log(LogLevel.Error, Message, _exception, LoggingExtensions.Formatter)); @@ -58,6 +64,7 @@ public void LoggerExtensions_LogError_CallsLogWithLogLevelErrorAndMessageAndExce _mockLogger.Verify(x => x.Log(LogLevel.Error, Message, _exception, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public void LoggerExtensions_LogError_CallsLogWithLogLevelErrorAndException() { _mockLogger.Setup(x => x.Log(LogLevel.Error, _exception.ToString(), null, LoggingExtensions.Formatter)); @@ -65,6 +72,7 @@ public void LoggerExtensions_LogError_CallsLogWithLogLevelErrorAndException() _mockLogger.Verify(x => x.Log(LogLevel.Error, _exception.ToString(), null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public void LoggerExtensions_LogCritical_CallsLogWithLogLevelCritical() { _mockLogger.Setup(x => x.Log(LogLevel.Critical, Message, null, LoggingExtensions.Formatter)); @@ -72,6 +80,7 @@ public void LoggerExtensions_LogCritical_CallsLogWithLogLevelCritical() _mockLogger.Verify(x => x.Log(LogLevel.Critical, Message, null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public async ValueTask LoggerExtensions_LogTraceAsync_CallsLogAsyncWithLogLevelTrace() { _mockLogger.Setup(x => x.LogAsync(LogLevel.Trace, Message, null, LoggingExtensions.Formatter)).Returns(Task.CompletedTask); @@ -79,6 +88,7 @@ public async ValueTask LoggerExtensions_LogTraceAsync_CallsLogAsyncWithLogLevelT _mockLogger.Verify(x => x.LogAsync(LogLevel.Trace, Message, null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public async ValueTask LoggerExtensions_LogDebugAsync_CallsLogAsyncWithLogLevelDebug() { _mockLogger.Setup(x => x.LogAsync(LogLevel.Debug, Message, null, LoggingExtensions.Formatter)).Returns(Task.CompletedTask); @@ -86,6 +96,7 @@ public async ValueTask LoggerExtensions_LogDebugAsync_CallsLogAsyncWithLogLevelD _mockLogger.Verify(x => x.LogAsync(LogLevel.Debug, Message, null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public async ValueTask LoggerExtensions_LogInformationAsync_CallsLogAsyncWithLogLevelInformation() { _mockLogger.Setup(x => x.LogAsync(LogLevel.Information, Message, null, LoggingExtensions.Formatter)).Returns(Task.CompletedTask); @@ -93,6 +104,7 @@ public async ValueTask LoggerExtensions_LogInformationAsync_CallsLogAsyncWithLog _mockLogger.Verify(x => x.LogAsync(LogLevel.Information, Message, null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public async ValueTask LoggerExtensions_LogWarningAsync_CallsLogAsyncWithLogLevelWarning() { _mockLogger.Setup(x => x.LogAsync(LogLevel.Warning, Message, null, LoggingExtensions.Formatter)).Returns(Task.CompletedTask); @@ -100,6 +112,7 @@ public async ValueTask LoggerExtensions_LogWarningAsync_CallsLogAsyncWithLogLeve _mockLogger.Verify(x => x.LogAsync(LogLevel.Warning, Message, null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public async ValueTask LoggerExtensions_LogErrorAsync_CallsLogAsyncWithLogLevelError() { _mockLogger.Setup(x => x.LogAsync(LogLevel.Error, Message, null, LoggingExtensions.Formatter)).Returns(Task.CompletedTask); @@ -107,6 +120,7 @@ public async ValueTask LoggerExtensions_LogErrorAsync_CallsLogAsyncWithLogLevelE _mockLogger.Verify(x => x.LogAsync(LogLevel.Error, Message, null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public async ValueTask LoggerExtensions_LogErrorAsync_CallsLogAsyncWithLogLevelErrorAndMessageAndException() { _mockLogger.Setup(x => x.LogAsync(LogLevel.Error, Message, _exception, LoggingExtensions.Formatter)).Returns(Task.CompletedTask); @@ -114,6 +128,7 @@ public async ValueTask LoggerExtensions_LogErrorAsync_CallsLogAsyncWithLogLevelE _mockLogger.Verify(x => x.LogAsync(LogLevel.Error, Message, _exception, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public async ValueTask LoggerExtensions_LogErrorAsync_CallsLogAsyncWithLogLevelErrorAndException() { _mockLogger.Setup(x => x.LogAsync(LogLevel.Error, _exception.ToString(), null, LoggingExtensions.Formatter)).Returns(Task.CompletedTask); @@ -121,6 +136,7 @@ public async ValueTask LoggerExtensions_LogErrorAsync_CallsLogAsyncWithLogLevelE _mockLogger.Verify(x => x.LogAsync(LogLevel.Error, _exception.ToString(), null, LoggingExtensions.Formatter), Times.Once); } + [TestMethod] public async ValueTask LoggerExtensions_LogCriticalAsync_CallsLogAsyncWithLogLevelCritical() { _mockLogger.Setup(x => x.LogAsync(LogLevel.Critical, Message, null, LoggingExtensions.Formatter)).Returns(Task.CompletedTask); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/NopLoggerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/NopLoggerTests.cs index 1db2c78371..687b8fcfe8 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/NopLoggerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/NopLoggerTests.cs @@ -5,8 +5,8 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class NopLoggerTests(ITestExecutionContext testExecutionContext) : TestBase(testExecutionContext) +[TestClass] +public sealed class NopLoggerTests { private static readonly Func Formatter = (state, exception) => @@ -21,18 +21,21 @@ public class NopLoggerTests(ITestExecutionContext testExecutionContext) : TestBa private static int s_formatterCalls; - [ArgumentsProvider(nameof(LogTestHelpers.GetLogLevels), typeof(LogTestHelpers))] + [DynamicData(nameof(LogTestHelpers.GetLogLevelsForDynamicData), typeof(LogTestHelpers), DynamicDataSourceType.Method)] + [TestMethod] public void NopLogger_CheckDisabled(LogLevel logLevel) => Assert.IsFalse(_nopLogger.IsEnabled(logLevel)); - [ArgumentsProvider(nameof(LogTestHelpers.GetLogLevels), typeof(LogTestHelpers))] + [DynamicData(nameof(LogTestHelpers.GetLogLevelsForDynamicData), typeof(LogTestHelpers), DynamicDataSourceType.Method)] + [TestMethod] public void NopLogger_Log_NoFormatterCalls(LogLevel logLevel) { _nopLogger.Log(logLevel, Message, _exception, Formatter); Assert.AreEqual(0, s_formatterCalls); } - [ArgumentsProvider(nameof(LogTestHelpers.GetLogLevels), typeof(LogTestHelpers))] + [DynamicData(nameof(LogTestHelpers.GetLogLevelsForDynamicData), typeof(LogTestHelpers), DynamicDataSourceType.Method)] + [TestMethod] public async ValueTask NopLogger_LogAsync_NoFormatterCalls(LogLevel logLevel) { await _nopLogger.LogAsync(logLevel, Message, _exception, Formatter); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/AsynchronousMessageBusTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/AsynchronousMessageBusTests.cs index 94af4c458e..727c21ac87 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/AsynchronousMessageBusTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/AsynchronousMessageBusTests.cs @@ -10,14 +10,10 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class AsynchronousMessageBusTests : TestBase +[TestClass] +public sealed class AsynchronousMessageBusTests { - public AsynchronousMessageBusTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public async Task UnexpectedTypePublished_ShouldFail() { MessageBusProxy proxy = new(); @@ -37,6 +33,7 @@ public async Task UnexpectedTypePublished_ShouldFail() await Assert.ThrowsAsync(proxy.DrainDataAsync); } + [TestMethod] public async Task DrainDataAsync_Loop_ShouldFail() { MessageBusProxy proxy = new(); @@ -59,7 +56,7 @@ public async Task DrainDataAsync_Loop_ShouldFail() } catch (InvalidOperationException ex) { - Assert.That(ex.Message.Contains("Publisher/Consumer loop detected during the drain after")); + StringAssert.Contains(ex.Message, "Publisher/Consumer loop detected during the drain after"); } // Prevent loop to continue @@ -67,6 +64,7 @@ public async Task DrainDataAsync_Loop_ShouldFail() consumerB.StopConsume(); } + [TestMethod] public async Task MessageBus_WhenConsumerProducesAndConsumesTheSameType_ShouldNotConsumeWhatProducedByItself() { MessageBusProxy proxy = new(); @@ -90,13 +88,14 @@ public async Task MessageBus_WhenConsumerProducesAndConsumesTheSameType_ShouldNo await proxy.DrainDataAsync(); // assert - Assert.AreEqual(consumerA.ConsumedData.Count, 1); - Assert.AreEqual(consumerA.ConsumedData[0], consumerBData); + Assert.AreEqual(1, consumerA.ConsumedData.Count); + Assert.AreEqual(consumerBData, consumerA.ConsumedData[0]); - Assert.AreEqual(consumerB.ConsumedData.Count, 1); - Assert.AreEqual(consumerB.ConsumedData[0], consumerAData); + Assert.AreEqual(1, consumerB.ConsumedData.Count); + Assert.AreEqual(consumerAData, consumerB.ConsumedData[0]); } + [TestMethod] public async Task Consumers_ConsumeData_ShouldNotMissAnyPayload() { int totalConsumers = Environment.ProcessorCount; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs index 0dfb5466ae..12f4ad6b23 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/PropertyBagTests.cs @@ -5,14 +5,10 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class PropertyBagTests : TestBase +[TestClass] +public sealed class PropertyBagTests { - public PropertyBagTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public void Ctors_CorrectlyInit() { PropertyBag property = new([new DummyProperty(), PassedTestNodeStateProperty.CachedInstance]); @@ -24,18 +20,21 @@ public void Ctors_CorrectlyInit() Assert.IsNotNull(property._property); } + [TestMethod] public void Ctors_With_WrongInit_ShouldFail() { - Assert.Throws(() => _ = new PropertyBag([new DummyProperty(), PassedTestNodeStateProperty.CachedInstance, PassedTestNodeStateProperty.CachedInstance])); - Assert.Throws(() => _ = new PropertyBag(new IProperty[] { new DummyProperty(), PassedTestNodeStateProperty.CachedInstance, PassedTestNodeStateProperty.CachedInstance }.AsEnumerable())); + Assert.ThrowsException(() => _ = new PropertyBag([new DummyProperty(), PassedTestNodeStateProperty.CachedInstance, PassedTestNodeStateProperty.CachedInstance])); + Assert.ThrowsException(() => _ = new PropertyBag(new IProperty[] { new DummyProperty(), PassedTestNodeStateProperty.CachedInstance, PassedTestNodeStateProperty.CachedInstance }.AsEnumerable())); } + [TestMethod] public void Counts_ShouldBe_Correct() { PropertyBag property = new([new DummyProperty(), new DummyProperty(), PassedTestNodeStateProperty.CachedInstance]); Assert.AreEqual(3, property.Count); } + [TestMethod] public void AddGet_Of_TestNodeStateProperty_Succed() { PropertyBag property = new(); @@ -51,21 +50,24 @@ public void AddGet_Of_TestNodeStateProperty_Succed() Assert.AreEqual(1, property.OfType().Length); } + [TestMethod] public void Add_Of_TestNodeStateProperty_More_Than_One_Time_Fail() { PropertyBag property = new(); property.Add(PassedTestNodeStateProperty.CachedInstance); - Assert.Throws(() => property.Add(PassedTestNodeStateProperty.CachedInstance)); + Assert.ThrowsException(() => property.Add(PassedTestNodeStateProperty.CachedInstance)); } + [TestMethod] public void Add_Same_Instance_More_Times_Fail() { PropertyBag property = new(); DummyProperty dummyProperty = new(); property.Add(dummyProperty); - Assert.Throws(() => property.Add(dummyProperty)); + Assert.ThrowsException(() => property.Add(dummyProperty)); } + [TestMethod] public void Any_Should_Return_CorrectBoolean() { PropertyBag property = new(); @@ -77,6 +79,7 @@ public void Any_Should_Return_CorrectBoolean() Assert.IsTrue(property.Any()); } + [TestMethod] public void SingleOrDefault_Should_Return_CorrectObject() { PropertyBag property = new(); @@ -89,9 +92,10 @@ public void SingleOrDefault_Should_Return_CorrectObject() Assert.IsNull(property.SingleOrDefault()); property.Add(new DummyProperty()); - Assert.Throws(() => property.SingleOrDefault()); + Assert.ThrowsException(property.SingleOrDefault); } + [TestMethod] public void Single_Should_Return_CorrectObject() { PropertyBag property = new(); @@ -101,12 +105,13 @@ public void Single_Should_Return_CorrectObject() Assert.AreEqual(PassedTestNodeStateProperty.CachedInstance, property.Single()); Assert.AreEqual(prop, property.Single()); - Assert.Throws(() => property.Single()); + Assert.ThrowsException(property.Single); property.Add(new DummyProperty()); - Assert.Throws(() => property.Single()); + Assert.ThrowsException(property.Single); } + [TestMethod] public void OfType_Should_Return_CorrectObject() { PropertyBag property = new(); @@ -118,6 +123,7 @@ public void OfType_Should_Return_CorrectObject() Assert.AreEqual(2, property.OfType().Length); } + [TestMethod] public void AsEnumerable_Should_Return_CorrectItems() { PropertyBag property = new(); @@ -135,7 +141,7 @@ public void AsEnumerable_Should_Return_CorrectItems() list.Remove(prop); } - Assert.IsEmpty(list); + Assert.AreEqual(0, list.Count); list = property.AsEnumerable().ToList(); foreach (IProperty prop in property) @@ -143,16 +149,17 @@ public void AsEnumerable_Should_Return_CorrectItems() list.Remove(prop); } - Assert.IsEmpty(list); + Assert.AreEqual(0, list.Count); } + [TestMethod] public void EmptyProperties_Should_NotFail() { PropertyBag property = new(); Assert.AreEqual(0, property.Count); Assert.IsFalse(property.Any()); Assert.IsNull(property.SingleOrDefault()); - Assert.Throws(() => property.Single()); + Assert.ThrowsException(property.Single); Assert.AreEqual(0, property.OfType().Length); Assert.AreEqual(0, property.AsEnumerable().Count()); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/TestNodeUidTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/TestNodeUidTests.cs index 10d6c1827e..6a57d3b664 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/TestNodeUidTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/TestNodeUidTests.cs @@ -1,47 +1,39 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using FrameworkTestNodeUid = Microsoft.Testing.Internal.Framework.TestNodeUid; - using TestNodeUid = Microsoft.Testing.Platform.Extensions.Messages.TestNodeUid; namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class TestNodeUidTests : TestBase +[TestClass] +public sealed class TestNodeUidTests { - public TestNodeUidTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public void TestNodeUid_EqualityChecks_ShouldWorkAsExpected() { TestNodeUid testNodeUid = "TestNodeUid"; string testNodeUidString = testNodeUid; Assert.AreEqual(new TestNodeUid("TestNodeUid"), testNodeUid); - Assert.IsTrue(new FrameworkTestNodeUid("TestNodeUid") == "TestNodeUid"); - Assert.IsTrue(testNodeUid == "TestNodeUid"); - Assert.IsTrue(testNodeUid != "TestNodeUid2"); - Assert.IsTrue(testNodeUidString == testNodeUid); + Assert.AreEqual("TestNodeUid", testNodeUid); + Assert.AreNotEqual("TestNodeUid2", testNodeUid); + Assert.AreEqual(testNodeUidString, testNodeUid); } + [TestMethod] public void TestNodeUid_NullValue_ShouldFail() { -#pragma warning disable CS0219 // Variable is assigned but its value is never used // This won't fail, TestNodeUid is a record (not a record struct) and assigning null is a compile time check // not a runtime check. No construction of the object is happening, so we won't throw. // Assert.Throw(() => { TestNodeUid testNode = null!; }); // Implicit conversion from a null, empty or whitespace string should throw. - Assert.Throws(() => { TestNodeUid testNode = (string)null!; }); - Assert.Throws(() => { TestNodeUid testNode = string.Empty; }); - Assert.Throws(() => { TestNodeUid testNode = " "; }); + Assert.ThrowsException(() => { TestNodeUid testNode = (string)null!; }); + Assert.ThrowsException(() => { TestNodeUid testNode = string.Empty; }); + Assert.ThrowsException(() => { TestNodeUid testNode = " "; }); // Providing null, empty, or whitespace id should throw. - Assert.Throws(() => { TestNodeUid testNode = new(null!); }); - Assert.Throws(() => { TestNodeUid testNode = new(string.Empty); }); - Assert.Throws(() => { TestNodeUid testNode = new(" "); }); -#pragma warning restore CS0219 // Variable is assigned but its value is never used + Assert.ThrowsException(() => { TestNodeUid testNode = new(null!); }); + Assert.ThrowsException(() => { TestNodeUid testNode = new(string.Empty); }); + Assert.ThrowsException(() => { TestNodeUid testNode = new(" "); }); } } diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Microsoft.Testing.Platform.UnitTests.csproj b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Microsoft.Testing.Platform.UnitTests.csproj index 5ff2e65fc9..770d8063a6 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Microsoft.Testing.Platform.UnitTests.csproj +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Microsoft.Testing.Platform.UnitTests.csproj @@ -1,9 +1,9 @@ - + $(MicrosoftTestingTargetFrameworks);net462 false - true + true Exe @@ -21,10 +21,6 @@ - - - - diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TargetFrameworkParserTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TargetFrameworkParserTests.cs index 1f3ac7a5b2..d597da8847 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TargetFrameworkParserTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TargetFrameworkParserTests.cs @@ -5,37 +5,35 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class TargetFrameworkParserTests : TestBase +[TestClass] +public sealed class TargetFrameworkParserTests { - public TargetFrameworkParserTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - // known 2 digit versions - [Arguments(".NET Framework 4.7.0", "net47")] - [Arguments(".NET Framework 4.8.0", "net48")] + [DataRow(".NET Framework 4.7.0", "net47")] + [DataRow(".NET Framework 4.8.0", "net48")] // known 3 digit versions - [Arguments(".NET Framework 4.6.2", "net462")] - [Arguments(".NET Framework 4.7.1", "net471")] - [Arguments(".NET Framework 4.7.2", "net472")] - [Arguments(".NET Framework 4.8.1", "net481")] + [DataRow(".NET Framework 4.6.2", "net462")] + [DataRow(".NET Framework 4.7.1", "net471")] + [DataRow(".NET Framework 4.7.2", "net472")] + [DataRow(".NET Framework 4.8.1", "net481")] // other - [Arguments(".NET Framework 4.6.3", "net46")] - [Arguments(".NET Framework 4.8.9", "net48")] + [DataRow(".NET Framework 4.6.3", "net46")] + [DataRow(".NET Framework 4.8.9", "net48")] + [TestMethod] public void ParseNETFramework(string longName, string expectedShortName) => Assert.AreEqual(expectedShortName, TargetFrameworkParser.GetShortTargetFramework(longName)); - [Arguments(".NET Core 3.1.0", "netcoreapp3.1")] + [DataRow(".NET Core 3.1.0", "netcoreapp3.1")] + [TestMethod] public void ParseNETCore(string longName, string expectedShortName) => Assert.AreEqual(expectedShortName, TargetFrameworkParser.GetShortTargetFramework(longName)); - [Arguments(".NET 6.0.0", "net6.0")] - [Arguments(".NET 8.0.0", "net8.0")] - [Arguments(".NET 10.0.0", "net10.0")] + [DataRow(".NET 6.0.0", "net6.0")] + [DataRow(".NET 8.0.0", "net8.0")] + [DataRow(".NET 10.0.0", "net10.0")] + [TestMethod] public void ParseNET(string longName, string expectedShortName) => Assert.AreEqual(expectedShortName, TargetFrameworkParser.GetShortTargetFramework(longName)); } diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs index d7bbe0f104..221fb03524 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs @@ -9,14 +9,10 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class TerminalTestReporterTests : TestBase +[TestClass] +public sealed class TerminalTestReporterTests { - public TerminalTestReporterTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public void AppendStackFrameFormatsStackTraceLineCorrectly() { var terminal = new StringBuilderTerminal(); @@ -34,30 +30,31 @@ public void AppendStackFrameFormatsStackTraceLineCorrectly() TerminalTestReporter.AppendStackFrame(terminal, firstStackTraceLine); #if NETCOREAPP - Assert.Contains(" at Microsoft.Testing.Platform.UnitTests.TerminalTestReporterTests.AppendStackFrameFormatsStackTraceLineCorrectly() in ", terminal.Output); + StringAssert.Contains(terminal.Output, " at Microsoft.Testing.Platform.UnitTests.TerminalTestReporterTests.AppendStackFrameFormatsStackTraceLineCorrectly() in "); #else - Assert.Contains(" at Microsoft.Testing.Platform.UnitTests.TerminalTestReporterTests.AppendStackFrameFormatsStackTraceLineCorrectly()", terminal.Output); + StringAssert.Contains(terminal.Output, " at Microsoft.Testing.Platform.UnitTests.TerminalTestReporterTests.AppendStackFrameFormatsStackTraceLineCorrectly()"); #endif // Line number without the respective file - Assert.That(!terminal.Output.ToString().Contains(" :0")); + Assert.IsFalse(terminal.Output.ToString().Contains(" :0")); } // Code with line when we have symbols - [Arguments( + [DataRow( " at TestingPlatformEntryPoint.Main(String[]) in /_/TUnit.TestProject/obj/Release/net8.0/osx-x64/TestPlatformEntryPoint.cs:line 16", $" at TestingPlatformEntryPoint.Main(String[]) in /_/TUnit.TestProject/obj/Release/net8.0/osx-x64/TestPlatformEntryPoint.cs:16")] // code without line when we don't have symbols - [Arguments( + [DataRow( " at TestingPlatformEntryPoint.
(String[])", " at TestingPlatformEntryPoint.
(String[])")] // stack trace when published as NativeAOT - [Arguments( + [DataRow( " at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d", " at BenchmarkTest.ExceptionThrower.d__2.MoveNext() + 0x9d")] // spanners that we want to keep, to not lose information - [Arguments( + [DataRow( "--- End of stack trace from previous location ---", " --- End of stack trace from previous location ---")] + [TestMethod] public void StackTraceRegexCapturesLines(string stackTraceLine, string expected) { var terminal = new StringBuilderTerminal(); @@ -69,6 +66,7 @@ public void StackTraceRegexCapturesLines(string stackTraceLine, string expected) Assert.AreEqual(expected, terminal.Output); } + [TestMethod] public void OutputFormattingIsCorrect() { var stringBuilderConsole = new StringBuilderConsole(); @@ -167,6 +165,7 @@ Oh no! Assert.AreEqual(expected, ShowEscape(output)); } + [TestMethod] public void OutputProgressFrameIsCorrect() { var stringBuilderConsole = new StringBuilderConsole(); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs index 3c5b97f952..ee46862285 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs @@ -1,10 +1,12 @@ // 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.Diagnostics; +using System.Reflection; using Microsoft.Testing.Extensions; -using Microsoft.Testing.Internal.Framework.Configurations; + +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] +[assembly: ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] // Opt-out telemetry Environment.SetEnvironmentVariable("DOTNET_CLI_TELEMETRY_OPTOUT", "1"); @@ -12,7 +14,8 @@ // DebuggerUtility.AttachVSToCurrentProcess(); ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); -builder.AddTestFramework(new TestFrameworkConfiguration(Debugger.IsAttached ? 1 : Environment.ProcessorCount), new Microsoft.Testing.Platform.UnitTests.SourceGeneratedTestNodesBuilder()); +builder.AddMSTest(() => [Assembly.GetEntryAssembly()!]); + #if ENABLE_CODECOVERAGE builder.AddCodeCoverageProvider(); #endif diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Properties/launchSettings.json b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Properties/launchSettings.json index f90979f3cd..3fcf329603 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Properties/launchSettings.json +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Microsoft.Testing.Platform.UnitTests": { "commandName": "Project", - "commandLineArgs": "--treenode-filter /*/*/*/**", + "commandLineArgs": "", "environmentVariables": { //"TESTINGPLATFORM_HOTRELOAD_ENABLED": "1" } diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs index 49523583b0..facd2f354b 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs @@ -7,14 +7,10 @@ #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class TreeNodeFilterTests : TestBase +[TestClass] +public sealed class TreeNodeFilterTests { - public TreeNodeFilterTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public void MatchAllFilter_MatchesAnyPath() { TreeNodeFilter filter = new("/**"); @@ -22,16 +18,20 @@ public void MatchAllFilter_MatchesAnyPath() Assert.IsTrue(filter.MatchesFilter("/Path/Of/The/Test", new PropertyBag())); } + [TestMethod] public void MatchAllFilter_MatchesSubpaths() { TreeNodeFilter filter = new("/Path/**"); Assert.IsTrue(filter.MatchesFilter("/Path/Of/The/Test", new PropertyBag())); } - public void MatchAllFilter_Invalid() => Assert.Throws(() => _ = new TreeNodeFilter("/A(&B)")); + [TestMethod] + public void MatchAllFilter_Invalid() => Assert.ThrowsException(() => _ = new TreeNodeFilter("/A(&B)")); - public void MatchAllFilter_DoNotAllowInMiddleOfFilter() => Assert.Throws(() => _ = new TreeNodeFilter("/**/Path")); + [TestMethod] + public void MatchAllFilter_DoNotAllowInMiddleOfFilter() => Assert.ThrowsException(() => _ = new TreeNodeFilter("/**/Path")); + [TestMethod] public void MatchWildcard_MatchesSubstrings() { TreeNodeFilter filter = new("/*.UnitTests"); @@ -40,6 +40,7 @@ public void MatchWildcard_MatchesSubstrings() Assert.IsFalse(filter.MatchesFilter("/ProjectB.FunctionalTests", new PropertyBag())); } + [TestMethod] public void EscapeSequences_SupportsWildcard() { TreeNodeFilter filter = new("/*.\\*UnitTests"); @@ -48,6 +49,7 @@ public void EscapeSequences_SupportsWildcard() Assert.IsFalse(filter.MatchesFilter("/ProjectB.AUnitTests", new PropertyBag())); } + [TestMethod] public void EscapeSequences_SupportsParentheses() { TreeNodeFilter filter = new("/*.\\(UnitTests\\)"); @@ -56,8 +58,10 @@ public void EscapeSequences_SupportsParentheses() Assert.IsFalse(filter.MatchesFilter("/ProjectB.(UnitTests", new PropertyBag())); } - public void EscapeSequences_ThrowsIfLastCharIsAnEscapeChar() => Assert.Throws(() => _ = new TreeNodeFilter("/*.\\(UnitTests\\)\\")); + [TestMethod] + public void EscapeSequences_ThrowsIfLastCharIsAnEscapeChar() => Assert.ThrowsException(() => _ = new TreeNodeFilter("/*.\\(UnitTests\\)\\")); + [TestMethod] public void OrExpression_WorksForLiteralStrings() { TreeNodeFilter filter = new("/A|B"); @@ -66,6 +70,7 @@ public void OrExpression_WorksForLiteralStrings() Assert.IsFalse(filter.MatchesFilter("/C", new PropertyBag())); } + [TestMethod] public void AndExpression() { TreeNodeFilter filter = new("/(*.UnitTests)&(*ProjectB*)"); @@ -75,6 +80,7 @@ public void AndExpression() Assert.IsFalse(filter.MatchesFilter("/ProjectC.UnitTests.SomeExtension", new PropertyBag())); } + [TestMethod] public void Parentheses_EnsuresOrdering() { TreeNodeFilter filter = new("/((*.UnitTests)&(*ProjectB*))|C"); @@ -86,8 +92,11 @@ public void Parentheses_EnsuresOrdering() Assert.IsFalse(filter.MatchesFilter("/C.UnitTests", new PropertyBag())); } - public void Parenthesis_DisallowSeparatorInside() => Assert.Throws(() => _ = new TreeNodeFilter("/(A/B)")); + [TestMethod] + public void Parenthesis_DisallowSeparatorInside() + => Assert.ThrowsException(() => new TreeNodeFilter("/(A/B)")); + [TestMethod] public void Parameters_PropertyCheck() { TreeNodeFilter filter = new("/*.UnitTests[Tag=Fast]"); @@ -96,18 +105,27 @@ public void Parameters_PropertyCheck() Assert.IsFalse(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag())); } - public void Parameters_DisallowAtStart() => Assert.Throws(() => _ = new TreeNodeFilter("/[Tag=Fast]")); + [TestMethod] + public void Parameters_DisallowAtStart() + => Assert.ThrowsException(() => _ = new TreeNodeFilter("/[Tag=Fast]")); - public void Parameters_DisallowEmpty() => Assert.Throws(() => _ = new TreeNodeFilter("/Path[]")); + [TestMethod] + public void Parameters_DisallowEmpty() + => Assert.ThrowsException(() => _ = new TreeNodeFilter("/Path[]")); - public void Parameters_DisallowMultiple() => Assert.Throws(() => _ = new TreeNodeFilter("/Path[Prop=2][Prop=B]")); + [TestMethod] + public void Parameters_DisallowMultiple() + => Assert.ThrowsException(() => _ = new TreeNodeFilter("/Path[Prop=2][Prop=B]")); - public void Parameters_DisallowNested() => Assert.Throws(() => _ = new TreeNodeFilter("/Path[X=[Y=1]]")); + [TestMethod] + public void Parameters_DisallowNested() + => Assert.ThrowsException(() => _ = new TreeNodeFilter("/Path[X=[Y=1]]")); - [Arguments("/A/B", "/A/B", true)] - [Arguments("/A/B", "/A%2FB", false)] - [Arguments("/A%2FB", "/A/B", false)] - [Arguments("/A%2FB", "/A%2FB", true)] + [DataRow("/A/B", "/A/B", true)] + [DataRow("/A/B", "/A%2FB", false)] + [DataRow("/A%2FB", "/A/B", false)] + [DataRow("/A%2FB", "/A%2FB", true)] + [TestMethod] public void TestNodeFilterNeedsUrlEncodingOfSlashes(string filter, string nodePath, bool isMatched) { TreeNodeFilter filterInstance = new(filter); @@ -123,14 +141,15 @@ public void TestNodeFilterNeedsUrlEncodingOfSlashes(string filter, string nodePa } } - [Arguments("/A/B[ValueWithSlash=Some/thing]", "/A/B", true)] - [Arguments("/A/B[ValueWithSlash=Some%2Fthing]", "/A/B", false)] - [Arguments("/A/B[Other/thing=KeyWithSlash]", "/A/B", true)] - [Arguments("/A/B[Other%2Fthing=KeyWithSlash]", "/A/B", false)] - [Arguments("/A%2FB[ValueWithSlash=Some/thing]", "/A%2FB", true)] - [Arguments("/A%2FB[ValueWithSlash=Some%2Fthing]", "/A%2FB", false)] - [Arguments("/A%2FB[Other/thing=KeyWithSlash]", "/A%2FB", true)] - [Arguments("/A%2FB[Other%2Fthing=KeyWithSlash]", "/A%2FB", false)] + [DataRow("/A/B[ValueWithSlash=Some/thing]", "/A/B", true)] + [DataRow("/A/B[ValueWithSlash=Some%2Fthing]", "/A/B", false)] + [DataRow("/A/B[Other/thing=KeyWithSlash]", "/A/B", true)] + [DataRow("/A/B[Other%2Fthing=KeyWithSlash]", "/A/B", false)] + [DataRow("/A%2FB[ValueWithSlash=Some/thing]", "/A%2FB", true)] + [DataRow("/A%2FB[ValueWithSlash=Some%2Fthing]", "/A%2FB", false)] + [DataRow("/A%2FB[Other/thing=KeyWithSlash]", "/A%2FB", true)] + [DataRow("/A%2FB[Other%2Fthing=KeyWithSlash]", "/A%2FB", false)] + [TestMethod] public void PropertiesDoNotNeedUrlEncodingOfSlashes(string filter, string nodePath, bool isMatched) { TreeNodeFilter filterInstance = new(filter); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs index 67cdcf857f..5f7440bc80 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs @@ -3,6 +3,8 @@ #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. +using System.Reflection; + using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.ServerMode; @@ -11,19 +13,23 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class FormatterUtilitiesTests : TestBase +[TestClass] +public sealed class FormatterUtilitiesTests { private readonly IMessageFormatter _formatter = FormatterUtilities.CreateFormatter(); - public FormatterUtilitiesTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) => + public static IEnumerable SerializerTypesForDynamicData + => SerializerUtilities.SerializerTypes.Select(x => new object[] { x }); + + public FormatterUtilitiesTests() + => #if NETCOREAPP Assert.AreEqual("System.Text.Json", _formatter.Id); #else Assert.AreEqual("Jsonite", _formatter.Id); #endif + [TestMethod] public void CanDeserializeTaskResponse() { #pragma warning disable SA1009 // Closing parenthesis should be spaced correctly @@ -44,11 +50,11 @@ public void CanDeserializeTaskResponse() var response = (ResponseMessage)msg; Assert.AreEqual(1, response.Id); - Assert.AreEqual(null, response.Result); + Assert.IsNull(response.Result); } - [ArgumentsProvider(memberName: nameof(SerializerUtilities.SerializerTypes), memberType: typeof(SerializerUtilities), - TestArgumentsEntryProviderMethodName = nameof(FormatSerializerTypes))] + [DynamicData(nameof(SerializerTypesForDynamicData), DynamicDataDisplayName = nameof(FormatSerializerTypes))] + [TestMethod] public async Task SerializeDeserialize_Succeed(Type type) { object instanceToSerialize = CreateInstance(type); @@ -71,8 +77,9 @@ public async Task SerializeDeserialize_Succeed(Type type) static bool HasCustomDeserializeAssert(Type type) => type == typeof(TestNode); } - [Arguments(typeof(DiscoverRequestArgs))] - [Arguments(typeof(RunRequestArgs))] + [DataRow(typeof(DiscoverRequestArgs))] + [DataRow(typeof(RunRequestArgs))] + [TestMethod] public void DeserializeSpecificTypes(Type type) { string json = CreateSerializedInstance(type); @@ -93,7 +100,7 @@ public void DeserializeSpecificTypes(Type type) } else { - Assert.AreEqual(actual, expected); + Assert.AreEqual(expected, actual); } } } @@ -127,7 +134,10 @@ private static void CustomAssert(Type type, object instanceDeserialized, object } } - internal static TestArgumentsEntry FormatSerializerTypes(TestArgumentsContext testArgumentsContext) => new((Type)testArgumentsContext.Arguments, ((Type)testArgumentsContext.Arguments).Name); + public static string? FormatSerializerTypes(MethodInfo methodInfo, object?[]? data) + => data is not null + ? (data[0] as Type)?.Name + : null; private static void AssertSerialize(Type type, string instanceSerialized) { diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/JsonTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/JsonTests.cs index bae1ad7d57..cfa9e68ac5 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/JsonTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/JsonTests.cs @@ -9,13 +9,12 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class JsonTests : TestBase +[TestClass] +public sealed class JsonTests { private readonly Json _json; - public JsonTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) + public JsonTests() { Dictionary serializers = new(); Dictionary deserializers = new(); @@ -36,6 +35,7 @@ public JsonTests(ITestExecutionContext testExecutionContext) _json = new Json(serializers, deserializers); } + [TestMethod] public async Task Serialize_TestNodeAsync() { // Arrange @@ -45,7 +45,7 @@ public async Task Serialize_TestNodeAsync() { DisplayName = "test", Properties = bag, - Uid = new Extensions.Messages.TestNodeUid("11111"), + Uid = new TestNodeUid("11111"), }; // Act @@ -55,6 +55,7 @@ public async Task Serialize_TestNodeAsync() Assert.AreEqual("""{"uid":"11111","display-name":"test","hello":"my friend","node-type":"group"}""", actual); } + [TestMethod] public async Task Serialize_Array() { // Arrange @@ -67,6 +68,7 @@ public async Task Serialize_Array() Assert.AreEqual("[1,2,3]", actual); } + [TestMethod] public async Task Serialize_DateTimeOffset() { // Arrange @@ -79,6 +81,7 @@ public async Task Serialize_DateTimeOffset() Assert.AreEqual("2023-01-01T01:01:01.0010000+00:00", actual.Trim('"')); } + [TestMethod] public async Task Serialize_ArrayOfObjects() { // Arrange @@ -113,6 +116,7 @@ public async Task Serialize_ArrayOfObjects() Assert.AreEqual("""[{"name":"Thomas","children":[{"name":"Ruth","children":null}]},[2],3]""", actual); } + [TestMethod] public void DeserializePerson() { // Arrange @@ -137,6 +141,7 @@ public void DeserializePerson() Assert.IsNull(actual.Children![0].Children); } + [TestMethod] public void DeserializePersonList() { // Arrange diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/JsoniteTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/JsoniteTests.cs index cee4678ebf..853256dc7f 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/JsoniteTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/JsoniteTests.cs @@ -3,14 +3,10 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class JsoniteTests : TestBase +[TestClass] +public sealed class JsoniteTests { - public JsoniteTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public void Serialize_DateTimeOffset() { #if !NETCOREAPP diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerDataConsumerServiceTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerDataConsumerServiceTests.cs index 71054ee0d7..e1703f6e8d 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerDataConsumerServiceTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerDataConsumerServiceTests.cs @@ -15,8 +15,8 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class ServerDataConsumerServiceTests : TestBase, IAsyncCleanable, IDisposable +[TestClass] +public sealed class ServerDataConsumerServiceTests : IDisposable { private readonly PerRequestServerDataConsumer _service; private readonly ServiceProvider _serviceProvider = new(); @@ -25,13 +25,13 @@ public sealed class ServerDataConsumerServiceTests : TestBase, IAsyncCleanable, private readonly Guid _runId = Guid.NewGuid(); - public ServerDataConsumerServiceTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) + public ServerDataConsumerServiceTests() { _serviceProvider.TryAddService(new PerRequestTestSessionContext(CancellationToken.None, CancellationToken.None)); _service = new PerRequestServerDataConsumer(_serviceProvider, _serverTestHost.Object, _runId, _task.Object); } + [TestMethod] public async Task ConsumeAsync_WithSessionFileArtifact() { SessionFileArtifact sessionFileArtifact = new(new SessionUid("1"), new FileInfo("file"), "name", "description"); @@ -55,6 +55,7 @@ public async Task ConsumeAsync_WithSessionFileArtifact() Assert.AreEqual(expected[0].Description, actual[0].Description); } + [TestMethod] public async Task ConsumeAsync_WithTestNodeUpdatedMessage() { TestNodeUpdateMessage testNode = new(new SessionUid("1"), new TestNode { Uid = new TestNodeUid("test()"), DisplayName = string.Empty }); @@ -66,6 +67,7 @@ public async Task ConsumeAsync_WithTestNodeUpdatedMessage() Assert.AreEqual(0, actual.Count); } + [TestMethod] public void PopulateTestNodeStatistics_WithMissingNodeType() { TestNodeUpdateMessage testNode = new(new SessionUid("1"), new TestNode { Uid = new TestNodeUid("test()"), DisplayName = string.Empty }); @@ -73,11 +75,12 @@ public void PopulateTestNodeStatistics_WithMissingNodeType() _service.PopulateTestNodeStatistics(testNode); TestNodeStatistics statistics = _service.GetTestNodeStatistics(); - Assert.AreEqual(statistics.TotalDiscoveredTests, 0); - Assert.AreEqual(statistics.TotalPassedTests, 0); - Assert.AreEqual(statistics.TotalFailedTests, 0); + Assert.AreEqual(0, statistics.TotalDiscoveredTests); + Assert.AreEqual(0, statistics.TotalPassedTests); + Assert.AreEqual(0, statistics.TotalFailedTests); } + [TestMethod] public void PopulateTestNodeStatistics_WithDuplicateDiscoveredEvents() { PropertyBag properties = new( @@ -89,11 +92,12 @@ public void PopulateTestNodeStatistics_WithDuplicateDiscoveredEvents() _service.PopulateTestNodeStatistics(testNode); TestNodeStatistics statistics = _service.GetTestNodeStatistics(); - Assert.AreEqual(statistics.TotalDiscoveredTests, 1); - Assert.AreEqual(statistics.TotalPassedTests, 0); - Assert.AreEqual(statistics.TotalFailedTests, 0); + Assert.AreEqual(1, statistics.TotalDiscoveredTests); + Assert.AreEqual(0, statistics.TotalPassedTests); + Assert.AreEqual(0, statistics.TotalFailedTests); } + [TestMethod] public void PopulateTestNodeStatistics_WithDiscoveredAndPassedEventsForSameUid() { PropertyBag properties = new( @@ -110,11 +114,12 @@ public void PopulateTestNodeStatistics_WithDiscoveredAndPassedEventsForSameUid() _service.PopulateTestNodeStatistics(otherTestNode); TestNodeStatistics statistics = _service.GetTestNodeStatistics(); - Assert.AreEqual(statistics.TotalDiscoveredTests, 1); - Assert.AreEqual(statistics.TotalPassedTests, 1); - Assert.AreEqual(statistics.TotalFailedTests, 0); + Assert.AreEqual(1, statistics.TotalDiscoveredTests); + Assert.AreEqual(1, statistics.TotalPassedTests); + Assert.AreEqual(0, statistics.TotalFailedTests); } + [TestMethod] public void PopulateTestNodeStatistics_WithDuplicatePassedEvents() { PropertyBag properties = new(PassedTestNodeStateProperty.CachedInstance); @@ -125,13 +130,14 @@ public void PopulateTestNodeStatistics_WithDuplicatePassedEvents() _service.PopulateTestNodeStatistics(testNode); TestNodeStatistics statistics = _service.GetTestNodeStatistics(); - Assert.AreEqual(statistics.TotalDiscoveredTests, 0); - Assert.AreEqual(statistics.TotalPassedTests, 1); - Assert.AreEqual(statistics.TotalFailedTests, 0); - Assert.AreEqual(statistics.TotalPassedRetries, 1); - Assert.AreEqual(statistics.TotalFailedRetries, 0); + Assert.AreEqual(0, statistics.TotalDiscoveredTests); + Assert.AreEqual(1, statistics.TotalPassedTests); + Assert.AreEqual(0, statistics.TotalFailedTests); + Assert.AreEqual(1, statistics.TotalPassedRetries); + Assert.AreEqual(0, statistics.TotalFailedRetries); } + [TestMethod] public void PopulateTestNodeStatistics_WithEventsForSameUid() { PropertyBag properties = new( @@ -148,13 +154,14 @@ public void PopulateTestNodeStatistics_WithEventsForSameUid() _service.PopulateTestNodeStatistics(otherTestNode); TestNodeStatistics statistics = _service.GetTestNodeStatistics(); - Assert.AreEqual(statistics.TotalDiscoveredTests, 0); - Assert.AreEqual(statistics.TotalPassedTests, 1); - Assert.AreEqual(statistics.TotalFailedTests, 0); - Assert.AreEqual(statistics.TotalPassedRetries, 1); - Assert.AreEqual(statistics.TotalFailedRetries, 0); + Assert.AreEqual(0, statistics.TotalDiscoveredTests); + Assert.AreEqual(1, statistics.TotalPassedTests); + Assert.AreEqual(0, statistics.TotalFailedTests); + Assert.AreEqual(1, statistics.TotalPassedRetries); + Assert.AreEqual(0, statistics.TotalFailedRetries); } + [TestMethod] public void PopulateTestNodeStatistics_WithEventsForDifferentUids() { PropertyBag properties = new( @@ -171,14 +178,15 @@ public void PopulateTestNodeStatistics_WithEventsForDifferentUids() _service.PopulateTestNodeStatistics(otherTestNode); TestNodeStatistics statistics = _service.GetTestNodeStatistics(); - Assert.AreEqual(statistics.TotalDiscoveredTests, 0); - Assert.AreEqual(statistics.TotalPassedTests, 1); - Assert.AreEqual(statistics.TotalFailedTests, 1); - Assert.AreEqual(statistics.TotalPassedRetries, 0); - Assert.AreEqual(statistics.TotalFailedRetries, 0); + Assert.AreEqual(0, statistics.TotalDiscoveredTests); + Assert.AreEqual(1, statistics.TotalPassedTests); + Assert.AreEqual(1, statistics.TotalFailedTests); + Assert.AreEqual(0, statistics.TotalPassedRetries); + Assert.AreEqual(0, statistics.TotalFailedRetries); } - public async Task CleanupAsync(CleanupContext context) + [TestCleanup] + public async Task CleanupAsync() { if (_service.GetIdleUpdateTaskAsync() is { } idleUpdateTaskAsync) { @@ -186,7 +194,7 @@ public async Task CleanupAsync(CleanupContext context) } } - public void Dispose() => _service.Dispose(); + void IDisposable.Dispose() => _service.Dispose(); private sealed class DataProducer : IDataProducer { diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs index ba16dad5dc..36f0db185d 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs @@ -15,11 +15,10 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public class ServerTests : TestBase +[TestClass] +public sealed class ServerTests { - public ServerTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) + public ServerTests() { if (IsHotReloadEnabled(new SystemEnvironment())) { @@ -30,6 +29,7 @@ public ServerTests(ITestExecutionContext testExecutionContext) private static bool IsHotReloadEnabled(SystemEnvironment environment) => environment.GetEnvironmentVariable(EnvironmentVariableConstants.DOTNET_WATCH) == "1" || environment.GetEnvironmentVariable(EnvironmentVariableConstants.TESTINGPLATFORM_HOTRELOAD_ENABLED) == "1"; + [TestMethod] public async Task ServerCanBeStartedAndAborted_TcpIp() => await RetryHelper.RetryAsync( async () => { @@ -51,6 +51,7 @@ public async Task ServerCanBeStartedAndAborted_TcpIp() => await RetryHelper.Retr Assert.AreEqual(ExitCodes.TestSessionAborted, await serverTask); }, 3, TimeSpan.FromSeconds(10)); + [TestMethod] public async Task ServerCanInitialize() { using var server = TcpServer.Create(); @@ -126,6 +127,7 @@ await WriteMessageAsync( Assert.AreEqual(0, result); } + [TestMethod] public async Task DiscoveryRequestCanBeCanceled() { using var server = TcpServer.Create(); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/ServiceProviderTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/ServiceProviderTests.cs index 2053169c0d..1ad71b8e80 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/ServiceProviderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/ServiceProviderTests.cs @@ -11,16 +11,12 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class ServiceProviderTests : TestBase +[TestClass] +public sealed class ServiceProviderTests { private readonly ServiceProvider _serviceProvider = new(); - public ServiceProviderTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public void GetService_InternalExtension_ShouldNotReturn() { _serviceProvider.AddService(new TestHostProcessLifetimeHandler()); @@ -39,6 +35,7 @@ public void GetService_InternalExtension_ShouldNotReturn() Assert.IsNull(_serviceProvider.GetService()); } + [TestMethod] public void GetServiceInternal_InternalExtension_ShouldReturn() { _serviceProvider.AddService(new TestHostProcessLifetimeHandler()); @@ -57,6 +54,7 @@ public void GetServiceInternal_InternalExtension_ShouldReturn() Assert.IsNotNull(_serviceProvider.GetServiceInternal()); } + [TestMethod] public void Clone_WithoutFilter_Succeeded() { _serviceProvider.AddService(new TestHostProcessLifetimeHandler()); @@ -74,6 +72,7 @@ public void Clone_WithoutFilter_Succeeded() } } + [TestMethod] public void Clone_WithFilter_Succeeded() { _serviceProvider.AddService(new TestHostProcessLifetimeHandler()); @@ -88,29 +87,37 @@ public void Clone_WithFilter_Succeeded() Assert.AreEqual(_serviceProvider.Services.ToArray()[0].GetType(), typeof(TestHostProcessLifetimeHandler)); } - public void AddService_TestFramework_ShouldFail() => _ = Assert.Throws(() => _serviceProvider.AddService(new TestFramework())); + [TestMethod] + public void AddService_TestFramework_ShouldFail() + => Assert.ThrowsException(() => _serviceProvider.AddService(new TestFramework())); - public void TryAddService_TestFramework_ShouldFail() => _ = Assert.Throws(() => _serviceProvider.TryAddService(new TestFramework())); + [TestMethod] + public void TryAddService_TestFramework_ShouldFail() + => Assert.ThrowsException(() => _serviceProvider.TryAddService(new TestFramework())); + [TestMethod] public void AddService_TestFramework_ShouldNotFail() { _serviceProvider.AllowTestAdapterFrameworkRegistration = true; _serviceProvider.AddService(new TestFramework()); } + [TestMethod] public void TryAddService_TestFramework_ShouldNotFail() { _serviceProvider.AllowTestAdapterFrameworkRegistration = true; _serviceProvider.TryAddService(new TestFramework()); } + [TestMethod] public void AddService_SameInstance_ShouldFail() { TestHostProcessLifetimeHandler instance = new(); _serviceProvider.AddService(instance); - _ = Assert.Throws(() => _serviceProvider.AddService(instance)); + _ = Assert.ThrowsException(() => _serviceProvider.AddService(instance)); } + [TestMethod] public void AddService_SameInstance_ShouldNotFail() { TestHostProcessLifetimeHandler instance = new(); @@ -118,13 +125,15 @@ public void AddService_SameInstance_ShouldNotFail() _serviceProvider.AddService(instance, throwIfSameInstanceExit: false); } + [TestMethod] public void AddServices_SameInstance_ShouldFail() { TestHostProcessLifetimeHandler instance = new(); _serviceProvider.AddServices([instance]); - _ = Assert.Throws(() => _serviceProvider.AddServices([instance])); + _ = Assert.ThrowsException(() => _serviceProvider.AddServices([instance])); } + [TestMethod] public void AddServices_SameInstance_ShouldNotFail() { TestHostProcessLifetimeHandler instance = new(); @@ -132,6 +141,7 @@ public void AddServices_SameInstance_ShouldNotFail() _serviceProvider.AddServices([instance], throwIfSameInstanceExit: false); } + [TestMethod] public void TryAddService_SameInstance_ShouldReturnFalse() { TestHostProcessLifetimeHandler instance = new(); @@ -139,6 +149,7 @@ public void TryAddService_SameInstance_ShouldReturnFalse() Assert.IsFalse(_serviceProvider.TryAddService(instance)); } + [TestMethod] public void GetServicesInternal_ExtensionMethod_InternalExtension_ShouldReturn() { _serviceProvider.AddService(new TestApplicationLifecycleCallbacks()); @@ -147,6 +158,7 @@ public void GetServicesInternal_ExtensionMethod_InternalExtension_ShouldReturn() Assert.AreEqual(2, _serviceProvider.GetServicesInternal().Count()); } + [TestMethod] public void GetServicesInternal_InternalExtension_ShouldNotReturn() { _serviceProvider.AddService(new TestApplicationLifecycleCallbacks()); @@ -155,6 +167,7 @@ public void GetServicesInternal_InternalExtension_ShouldNotReturn() Assert.AreEqual(0, _serviceProvider.GetServicesInternal(typeof(ITestApplicationLifecycleCallbacks), stopAtFirst: false, skipInternalOnlyExtensions: true).Count()); } + [TestMethod] public void GetServicesInternal_InternalExtension_ShouldReturn() { _serviceProvider.AddService(new TestApplicationLifecycleCallbacks()); @@ -163,6 +176,7 @@ public void GetServicesInternal_InternalExtension_ShouldReturn() Assert.AreEqual(2, _serviceProvider.GetServicesInternal(typeof(ITestApplicationLifecycleCallbacks), stopAtFirst: false, skipInternalOnlyExtensions: false).Count()); } + [TestMethod] public void GetServicesInternal_InternalExtension_FirstOnly_ShouldReturnOne() { _serviceProvider.AddService(new TestApplicationLifecycleCallbacks()); @@ -171,6 +185,7 @@ public void GetServicesInternal_InternalExtension_FirstOnly_ShouldReturnOne() Assert.AreEqual(1, _serviceProvider.GetServicesInternal(typeof(ITestApplicationLifecycleCallbacks), stopAtFirst: true, skipInternalOnlyExtensions: false).Count()); } + [TestMethod] public void GetServiceInternal_InternalExtension_ShouldReturnOne() { _serviceProvider.AddService(new TestApplicationLifecycleCallbacks()); @@ -179,7 +194,8 @@ public void GetServiceInternal_InternalExtension_ShouldReturnOne() Assert.IsNotNull(_serviceProvider.GetServiceInternal(typeof(ITestApplicationLifecycleCallbacks), skipInternalOnlyExtensions: false)); } - public void GetServiceInternal_InternalExtension_SkipInternalOnlyExtensios_ShouldReturnNull() + [TestMethod] + public void GetServiceInternal_InternalExtension_SkipInternalOnlyExtensions_ShouldReturnNull() { _serviceProvider.AddService(new TestApplicationLifecycleCallbacks()); _serviceProvider.AddService(new TestApplicationLifecycleCallbacks()); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs index 804d5aecf0..f16518ac06 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Services/TestApplicationResultTests.cs @@ -11,24 +11,20 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class TestApplicationResultTests : TestBase +[TestClass] +public sealed class TestApplicationResultTests { private readonly TestApplicationResult _testApplicationResult = new(new Mock().Object, new Mock().Object, new Mock().Object, new Mock().Object); - public TestApplicationResultTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - + [TestMethod] public async Task GetProcessExitCodeAsync_If_All_Skipped_Returns_ZeroTestsRan() { await _testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, - new Extensions.Messages.TestNode + new TestNode { - Uid = new Extensions.Messages.TestNodeUid("id"), + Uid = new TestNodeUid("id"), DisplayName = "DisplayName", Properties = new PropertyBag(SkippedTestNodeStateProperty.CachedInstance), }), CancellationToken.None); @@ -36,13 +32,14 @@ public async Task GetProcessExitCodeAsync_If_All_Skipped_Returns_ZeroTestsRan() Assert.AreEqual(ExitCodes.ZeroTests, _testApplicationResult.GetProcessExitCode()); } + [TestMethod] public async Task GetProcessExitCodeAsync_If_No_Tests_Ran_Returns_ZeroTestsRan() { await _testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, - new Extensions.Messages.TestNode + new TestNode { - Uid = new Extensions.Messages.TestNodeUid("id"), + Uid = new TestNodeUid("id"), DisplayName = "DisplayName", Properties = new PropertyBag(), }), CancellationToken.None); @@ -50,14 +47,15 @@ public async Task GetProcessExitCodeAsync_If_No_Tests_Ran_Returns_ZeroTestsRan() Assert.AreEqual(ExitCodes.ZeroTests, _testApplicationResult.GetProcessExitCode()); } - [ArgumentsProvider(nameof(FailedState))] + [TestMethod] + [DynamicData(nameof(FailedState), DynamicDataSourceType.Method)] public async Task GetProcessExitCodeAsync_If_Failed_Tests_Returns_AtLeastOneTestFailed(TestNodeStateProperty testNodeStateProperty) { await _testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, - new Extensions.Messages.TestNode + new TestNode { - Uid = new Extensions.Messages.TestNodeUid("id"), + Uid = new TestNodeUid("id"), DisplayName = "DisplayName", Properties = new PropertyBag(testNodeStateProperty), }), CancellationToken.None); @@ -65,6 +63,7 @@ public async Task GetProcessExitCodeAsync_If_Failed_Tests_Returns_AtLeastOneTest Assert.AreEqual(ExitCodes.AtLeastOneTestFailed, _testApplicationResult.GetProcessExitCode()); } + [TestMethod] public async Task GetProcessExitCodeAsync_If_Canceled_Returns_TestSessionAborted() { Mock testApplicationCancellationTokenSource = new(); @@ -82,9 +81,9 @@ TestApplicationResult testApplicationResult await testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, - new Extensions.Messages.TestNode + new TestNode { - Uid = new Extensions.Messages.TestNodeUid("id"), + Uid = new TestNodeUid("id"), DisplayName = "DisplayName", Properties = new PropertyBag(), }), CancellationToken.None); @@ -92,14 +91,15 @@ TestApplicationResult testApplicationResult Assert.AreEqual(ExitCodes.TestSessionAborted, testApplicationResult.GetProcessExitCode()); } + [TestMethod] public async Task GetProcessExitCodeAsync_If_TestAdapter_Returns_TestAdapterTestSessionFailure() { await _testApplicationResult.SetTestAdapterTestSessionFailureAsync("Adapter error"); await _testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, - new Extensions.Messages.TestNode + new TestNode { - Uid = new Extensions.Messages.TestNodeUid("id"), + Uid = new TestNodeUid("id"), DisplayName = "DisplayName", Properties = new PropertyBag(PassedTestNodeStateProperty.CachedInstance), }), CancellationToken.None); @@ -107,6 +107,7 @@ public async Task GetProcessExitCodeAsync_If_TestAdapter_Returns_TestAdapterTest Assert.AreEqual(ExitCodes.TestAdapterTestSessionFailure, _testApplicationResult.GetProcessExitCode()); } + [TestMethod] public async Task GetProcessExitCodeAsync_If_MinimumExpectedTests_Violated_Returns_MinimumExpectedTestsPolicyViolation() { TestApplicationResult testApplicationResult @@ -117,18 +118,18 @@ TestApplicationResult testApplicationResult await testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, - new Extensions.Messages.TestNode + new TestNode { - Uid = new Extensions.Messages.TestNodeUid("id"), + Uid = new TestNodeUid("id"), DisplayName = "DisplayName", Properties = new PropertyBag(PassedTestNodeStateProperty.CachedInstance), }), CancellationToken.None); await testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, - new Extensions.Messages.TestNode + new TestNode { - Uid = new Extensions.Messages.TestNodeUid("id"), + Uid = new TestNodeUid("id"), DisplayName = "DisplayName", Properties = new PropertyBag(InProgressTestNodeStateProperty.CachedInstance), }), CancellationToken.None); @@ -136,6 +137,7 @@ TestApplicationResult testApplicationResult Assert.AreEqual(ExitCodes.MinimumExpectedTestsPolicyViolation, testApplicationResult.GetProcessExitCode()); } + [TestMethod] public async Task GetProcessExitCodeAsync_OnDiscovery_No_Tests_Discovered_Returns_ZeroTests() { TestApplicationResult testApplicationResult @@ -146,15 +148,16 @@ TestApplicationResult testApplicationResult await testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, - new Extensions.Messages.TestNode + new TestNode { - Uid = new Extensions.Messages.TestNodeUid("id"), + Uid = new TestNodeUid("id"), DisplayName = "DisplayName", }), CancellationToken.None); Assert.AreEqual(ExitCodes.ZeroTests, testApplicationResult.GetProcessExitCode()); } + [TestMethod] public async Task GetProcessExitCodeAsync_OnDiscovery_Some_Tests_Discovered_Returns_Success() { TestApplicationResult testApplicationResult @@ -165,9 +168,9 @@ TestApplicationResult testApplicationResult await testApplicationResult.ConsumeAsync(new DummyProducer(), new TestNodeUpdateMessage( default, - new Extensions.Messages.TestNode + new TestNode { - Uid = new Extensions.Messages.TestNodeUid("id"), + Uid = new TestNodeUid("id"), DisplayName = "DisplayName", Properties = new PropertyBag(DiscoveredTestNodeStateProperty.CachedInstance), }), CancellationToken.None); @@ -175,17 +178,18 @@ TestApplicationResult testApplicationResult Assert.AreEqual(ExitCodes.Success, testApplicationResult.GetProcessExitCode()); } - [Arguments("8", ExitCodes.Success)] - [Arguments("8;2", ExitCodes.Success)] - [Arguments("8;", ExitCodes.Success)] - [Arguments("8;2;", ExitCodes.Success)] - [Arguments("5", ExitCodes.ZeroTests)] - [Arguments("5;7", ExitCodes.ZeroTests)] - [Arguments("5;", ExitCodes.ZeroTests)] - [Arguments("5;7;", ExitCodes.ZeroTests)] - [Arguments(";", ExitCodes.ZeroTests)] - [Arguments(null, ExitCodes.ZeroTests)] - [Arguments("", ExitCodes.ZeroTests)] + [DataRow("8", ExitCodes.Success)] + [DataRow("8;2", ExitCodes.Success)] + [DataRow("8;", ExitCodes.Success)] + [DataRow("8;2;", ExitCodes.Success)] + [DataRow("5", ExitCodes.ZeroTests)] + [DataRow("5;7", ExitCodes.ZeroTests)] + [DataRow("5;", ExitCodes.ZeroTests)] + [DataRow("5;7;", ExitCodes.ZeroTests)] + [DataRow(";", ExitCodes.ZeroTests)] + [DataRow(null, ExitCodes.ZeroTests)] + [DataRow("", ExitCodes.ZeroTests)] + [TestMethod] public void GetProcessExitCodeAsync_IgnoreExitCodes(string argument, int expectedExitCode) { Mock environment = new(); @@ -208,12 +212,12 @@ public void GetProcessExitCodeAsync_IgnoreExitCodes(string argument, int expecte } } - internal static IEnumerable FailedState() + internal static IEnumerable FailedState() { - yield return new FailedTestNodeStateProperty(); - yield return new ErrorTestNodeStateProperty(); - yield return new CancelledTestNodeStateProperty(); - yield return new TimeoutTestNodeStateProperty(); + yield return new[] { new FailedTestNodeStateProperty() }; + yield return new[] { new ErrorTestNodeStateProperty() }; + yield return new[] { new CancelledTestNodeStateProperty() }; + yield return new[] { new TimeoutTestNodeStateProperty() }; } private sealed class CommandLineOption : ICommandLineOptions diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Telemetry/ServerTelemetryTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Telemetry/ServerTelemetryTests.cs index dfee39ce9f..8b754df5a8 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Telemetry/ServerTelemetryTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Telemetry/ServerTelemetryTests.cs @@ -9,15 +9,16 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class ServerTelemetryTests : TestBase +[TestClass] +public sealed class ServerTelemetryTests { private readonly ServerTelemetry _serverTelemetry; private readonly Mock _serverTestHost = new(); - public ServerTelemetryTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) => _serverTelemetry = new(_serverTestHost.Object); + public ServerTelemetryTests() + => _serverTelemetry = new(_serverTestHost.Object); + [TestMethod] public async Task LogEvent_ForDiscovery() { Dictionary metadata = new() @@ -30,6 +31,7 @@ public async Task LogEvent_ForDiscovery() _serverTestHost.Verify(s => s.SendTelemetryEventUpdateAsync(new TelemetryEventArgs(TelemetryEvents.TestsDiscoveryEventName, metadata))); } + [TestMethod] public async Task LogEvent_ForRun() { Dictionary metadata = new() diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Telemetry/TelemetryManagerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Telemetry/TelemetryManagerTests.cs index d66cd424f7..475b900da2 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Telemetry/TelemetryManagerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Telemetry/TelemetryManagerTests.cs @@ -13,23 +13,19 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class TelemetryManagerTests : TestBase +[TestClass] +public sealed class TelemetryManagerTests { - public TelemetryManagerTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) - { - } - // When set to 1 or true it should suppress the message. - [Arguments(EnvironmentVariableConstants.TESTINGPLATFORM_NOBANNER, "1")] - [Arguments(EnvironmentVariableConstants.TESTINGPLATFORM_NOBANNER, "true")] - [Arguments(EnvironmentVariableConstants.DOTNET_NOLOGO, "1")] - [Arguments(EnvironmentVariableConstants.DOTNET_NOLOGO, "true")] + [DataRow(EnvironmentVariableConstants.TESTINGPLATFORM_NOBANNER, "1")] + [DataRow(EnvironmentVariableConstants.TESTINGPLATFORM_NOBANNER, "true")] + [DataRow(EnvironmentVariableConstants.DOTNET_NOLOGO, "1")] + [DataRow(EnvironmentVariableConstants.DOTNET_NOLOGO, "true")] // When set to 0 it should write the message. - [Arguments(EnvironmentVariableConstants.TESTINGPLATFORM_NOBANNER, "0")] - [Arguments(EnvironmentVariableConstants.DOTNET_NOLOGO, "0")] + [DataRow(EnvironmentVariableConstants.TESTINGPLATFORM_NOBANNER, "0")] + [DataRow(EnvironmentVariableConstants.DOTNET_NOLOGO, "0")] + [TestMethod] public async Task TelemetryManager_UsingNoLogoShouldSuppressTelemetryMessage(string variable, string value) { // Arrange @@ -75,14 +71,15 @@ public async Task TelemetryManager_UsingNoLogoShouldSuppressTelemetryMessage(str } // When set to 1 or true it should suppress the message. - [Arguments(EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT, "1")] - [Arguments(EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT, "true")] - [Arguments(EnvironmentVariableConstants.DOTNET_CLI_TELEMETRY_OPTOUT, "1")] - [Arguments(EnvironmentVariableConstants.DOTNET_CLI_TELEMETRY_OPTOUT, "true")] + [DataRow(EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT, "1")] + [DataRow(EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT, "true")] + [DataRow(EnvironmentVariableConstants.DOTNET_CLI_TELEMETRY_OPTOUT, "1")] + [DataRow(EnvironmentVariableConstants.DOTNET_CLI_TELEMETRY_OPTOUT, "true")] // When set to 0 it should write the message. - [Arguments(EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT, "0")] - [Arguments(EnvironmentVariableConstants.DOTNET_CLI_TELEMETRY_OPTOUT, "0")] + [DataRow(EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT, "0")] + [DataRow(EnvironmentVariableConstants.DOTNET_CLI_TELEMETRY_OPTOUT, "0")] + [TestMethod] public async Task TelemetryManager_UsingTelemetryOptOutShouldDisableTelemetry(string variable, string value) { // Arrange @@ -131,6 +128,7 @@ public async Task TelemetryManager_UsingTelemetryOptOutShouldDisableTelemetry(st } } + [TestMethod] public async Task TelemetryManager_SentinelIsWrittenPerUserAndAvoidsShowingNoticeOnSubsequentRuns() { // Arrange @@ -193,6 +191,7 @@ public async Task TelemetryManager_SentinelIsWrittenPerUserAndAvoidsShowingNotic fileSystemMock.Verify(f => f.NewFileStream(path, It.IsAny(), It.IsAny()), Times.Never); } + [TestMethod] public async Task TelemetryManager_SentinelIsWrittenOnlyWhenUserWouldSeeTheMessage() { // Arrange @@ -262,6 +261,7 @@ public async Task TelemetryManager_SentinelIsWrittenOnlyWhenUserWouldSeeTheMessa fileSystemMock.Verify(f => f.NewFileStream(path, It.IsAny(), It.IsAny()), Times.Once); } + [TestMethod] public async Task TelemetryManager_UsingNoBannerCommandLine_ShouldSuppressTelemetryMessage() { TestApplicationOptions options = new(); diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs index 0d58477da0..547f65e403 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs @@ -14,13 +14,12 @@ namespace Microsoft.Testing.Platform.UnitTests; -[TestGroup] -public sealed class TestApplicationBuilderTests : TestBase +[TestClass] +public sealed class TestApplicationBuilderTests { private readonly ServiceProvider _serviceProvider = new(); - public TestApplicationBuilderTests(ITestExecutionContext testExecutionContext) - : base(testExecutionContext) + public TestApplicationBuilderTests() { CurrentTestApplicationModuleInfo testApplicationModuleInfo = new(new SystemEnvironment(), new SystemProcessHandler()); AggregatedConfiguration configuration = new([], testApplicationModuleInfo, new SystemFileSystem()); @@ -29,55 +28,61 @@ public TestApplicationBuilderTests(ITestExecutionContext testExecutionContext) _serviceProvider.AddService(configuration); } + [TestMethod] public async Task TestApplicationLifecycleCallbacks_DuplicatedId_ShouldFail() { TestHostManager testHostManager = new(); testHostManager.AddTestApplicationLifecycleCallbacks(_ => new ApplicationLifecycleCallbacks("duplicatedId")); testHostManager.AddTestApplicationLifecycleCallbacks(_ => new ApplicationLifecycleCallbacks("duplicatedId")); - InvalidOperationException invalidOperationException = await Assert.ThrowsAsync(() => testHostManager.BuildTestApplicationLifecycleCallbackAsync(_serviceProvider)); + InvalidOperationException invalidOperationException = await Assert.ThrowsExceptionAsync(() => testHostManager.BuildTestApplicationLifecycleCallbackAsync(_serviceProvider)); Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(ApplicationLifecycleCallbacks).ToString())); } + [TestMethod] public async Task DataConsumer_DuplicatedId_ShouldFail() { TestHostManager testHostManager = new(); testHostManager.AddDataConsumer(_ => new Consumer("duplicatedId")); testHostManager.AddDataConsumer(_ => new Consumer("duplicatedId")); - InvalidOperationException invalidOperationException = await Assert.ThrowsAsync(() => testHostManager.BuildDataConsumersAsync(_serviceProvider, [])); + InvalidOperationException invalidOperationException = await Assert.ThrowsExceptionAsync(() => testHostManager.BuildDataConsumersAsync(_serviceProvider, [])); Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(Consumer).ToString())); } + [TestMethod] public async Task DataConsumer_DuplicatedIdWithCompositeFactory_ShouldFail() { TestHostManager testHostManager = new(); CompositeExtensionFactory compositeExtensionFactory = new(() => new Consumer("duplicatedId")); testHostManager.AddDataConsumer(_ => new Consumer("duplicatedId")); testHostManager.AddDataConsumer(compositeExtensionFactory); - InvalidOperationException invalidOperationException = await Assert.ThrowsAsync(() => testHostManager.BuildDataConsumersAsync(_serviceProvider, [])); + InvalidOperationException invalidOperationException = await Assert.ThrowsExceptionAsync(() => testHostManager.BuildDataConsumersAsync(_serviceProvider, [])); Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(Consumer).ToString())); } + [TestMethod] public async Task TestSessionLifetimeHandle_DuplicatedId_ShouldFail() { TestHostManager testHostManager = new(); testHostManager.AddTestSessionLifetimeHandle(_ => new TestSessionLifetimeHandler("duplicatedId")); testHostManager.AddTestSessionLifetimeHandle(_ => new TestSessionLifetimeHandler("duplicatedId")); - InvalidOperationException invalidOperationException = await Assert.ThrowsAsync(() => testHostManager.BuildTestSessionLifetimeHandleAsync(_serviceProvider, [])); + InvalidOperationException invalidOperationException = await Assert.ThrowsExceptionAsync(() => testHostManager.BuildTestSessionLifetimeHandleAsync(_serviceProvider, [])); Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(TestSessionLifetimeHandler).ToString())); } + [TestMethod] public async Task TestSessionLifetimeHandle_DuplicatedIdWithCompositeFactory_ShouldFail() { TestHostManager testHostManager = new(); CompositeExtensionFactory compositeExtensionFactory = new(() => new TestSessionLifetimeHandler("duplicatedId")); testHostManager.AddTestSessionLifetimeHandle(_ => new TestSessionLifetimeHandler("duplicatedId")); testHostManager.AddTestSessionLifetimeHandle(compositeExtensionFactory); - InvalidOperationException invalidOperationException = await Assert.ThrowsAsync(() => testHostManager.BuildTestSessionLifetimeHandleAsync(_serviceProvider, [])); + InvalidOperationException invalidOperationException = await Assert.ThrowsExceptionAsync(() => testHostManager.BuildTestSessionLifetimeHandleAsync(_serviceProvider, [])); Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(TestSessionLifetimeHandler).ToString())); } - [Arguments(true)] - [Arguments(false)] + [DataRow(true)] + [DataRow(false)] + [TestMethod] public async Task TestHost_ComposeFactory_ShouldSucceed(bool withParameter) { TestHostManager testHostManager = new(); @@ -96,46 +101,51 @@ public async Task TestHost_ComposeFactory_ShouldSucceed(bool withParameter) Assert.AreEqual(compositeExtensions[0].GetInstance(), sessionLifetimeHandle[0]); } + [TestMethod] public async Task TestHostControllerEnvironmentVariableProvider_DuplicatedId_ShouldFail() { TestHostControllersManager testHostControllerManager = new(); testHostControllerManager.AddEnvironmentVariableProvider(_ => new TestHostEnvironmentVariableProvider("duplicatedId")); testHostControllerManager.AddEnvironmentVariableProvider(_ => new TestHostEnvironmentVariableProvider("duplicatedId")); - InvalidOperationException invalidOperationException = await Assert.ThrowsAsync(() => testHostControllerManager.BuildAsync(_serviceProvider)); + InvalidOperationException invalidOperationException = await Assert.ThrowsExceptionAsync(() => testHostControllerManager.BuildAsync(_serviceProvider)); Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(TestHostEnvironmentVariableProvider).ToString())); } + [TestMethod] public async Task TestHostControllerEnvironmentVariableProvider_DuplicatedIdWithCompositeFactory_ShouldFail() { TestHostControllersManager testHostControllerManager = new(); CompositeExtensionFactory compositeExtensionFactory = new(() => new TestHostEnvironmentVariableProvider("duplicatedId")); testHostControllerManager.AddEnvironmentVariableProvider(_ => new TestHostEnvironmentVariableProvider("duplicatedId")); testHostControllerManager.AddEnvironmentVariableProvider(compositeExtensionFactory); - InvalidOperationException invalidOperationException = await Assert.ThrowsAsync(() => testHostControllerManager.BuildAsync(_serviceProvider)); + InvalidOperationException invalidOperationException = await Assert.ThrowsExceptionAsync(() => testHostControllerManager.BuildAsync(_serviceProvider)); Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(TestHostEnvironmentVariableProvider).ToString())); } + [TestMethod] public async Task TestHostControllerProcessLifetimeHandler_DuplicatedId_ShouldFail() { TestHostControllersManager testHostControllerManager = new(); testHostControllerManager.AddProcessLifetimeHandler(_ => new TestHostProcessLifetimeHandler("duplicatedId")); testHostControllerManager.AddProcessLifetimeHandler(_ => new TestHostProcessLifetimeHandler("duplicatedId")); - InvalidOperationException invalidOperationException = await Assert.ThrowsAsync(() => testHostControllerManager.BuildAsync(_serviceProvider)); + InvalidOperationException invalidOperationException = await Assert.ThrowsExceptionAsync(() => testHostControllerManager.BuildAsync(_serviceProvider)); Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(TestHostProcessLifetimeHandler).ToString())); } + [TestMethod] public async Task TestHostControllerProcessLifetimeHandler_DuplicatedIdWithCompositeFactory_ShouldFail() { TestHostControllersManager testHostControllerManager = new(); CompositeExtensionFactory compositeExtensionFactory = new(() => new TestHostProcessLifetimeHandler("duplicatedId")); testHostControllerManager.AddProcessLifetimeHandler(_ => new TestHostProcessLifetimeHandler("duplicatedId")); testHostControllerManager.AddProcessLifetimeHandler(compositeExtensionFactory); - InvalidOperationException invalidOperationException = await Assert.ThrowsAsync(() => testHostControllerManager.BuildAsync(_serviceProvider)); + InvalidOperationException invalidOperationException = await Assert.ThrowsExceptionAsync(() => testHostControllerManager.BuildAsync(_serviceProvider)); Assert.IsTrue(invalidOperationException.Message.Contains("duplicatedId") && invalidOperationException.Message.Contains(typeof(TestHostProcessLifetimeHandler).ToString())); } - [Arguments(true)] - [Arguments(false)] + [DataRow(true)] + [DataRow(false)] + [TestMethod] public async Task TestHostController_ComposeFactory_ShouldSucceed(bool withParameter) { TestHostControllersManager testHostControllerManager = new(); @@ -154,15 +164,16 @@ public async Task TestHostController_ComposeFactory_ShouldSucceed(bool withParam Assert.AreEqual(((ICompositeExtensionFactory)compositeExtensionFactory).GetInstance(), configuration.EnvironmentVariableProviders[0]); } - [Arguments(true)] - [Arguments(false)] + [DataRow(true)] + [DataRow(false)] + [TestMethod] public void ComposeFactory_InvalidComposition_ShouldFail(bool withParameter) { CompositeExtensionFactory compositeExtensionFactory = withParameter ? new CompositeExtensionFactory(sp => new InvalidComposition(sp)) : new CompositeExtensionFactory(() => new InvalidComposition()); - InvalidOperationException invalidOperationException = Assert.Throws(() => ((ICompositeExtensionFactory)compositeExtensionFactory).GetInstance()); + InvalidOperationException invalidOperationException = Assert.ThrowsException(() => ((ICompositeExtensionFactory)compositeExtensionFactory).GetInstance()); Assert.AreEqual(CompositeExtensionFactory.ValidateCompositionErrorMessage, invalidOperationException.Message); } diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs index a4489f8b11..65c5414243 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs @@ -3,6 +3,9 @@ using System.Runtime.InteropServices; +// TODO: this should not be required +[assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] + namespace Microsoft.Testing.TestInfrastructure; public static class Constants diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/Microsoft.Testing.TestInfrastructure.csproj b/test/Utilities/Microsoft.Testing.TestInfrastructure/Microsoft.Testing.TestInfrastructure.csproj index 927d31caaf..ebff01df15 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/Microsoft.Testing.TestInfrastructure.csproj +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/Microsoft.Testing.TestInfrastructure.csproj @@ -1,4 +1,4 @@ - + $(MicrosoftTestingTargetFrameworks);netstandard2.0 @@ -7,18 +7,18 @@ - + + - - - + + diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/RetryHelper.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/RetryHelper.cs index c0261fca89..a2adaf6262 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/RetryHelper.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/RetryHelper.cs @@ -7,11 +7,13 @@ namespace Microsoft.Testing.TestInfrastructure; public class RetryHelper { - public static async Task RetryAsync(Func action, uint times, TimeSpan every, Func? predicate = null) => await Policy.Handle(exception => predicate is null || predicate(exception)) + public static async Task RetryAsync(Func action, uint times, TimeSpan every, Func? predicate = null) + => await Policy.Handle(exception => predicate is null || predicate(exception)) .WaitAndRetryAsync((int)times, _ => every) .ExecuteAsync(action); - public static async Task RetryAsync(Func> action, uint times, TimeSpan every, Func? predicate = null) => await Policy.Handle(exception => predicate is null || predicate(exception)) + public static async Task RetryAsync(Func> action, uint times, TimeSpan every, Func? predicate = null) + => await Policy.Handle(exception => predicate is null || predicate(exception)) .WaitAndRetryAsync((int)times, _ => every) .ExecuteAsync(action); } diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/SourceCodeExtensions.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/SourceCodeExtensions.cs index 88e502c555..afa810c240 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/SourceCodeExtensions.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/SourceCodeExtensions.cs @@ -1,8 +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 Microsoft.Testing.Internal.Framework; - namespace Microsoft.Testing.TestInfrastructure; public static class SourceCodeExtensions @@ -10,6 +8,6 @@ public static class SourceCodeExtensions public static string PatchCodeWithReplace(this string code, string pattern, string value) => code.Replace(pattern, value); - public static string PatchTargetFrameworks(this string code, params TestArgumentsEntry[] targetFrameworks) + public static string PatchTargetFrameworks(this string code, params string[] targetFrameworks) => PatchCodeWithReplace(code, "$TargetFrameworks$", targetFrameworks.ToMSBuildTargetFrameworks()); } diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs index f5bdc6d05e..58ec8a7d21 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs @@ -3,31 +3,35 @@ using System.Runtime.InteropServices; -using Microsoft.Testing.Internal.Framework; - namespace Microsoft.Testing.TestInfrastructure; public static class TargetFrameworks { - public static TestArgumentsEntry[] Net { get; } = + public static string[] Net { get; } = [ - new("net9.0", "net9.0"), + "net9.0", #if !SKIP_INTERMEDIATE_TARGET_FRAMEWORKS - new("net8.0", "net8.0"), - new("net7.0", "net7.0"), - new("net6.0", "net6.0"), + "net8.0", + "net7.0", + "net6.0", #endif ]; - public static TestArgumentsEntry NetCurrent { get; } = Net[0]; + public static IEnumerable NetForDynamicData { get; } = + Net.Select(tfm => new object[] { tfm }); + + public static string NetCurrent { get; } = Net[0]; - public static TestArgumentsEntry[] NetFramework { get; } = [new("net462", "net462")]; + public static string[] NetFramework { get; } = ["net462"]; - public static TestArgumentsEntry[] All { get; } + public static string[] All { get; } = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? Net.Concat(NetFramework).ToArray() : Net; - public static string ToMSBuildTargetFrameworks(this TestArgumentsEntry[] targetFrameworksEntries) - => string.Join(";", targetFrameworksEntries.Select(x => x.Arguments)); + public static IEnumerable AllForDynamicData { get; } = + All.Select(tfm => new object[] { tfm }); + + public static string ToMSBuildTargetFrameworks(this string[] targetFrameworksEntries) + => string.Join(";", targetFrameworksEntries); } diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestAssetFixtureBase.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestAssetFixtureBase.cs index e40adefc3e..0f25e2993b 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestAssetFixtureBase.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestAssetFixtureBase.cs @@ -3,24 +3,37 @@ using System.Collections.Concurrent; -using Microsoft.Testing.Internal.Framework; - namespace Microsoft.Testing.TestInfrastructure; -public abstract class TestAssetFixtureBase : IDisposable, IAsyncInitializable +public interface ITestAssetFixture : IDisposable +{ + Task InitializeAsync(); +} + +public sealed class NopAssetFixture : ITestAssetFixture +{ + public Task InitializeAsync() => Task.CompletedTask; + + public void Dispose() + { + } +} + +public abstract class TestAssetFixtureBase : ITestAssetFixture { private readonly ConcurrentDictionary _testAssets = new(); private readonly TempDirectory _nugetGlobalPackagesDirectory; private bool _disposedValue; - protected TestAssetFixtureBase(TempDirectory nugetGlobalPackagesDirectory) => _nugetGlobalPackagesDirectory = nugetGlobalPackagesDirectory; + protected TestAssetFixtureBase(TempDirectory nugetGlobalPackagesDirectory) + => _nugetGlobalPackagesDirectory = nugetGlobalPackagesDirectory; public string GetAssetPath(string assetID) => !_testAssets.TryGetValue(assetID, out TestAsset? testAsset) ? throw new ArgumentNullException(nameof(assetID), $"Cannot find target path for test asset '{assetID}'") : testAsset.TargetAssetPath; - public async Task InitializeAsync(InitializationContext context) + public async Task InitializeAsync() #if NET => await Parallel.ForEachAsync(GetAssetsToGenerate(), async (asset, _) => { diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestBase.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestBase.cs deleted file mode 100644 index c5124a15f3..0000000000 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestBase.cs +++ /dev/null @@ -1,11 +0,0 @@ -// 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.Testing.Internal.Framework; - -namespace Microsoft.Testing.TestInfrastructure; - -public abstract class TestBase -{ - protected TestBase(ITestExecutionContext testExecutionContext) => TestsRunWatchDog.AddTestRun(testExecutionContext.TestInfo.StableUid); -} diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestsRunWatchDog.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestsRunWatchDog.cs deleted file mode 100644 index f35320d659..0000000000 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestsRunWatchDog.cs +++ /dev/null @@ -1,120 +0,0 @@ -// 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.Concurrent; -using System.Globalization; -using System.Text; - -using Microsoft.Testing.Internal.Framework; - -namespace Microsoft.Testing.TestInfrastructure; - -public static class TestsRunWatchDog -{ - private static readonly ConcurrentDictionary TestNodes = new(); - - public static string? BaselineFile { get; set; } - - public static void AddTestRun(TestNodeUid testNodeUid) => TestNodes.AddOrUpdate(testNodeUid, 1, (_, count) => count + 1); - - public static async Task VerifyAsync(bool skip = false, bool fixBaseLine = false) - { - if (skip) - { - return; - } - - if (BaselineFile is null) - { - throw new InvalidOperationException("Baseline file should not be null"); - } - - if (TestNodes.IsEmpty) - { - throw new InvalidOperationException("No tests were executed. Have you called 'TestsRunWatchDog.AddTestRun'?"); - } - - List expectedTestsDidNotRun = []; - List unexpectedRanTests = []; - using (FileStream fs = File.OpenRead(BaselineFile)) - { - using StreamReader streamReader = new(fs); - string? testFullyQualifiedName; - while ((testFullyQualifiedName = await streamReader.ReadLineAsync()) != null) - { - if (string.IsNullOrWhiteSpace(testFullyQualifiedName)) - { - // Skip empty lines. - continue; - } - else if (!TestNodes.TryGetValue(testFullyQualifiedName, out int _)) - { - expectedTestsDidNotRun.Add(testFullyQualifiedName); - } - else - { - TestNodes[testFullyQualifiedName]--; - if (TestNodes[testFullyQualifiedName] == 0) - { - TestNodes.TryRemove(testFullyQualifiedName, out _); - } - } - } - } - - if (!TestNodes.IsEmpty) - { - foreach (KeyValuePair notRunNodes in TestNodes) - { - for (int i = 0; i < notRunNodes.Value; i++) - { - unexpectedRanTests.Add(notRunNodes.Key.Value); - } - } - } - - StringBuilder sb = new(); - if (unexpectedRanTests.Count > 0) - { - sb.AppendLine(); - sb.AppendLine(CultureInfo.InvariantCulture, $"Unexpected tests that ran (base line file name {BaselineFile}):"); - sb.AppendLine(); - foreach (string unexpectedTest in unexpectedRanTests) - { - sb.AppendLine(unexpectedTest); - } - } - - if (expectedTestsDidNotRun.Count > 0) - { - sb.AppendLine(); - sb.AppendLine(CultureInfo.InvariantCulture, $"Expected tests that did not run (base line file name {BaselineFile}):"); - sb.AppendLine(); - foreach (string missingTest in expectedTestsDidNotRun) - { - sb.AppendLine(missingTest); - } - } - - try - { - if (unexpectedRanTests.Count > 0 || expectedTestsDidNotRun.Count > 0) - { - throw new InvalidOperationException(sb.ToString()); - } - } - finally - { - if (fixBaseLine) - { - List tests = [.. File.ReadAllLines(BaselineFile)]; - tests.RemoveAll(expectedTestsDidNotRun.Contains); - tests.AddRange(unexpectedRanTests); - tests.Sort(); - File.WriteAllLines(BaselineFile, tests); - Console.WriteLine(); - Console.WriteLine($"FIXED BASELINE: '{BaselineFile}'"); - } - } - } -} From f81364c371f1e04d47a48561a4533c21722461c2 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 17 Dec 2024 13:18:42 +0100 Subject: [PATCH 126/273] Auto detect DynamicDataSourceType (#4340) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../DynamicDataOperations.cs | 71 ++++++++++----- .../Resources/Resource.Designer.cs | 9 ++ .../Resources/Resource.resx | 5 +- .../Resources/xlf/Resource.cs.xlf | 5 ++ .../Resources/xlf/Resource.de.xlf | 5 ++ .../Resources/xlf/Resource.es.xlf | 5 ++ .../Resources/xlf/Resource.fr.xlf | 5 ++ .../Resources/xlf/Resource.it.xlf | 5 ++ .../Resources/xlf/Resource.ja.xlf | 5 ++ .../Resources/xlf/Resource.ko.xlf | 5 ++ .../Resources/xlf/Resource.pl.xlf | 5 ++ .../Resources/xlf/Resource.pt-BR.xlf | 5 ++ .../Resources/xlf/Resource.ru.xlf | 5 ++ .../Resources/xlf/Resource.tr.xlf | 5 ++ .../Resources/xlf/Resource.zh-Hans.xlf | 5 ++ .../Resources/xlf/Resource.zh-Hant.xlf | 5 ++ .../DynamicDataShouldBeValidAnalyzer.cs | 7 +- .../DataSource/DynamicDataAttribute.cs | 38 +++++++- .../PublicAPI/PublicAPI.Unshipped.txt | 7 ++ .../NativeAotTests.cs | 1 + .../Parameterized tests/DynamicDataTests.cs | 4 + .../Parameterized tests/DynamicDataTests.cs | 4 + .../DynamicDataTests.cs | 10 ++- .../DynamicDataShouldBeValidAnalyzerTests.cs | 88 ++++++++++++++++--- .../DynamicDataAttributeTests.cs | 13 +-- 25 files changed, 276 insertions(+), 46 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs b/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs index 10485ab7c3..5a2631f7be 100644 --- a/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs @@ -25,36 +25,35 @@ public IEnumerable GetData(Type? _dynamicDataDeclaringType, DynamicDat switch (_dynamicDataSourceType) { + case DynamicDataSourceType.AutoDetect: +#pragma warning disable IDE0045 // Convert to conditional expression - it becomes less readable. + if (PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredProperty(_dynamicDataDeclaringType, _dynamicDataSourceName) is { } dynamicDataPropertyInfo) + { + obj = GetDataFromProperty(dynamicDataPropertyInfo); + } + else if (PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredMethod(_dynamicDataDeclaringType, _dynamicDataSourceName) is { } dynamicDataMethodInfo) + { + obj = GetDataFromMethod(dynamicDataMethodInfo); + } + else + { + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, Resource.DynamicDataSourceShouldExistAndBeValid, _dynamicDataSourceName, _dynamicDataDeclaringType.FullName)); + } +#pragma warning restore IDE0045 // Convert to conditional expression + + break; case DynamicDataSourceType.Property: PropertyInfo property = PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredProperty(_dynamicDataDeclaringType, _dynamicDataSourceName) ?? throw new ArgumentNullException($"{DynamicDataSourceType.Property} {_dynamicDataSourceName}"); - if (property.GetGetMethod(true) is not { IsStatic: true }) - { - throw new NotSupportedException( - string.Format( - CultureInfo.InvariantCulture, - FrameworkMessages.DynamicDataInvalidPropertyLayout, - property.DeclaringType?.FullName is { } typeFullName ? $"{typeFullName}.{property.Name}" : property.Name)); - } - obj = property.GetValue(null, null); + obj = GetDataFromProperty(property); break; case DynamicDataSourceType.Method: MethodInfo method = PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredMethod(_dynamicDataDeclaringType, _dynamicDataSourceName) ?? throw new ArgumentNullException($"{DynamicDataSourceType.Method} {_dynamicDataSourceName}"); - if (!method.IsStatic - || method.ContainsGenericParameters - || method.GetParameters().Length > 0) - { - throw new NotSupportedException( - string.Format( - CultureInfo.InvariantCulture, - FrameworkMessages.DynamicDataInvalidPropertyLayout, - method.DeclaringType?.FullName is { } typeFullName ? $"{typeFullName}.{method.Name}" : method.Name)); - } - obj = method.Invoke(null, null); + obj = GetDataFromMethod(method); break; } @@ -82,6 +81,38 @@ public IEnumerable GetData(Type? _dynamicDataDeclaringType, DynamicDat return data; } + private static object? GetDataFromMethod(MethodInfo method) + { + if (!method.IsStatic + || method.ContainsGenericParameters + || method.GetParameters().Length > 0) + { + throw new NotSupportedException( + string.Format( + CultureInfo.InvariantCulture, + FrameworkMessages.DynamicDataInvalidPropertyLayout, + method.DeclaringType?.FullName is { } typeFullName ? $"{typeFullName}.{method.Name}" : method.Name)); + } + + // Note: the method is static and takes no parameters. + return method.Invoke(null, null); + } + + private static object? GetDataFromProperty(PropertyInfo property) + { + if (property.GetGetMethod(true) is not { IsStatic: true }) + { + throw new NotSupportedException( + string.Format( + CultureInfo.InvariantCulture, + FrameworkMessages.DynamicDataInvalidPropertyLayout, + property.DeclaringType?.FullName is { } typeFullName ? $"{typeFullName}.{property.Name}" : property.Name)); + } + + // Note: the property getter is static. + return property.GetValue(null, null); + } + /// public string? GetDisplayName(string? DynamicDataDisplayName, Type? DynamicDataDisplayNameDeclaringType, MethodInfo methodInfo, object?[]? data) { diff --git a/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs b/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs index d486407837..5a7d1aa400 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs +++ b/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs @@ -251,6 +251,15 @@ internal static string DynamicDataShouldBeValidMessageFormat_MemberType { } } + /// + /// Looks up a localized string similar to The dynamic data source '{0}' in type '{1}' should exist and be a property or a method.. + /// + internal static string DynamicDataSourceShouldExistAndBeValid { + get { + return ResourceManager.GetString("DynamicDataSourceShouldExistAndBeValid", resourceCulture); + } + } + /// /// Looks up a localized string similar to {0}: {1}. /// diff --git a/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx b/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx index 0521e091cd..8ed6ddde11 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx +++ b/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx @@ -423,4 +423,7 @@ but received {4} argument(s), with types '{5}'. Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + \ No newline at end of file diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf index 4b5f4877b9..14333c6b35 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf @@ -66,6 +66,11 @@ byl však přijat tento počet argumentů: {4} s typy {5}. Odkazovaný člen [DynamicData] {0}.{1} by měl vracet IEnumerable<object[]>, IEnumerable<Tuple> nebo IEnumerable<ValueTuple>. + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. Test {0} překročil časový limit spuštění. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf index a69a0d6c25..95ca34eff8 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf @@ -66,6 +66,11 @@ aber empfing {4} Argument(e) mit den Typen „{5}“. "[DynamicData]"-Element "{0}.{1}" muss "IEnumerable"<"object[]>", "IEnumerable<Tuple>" oder "IEnumerable<ValueTuple>" zurückgeben. + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. Der Test "{0}" hat das Ausführungstimeout überschritten. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf index 6c16560a28..f10464df2f 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf @@ -66,6 +66,11 @@ pero recibió {4} argumento(s), con los tipos "{5}". El miembro ''{0}.{1}'' de '[DynamicData]' al que se hace referencia debe devolver ''IEnumerable<object[]>', 'IEnumerable<Tuple>'' o ''IEnumerable<ValueTuple>'' + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. La prueba '{0}' superó el tiempo de espera de ejecución. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf index 5d160ebd04..4c83356a65 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf @@ -66,6 +66,11 @@ mais a reçu {4} argument(s), avec les types « {5} ». Le membre référencé « [DynamicData] '{0}.{1}' doit renvoyer « IEnumerable<object[]> », « IEnumerable<Tuple> » ou « IEnumerable<ValueTuple> » + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. Le test '{0}' a dépassé le délai d'attente de l'exécution. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf index 926c193cc1..c12e6b26a8 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf @@ -66,6 +66,11 @@ ma ha ricevuto {4} argomenti, con tipi "{5}". '[DynamicData]' membro di riferimento '{0}.{1}' deve restituire 'IEnumerable<object[]>', 'IEnumerable<Tuple>' o 'IEnumerable<ValueTuple>' + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. È stato superato il periodo di timeout per l'esecuzione del test '{0}'. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf index fcdaef3740..6fe9d8a46f 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf @@ -67,6 +67,11 @@ but received {4} argument(s), with types '{5}'. '[DynamicData]' の参照されるメンバー '{0}.{1}' は、'IEnumerable<object[]>'、'IEnumerable<Tuple>`、'IEnumerable<ValueTuple>' のいずれかを返す必要があります + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. テスト '{0}' は実行タイムアウトを超えました。 diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf index 1801e92413..68c71d989c 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf @@ -66,6 +66,11 @@ but received {4} argument(s), with types '{5}'. '[DynamicData]'이(가) '{0} 멤버를 참조했습니다.{1}'은(는) 'IEnumerable<object[]>', 'IEnumerable<Tuple>' 또는 'IEnumerable<ValueTuple>'을 반환해야 합니다. + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. '{0}' 테스트가 실행 시간 제한을 초과했습니다. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf index 2c998a9401..18c3034507 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf @@ -66,6 +66,11 @@ ale liczba odebranych argumentów to {4} z typami „{5}”. Przywołany element członkowski „{0}.{1}” „[DynamicData]” powinien zwrócić „IEnumerable<object[]>”, „IEnumerable<Tuple>” lub „IEnumerable<ValueTuple>” + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. Test „{0}” przekroczył okres limitu czasu na wykonanie. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf index 5fd1e38263..cb3c269ffe 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf @@ -66,6 +66,11 @@ mas {4} argumentos recebidos, com tipos '{5}'. O membro referenciado "{0}.{1}" de "[DynamicData]" deve retornar "IEnumerable<object[]>", "IEnumerable<Tuple>" ou "IEnumerable<ValueTuple>" + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. Teste '{0}' ultrapassou o período de tempo limite de execução. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf index 81e3cdea13..2e1a3dbf58 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf @@ -66,6 +66,11 @@ but received {4} argument(s), with types '{5}'. Указанный элемент "[DynamicData]" "{0}.{1}" должен возвращать "IEnumerable<object[]>", "IEnumerable<Tuple>" или "IEnumerable<ValueTuple>" + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. Превышено время ожидания выполнения теста "{0}". diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf index 5b134802e5..c440ff0b10 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf @@ -66,6 +66,11 @@ ancak, '{5}' türüyle {4} argüman aldı. '[DynamicData]' başvurulan üyesi '{0}.{1}' şu değerleri döndürmelidir: 'IEnumerable<object[]>', 'IEnumerable<Tuple>` veya 'IEnumerable<ValueTuple>' + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. '{0}' testi yürütme zaman aşımı süresini aştı. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf index f6fe41a75b..05fec29a05 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf @@ -66,6 +66,11 @@ but received {4} argument(s), with types '{5}'. “[DynamicData]”引用的成员“{0}.{1}”应返回“IEnumerable<object[]>”、“IEnumerable<Tuple>”或“IEnumerable<ValueTuple>” + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. 测试“{0}”的执行超时。 diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf index de4b58baf4..43ac773225 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf @@ -66,6 +66,11 @@ but received {4} argument(s), with types '{5}'. '[DynamicData]' 參考成員 '{0}.{1}' 應傳回 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' + + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + + Test '{0}' exceeded execution timeout period. 測試 '{0}' 超過執行逾時期限。 diff --git a/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs index c92572ebd9..d21e8335d2 100644 --- a/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs @@ -20,6 +20,7 @@ public sealed class DynamicDataShouldBeValidAnalyzer : DiagnosticAnalyzer { private const int DynamicDataSourceTypeProperty = 0; private const int DynamicDataSourceTypeMethod = 1; + private const int DynamicDataSourceTypeAutoDetect = 2; private static readonly LocalizableResourceString Title = new(nameof(Resources.DynamicDataShouldBeValidTitle), Resources.ResourceManager, typeof(Resources)); private static readonly LocalizableResourceString Description = new(nameof(Resources.DynamicDataShouldBeValidDescription), Resources.ResourceManager, typeof(Resources)); @@ -144,7 +145,7 @@ private static void AnalyzeDataSource(SymbolAnalysisContext context, AttributeDa INamedTypeSymbol itupleTypeSymbol) { string? memberName = null; - int dataSourceType = 0; + int dataSourceType = DynamicDataSourceTypeAutoDetect; INamedTypeSymbol declaringType = methodSymbol.ContainingType; foreach (TypedConstant argument in attributeData.ConstructorArguments) { @@ -192,14 +193,14 @@ private static void AnalyzeDataSource(SymbolAnalysisContext context, AttributeDa ISymbol member = potentialMembers[0]; // If the member is a property and the data source type is not set to property, report a diagnostic. - if (member.Kind == SymbolKind.Property && dataSourceType is not DynamicDataSourceTypeProperty) + if (member.Kind == SymbolKind.Property && dataSourceType is not (DynamicDataSourceTypeProperty or DynamicDataSourceTypeAutoDetect)) { context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(SourceTypePropertyRule, declaringType.Name, memberName)); return; } // If the member is a method and the data source type is not set to method, report a diagnostic. - if (member.Kind == SymbolKind.Method && dataSourceType is not DynamicDataSourceTypeMethod) + if (member.Kind == SymbolKind.Method && dataSourceType is not (DynamicDataSourceTypeMethod or DynamicDataSourceTypeAutoDetect)) { context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(SourceTypeMethodRule, declaringType.Name, memberName)); return; diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs index 2abb53a755..a7240468d8 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs @@ -5,6 +5,7 @@ using System.Collections; using System.Runtime.CompilerServices; #endif +using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection; @@ -27,6 +28,11 @@ public enum DynamicDataSourceType /// Data is declared in method. /// Method = 1, + + /// + /// The data source type is auto-detected. + /// + AutoDetect = 2, } /// @@ -49,12 +55,25 @@ public sealed class DynamicDataAttribute : Attribute, ITestDataSource, ITestData /// /// Specifies whether the data is stored as property or in method. /// - public DynamicDataAttribute(string dynamicDataSourceName, DynamicDataSourceType dynamicDataSourceType = DynamicDataSourceType.Property) + [EditorBrowsable(EditorBrowsableState.Never)] + public DynamicDataAttribute(string dynamicDataSourceName, DynamicDataSourceType dynamicDataSourceType) { _dynamicDataSourceName = dynamicDataSourceName; _dynamicDataSourceType = dynamicDataSourceType; } + /// + /// Initializes a new instance of the class. + /// + /// + /// The name of method or property having test data. + /// + public DynamicDataAttribute(string dynamicDataSourceName) + { + _dynamicDataSourceName = dynamicDataSourceName; + _dynamicDataSourceType = DynamicDataSourceType.AutoDetect; + } + /// /// Initializes a new instance of the class when the test data is present in a class different /// from test method's class. @@ -69,9 +88,24 @@ public DynamicDataAttribute(string dynamicDataSourceName, DynamicDataSourceType /// /// Specifies whether the data is stored as property or in method. /// - public DynamicDataAttribute(string dynamicDataSourceName, Type dynamicDataDeclaringType, DynamicDataSourceType dynamicDataSourceType = DynamicDataSourceType.Property) + [EditorBrowsable(EditorBrowsableState.Never)] + public DynamicDataAttribute(string dynamicDataSourceName, Type dynamicDataDeclaringType, DynamicDataSourceType dynamicDataSourceType) : this(dynamicDataSourceName, dynamicDataSourceType) => _dynamicDataDeclaringType = dynamicDataDeclaringType; + /// + /// Initializes a new instance of the class when the test data is present in a class different + /// from test method's class. + /// + /// + /// The name of method or property having test data. + /// + /// + /// The declaring type of property or method having data. Useful in cases when declaring type is present in a class different from + /// test method's class. If null, declaring type defaults to test method's class type. + /// + public DynamicDataAttribute(string dynamicDataSourceName, Type dynamicDataDeclaringType) + : this(dynamicDataSourceName) => _dynamicDataDeclaringType = dynamicDataDeclaringType; + internal static TestIdGenerationStrategy TestIdGenerationStrategy { get; set; } /// diff --git a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt index 7c1390e0bf..3ceaf8e88e 100644 --- a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt @@ -1,4 +1,11 @@ #nullable enable +Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType dynamicDataSourceType) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, System.Type! dynamicDataDeclaringType) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, System.Type! dynamicDataDeclaringType, Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType dynamicDataSourceType) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.AutoDetect = 2 -> Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType +*REMOVED*Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType dynamicDataSourceType = Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Property) -> void +*REMOVED*Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, System.Type! dynamicDataDeclaringType, Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType dynamicDataSourceType = Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Property) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Throws(System.Action! action, string! message = "", params object![]! messageArgs) -> TException! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsAsync(System.Func! action, string! message = "", params object![]! messageArgs) -> System.Threading.Tasks.Task! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactly(System.Action! action, string! message = "", params object![]! messageArgs) -> TException! diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs index fb0cf271af..c32d56e656 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs @@ -85,6 +85,7 @@ public void TestMethod3(int a, int b) """; [TestMethod] + [Ignore("https://github.com/microsoft/testfx/issues/4369")] public async Task NativeAotTests_WillRunWithExitCodeZero() { // The hosted AzDO agents for Mac OS don't have the required tooling for us to test Native AOT. diff --git a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs index a370027ea9..bd61e0b916 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs @@ -25,12 +25,14 @@ public void ExecuteDynamicDataTests() VerifyE2E.TestsPassed( testResults, "DynamicDataTest_SourceProperty (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAuto (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "Custom DynamicDataTestMethod DynamicDataTest_SourcePropertyOtherType_CustomDisplayName with 2 parameters", "Custom DynamicDataTestMethod DynamicDataTest_SourceMethodOtherType_CustomDisplayName with 2 parameters", "UserDynamicDataTestMethod DynamicDataTest_SourcePropertyOtherType_CustomDisplayNameOtherType with 2 parameters", "Custom DynamicDataTestMethod DynamicDataTest_SourceMethod_CustomDisplayName with 2 parameters", "UserDynamicDataTestMethod DynamicDataTest_SourceMethodOtherType_CustomDisplayNameOtherType with 2 parameters", "DynamicDataTest_SourceMethod (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAuto (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "UserDynamicDataTestMethod DynamicDataTest_SourcePropertyOtherType_CustomDisplayNameOtherType with 2 parameters", "StackOverflowException_Example (DataSourceTestProject.DynamicDataTests+ExampleTestCase)", "Custom DynamicDataTestMethod DynamicDataTest_SourceProperty_CustomDisplayName with 2 parameters", @@ -46,9 +48,11 @@ public void ExecuteDynamicDataTests() "UserDynamicDataTestMethod DynamicDataTest_SourceProperty_CustomDisplayNameOtherType with 2 parameters", "UserDynamicDataTestMethod DynamicDataTest_SourceProperty_CustomDisplayNameOtherType with 2 parameters", "DynamicDataTest_SourceMethod (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAuto (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "Custom DynamicDataTestMethod DynamicDataTest_SourcePropertyOtherType_CustomDisplayName with 2 parameters", "UserDynamicDataTestMethod DynamicDataTest_SourceMethodOtherType_CustomDisplayNameOtherType with 2 parameters", "DynamicDataTest_SourceProperty (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAuto (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourcePropertyOtherType (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "Custom DynamicDataTestMethod DynamicDataTest_SourceMethod_CustomDisplayName with 2 parameters", "MethodWithOverload (\"1\",1)", diff --git a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs index a9e134080f..652f65471b 100644 --- a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs +++ b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs @@ -20,8 +20,12 @@ public void ExecuteDynamicDataTests() ValidatePassedTests( "DynamicDataTest_SourceMethod (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourceMethod (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAuto (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAuto (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourceProperty (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourceProperty (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAuto (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAuto (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "Custom DynamicDataTestMethod DynamicDataTest_SourceMethod_CustomDisplayName with 2 parameters", "Custom DynamicDataTestMethod DynamicDataTest_SourceMethod_CustomDisplayName with 2 parameters", "Custom DynamicDataTestMethod DynamicDataTest_SourceProperty_CustomDisplayName with 2 parameters", diff --git a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs index bc467c3057..6013db1afa 100644 --- a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs +++ b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs @@ -22,9 +22,17 @@ public class DynamicDataTests public void DynamicDataTest_SourceMethod(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); [DataTestMethod] - [DynamicData(nameof(ParseUserData))] + [DynamicData(nameof(GetParseUserData))] + public void DynamicDataTest_SourceMethodAuto(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + + [DataTestMethod] + [DynamicData(nameof(ParseUserData), DynamicDataSourceType.Property)] public void DynamicDataTest_SourceProperty(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + [DataTestMethod] + [DynamicData(nameof(ParseUserData))] + public void DynamicDataTest_SourcePropertyAuto(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + [DataTestMethod] [DynamicData(nameof(GetParseUserData), DynamicDataSourceType.Method, DynamicDataDisplayName = nameof(GetCustomDynamicDataDisplayName))] diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs index b572150cc1..baf83013c6 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs @@ -23,49 +23,97 @@ public class MyTestClass { [DynamicData("Data")] [TestMethod] - public void TestMethod1(object[] o) + public void TestMethod1Auto(object[] o) + { + } + + [DynamicData("Data", DynamicDataSourceType.Property)] + [TestMethod] + public void TestMethod1Property(object[] o) { } [DynamicData("SomeData", typeof(SomeClass))] [TestMethod] - public void TestMethod2(object[] o) + public void TestMethod2Auto(object[] o) + { + } + + [DynamicData("SomeData", typeof(SomeClass), DynamicDataSourceType.Property)] + [TestMethod] + public void TestMethod2Property(object[] o) { } [DynamicData(dynamicDataSourceName: "Data")] [TestMethod] - public void TestMethod3(object[] o) + public void TestMethod3Auto(object[] o) + { + } + + [DynamicData(dynamicDataSourceName: "Data", DynamicDataSourceType.Property)] + [TestMethod] + public void TestMethod3Property(object[] o) { } [DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "SomeData")] [TestMethod] - public void TestMethod4(object[] o) + public void TestMethod4Auto(object[] o) + { + } + + [DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "SomeData", dynamicDataSourceType: DynamicDataSourceType.Property)] + [TestMethod] + public void TestMethod4Property(object[] o) { } [DynamicData("GetData", DynamicDataSourceType.Method)] [TestMethod] - public void TestMethod11(object[] o) + public void TestMethod11Method(object[] o) + { + } + + [DynamicData("GetData")] + [TestMethod] + public void TestMethod11Auto(object[] o) { } [DynamicData("GetSomeData", typeof(SomeClass), DynamicDataSourceType.Method)] [TestMethod] - public void TestMethod12(object[] o) + public void TestMethod12Method(object[] o) + { + } + + [DynamicData("GetSomeData", typeof(SomeClass))] + [TestMethod] + public void TestMethod12Auto(object[] o) { } [DynamicData(dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetData")] [TestMethod] - public void TestMethod13(object[] o) + public void TestMethod13Method(object[] o) + { + } + + [DynamicData(dynamicDataSourceType: DynamicDataSourceType.AutoDetect, dynamicDataSourceName: "GetData")] + [TestMethod] + public void TestMethod13Auto(object[] o) { } [DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetSomeData")] [TestMethod] - public void TestMethod14(object[] o) + public void TestMethod14Method(object[] o) + { + } + + [DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceType: DynamicDataSourceType.AutoDetect, dynamicDataSourceName: "GetSomeData")] + [TestMethod] + public void TestMethod14Auto(object[] o) { } @@ -443,6 +491,18 @@ public void TestMethod4(object[] o) { } + [{|#4:DynamicData("GetData", DynamicDataSourceType.AutoDetect)|}] + [TestMethod] + public void TestMethod5(object[] o) + { + } + + [{|#5:DynamicData("GetData")|}] + [TestMethod] + public void TestMethod6(object[] o) + { + } + public static IEnumerable GetData() => new List(); public static IEnumerable GetData(int i) => new List(); } @@ -459,7 +519,9 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.FoundTooManyMembersRule).WithLocation(0).WithArguments("MyTestClass", "GetData"), VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.FoundTooManyMembersRule).WithLocation(1).WithArguments("SomeClass", "GetSomeData"), VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.FoundTooManyMembersRule).WithLocation(2).WithArguments("MyTestClass", "GetData"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.FoundTooManyMembersRule).WithLocation(3).WithArguments("SomeClass", "GetSomeData")); + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.FoundTooManyMembersRule).WithLocation(3).WithArguments("SomeClass", "GetSomeData"), + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.FoundTooManyMembersRule).WithLocation(4).WithArguments("MyTestClass", "GetData"), + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.FoundTooManyMembersRule).WithLocation(5).WithArguments("MyTestClass", "GetData")); } [TestMethod] @@ -472,25 +534,25 @@ public async Task WhenMemberKindIsMixedUp_Diagnostic() [TestClass] public class MyTestClass { - [{|#0:DynamicData("GetData")|}] + [{|#0:DynamicData("GetData", DynamicDataSourceType.Property)|}] [TestMethod] public void TestMethod1(object[] o) { } - [{|#1:DynamicData("GetSomeData", typeof(SomeClass))|}] + [{|#1:DynamicData("GetSomeData", typeof(SomeClass), DynamicDataSourceType.Property)|}] [TestMethod] public void TestMethod2(object[] o) { } - [{|#2:DynamicData(dynamicDataSourceName: "GetData")|}] + [{|#2:DynamicData(dynamicDataSourceName: "GetData", DynamicDataSourceType.Property)|}] [TestMethod] public void TestMethod3(object[] o) { } - [{|#3:DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "GetSomeData")|}] + [{|#3:DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "GetSomeData", dynamicDataSourceType: DynamicDataSourceType.Property)|}] [TestMethod] public void TestMethod4(object[] o) { diff --git a/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs index 866b30d657..037ee46cae 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs @@ -3,6 +3,7 @@ using System.Collections; using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.Reflection; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; @@ -29,12 +30,12 @@ public DynamicDataAttributeTests() DynamicDataAttribute.TestIdGenerationStrategy = TestIdGenerationStrategy.FullyQualified; } - public void GetDataShouldThrowExceptionIfInvalidPropertyNameIsSpecifiedOrPropertyDoesNotExist() => - VerifyThrows(() => - { - _dynamicDataAttribute = new DynamicDataAttribute("ABC"); - _dynamicDataAttribute.GetData(_testMethodInfo); - }); + public void GetDataShouldThrowExceptionIfInvalidPropertyNameIsSpecifiedOrPropertyDoesNotExist() + { + _dynamicDataAttribute = new DynamicDataAttribute("ABC"); + InvalidOperationException ex = VerifyThrows(() => _dynamicDataAttribute.GetData(_testMethodInfo)); + Verify(ex.Message == string.Format(CultureInfo.InvariantCulture, Resource.DynamicDataSourceShouldExistAndBeValid, "ABC", _testMethodInfo.DeclaringType.FullName)); + } public void GetDataShouldReadDataFromProperty() { From 35a6176e5031ee7ecf7490b5a2c346ec51bfffe6 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 18 Dec 2024 08:03:58 +0100 Subject: [PATCH 127/273] Fix main (#4373) --- test/Directory.Build.targets | 2 ++ .../MSTest.Analyzers.UnitTests.csproj | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index be7e8c4711..463df410cc 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -28,7 +28,9 @@ + + diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj b/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj index 48717386f5..40ef00ed4b 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj @@ -1,4 +1,4 @@ - + net6.0 @@ -6,6 +6,11 @@ true true true + + + + + true From 961a1e1c274a5364f75a0bcdf5bcfc419162e2da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 18 Dec 2024 08:06:25 +0100 Subject: [PATCH 128/273] Open source Retry and Hot Reload extensions (#4354) --- .editorconfig | 1 + LICENSE.PLATFORMTOOLS.txt | 110 ++++++ TestFx.sln | 15 +- eng/Analyzers.props | 1 - eng/stylecop.json | 11 - eng/stylecop.ruleset | 15 - eng/stylecop.test.ruleset | 20 - .../.editorconfig | 2 + .../BannedSymbols.txt | 10 + .../HotReloadExtensions.cs | 15 + .../HotReloadHandler.cs | 91 +++++ .../HotReloadTestHostTestFrameworkInvoker.cs | 68 ++++ ...rosoft.Testing.Extensions.HotReload.csproj | 61 +++ .../PACKAGE.md | 9 + .../PublicAPI/PublicAPI.Shipped.txt | 5 + .../PublicAPI/PublicAPI.Unshipped.txt | 1 + .../Resources/ExtensionResources.Designer.cs | 90 +++++ .../Resources/ExtensionResources.resx | 129 ++++++ .../Resources/xlf/ExtensionResources.cs.xlf | 22 ++ .../Resources/xlf/ExtensionResources.de.xlf | 22 ++ .../Resources/xlf/ExtensionResources.es.xlf | 22 ++ .../Resources/xlf/ExtensionResources.fr.xlf | 22 ++ .../Resources/xlf/ExtensionResources.it.xlf | 22 ++ .../Resources/xlf/ExtensionResources.ja.xlf | 22 ++ .../Resources/xlf/ExtensionResources.ko.xlf | 22 ++ .../Resources/xlf/ExtensionResources.pl.xlf | 22 ++ .../xlf/ExtensionResources.pt-BR.xlf | 22 ++ .../Resources/xlf/ExtensionResources.ru.xlf | 22 ++ .../Resources/xlf/ExtensionResources.tr.xlf | 22 ++ .../xlf/ExtensionResources.zh-Hans.xlf | 22 ++ .../xlf/ExtensionResources.zh-Hant.xlf | 22 ++ .../TestingPlatformBuilderHook.cs | 12 + ...crosoft.Testing.Extensions.HotReload.props | 3 + ...crosoft.Testing.Extensions.HotReload.props | 9 + ...crosoft.Testing.Extensions.HotReload.props | 3 + .../.editorconfig | 2 + .../BannedSymbols.txt | 10 + .../Microsoft.Testing.Extensions.Retry.csproj | 65 ++++ .../PACKAGE.md | 9 + .../PublicAPI/PublicAPI.Shipped.txt | 5 + .../PublicAPI/PublicAPI.Unshipped.txt | 1 + .../RandomId.cs | 44 +++ .../Resources/ExtensionResources.Designer.cs | 284 ++++++++++++++ .../Resources/ExtensionResources.resx | 204 ++++++++++ .../Resources/xlf/ExtensionResources.cs.xlf | 150 +++++++ .../Resources/xlf/ExtensionResources.de.xlf | 150 +++++++ .../Resources/xlf/ExtensionResources.es.xlf | 151 ++++++++ .../Resources/xlf/ExtensionResources.fr.xlf | 150 +++++++ .../Resources/xlf/ExtensionResources.it.xlf | 150 +++++++ .../Resources/xlf/ExtensionResources.ja.xlf | 150 +++++++ .../Resources/xlf/ExtensionResources.ko.xlf | 150 +++++++ .../Resources/xlf/ExtensionResources.pl.xlf | 150 +++++++ .../xlf/ExtensionResources.pt-BR.xlf | 150 +++++++ .../Resources/xlf/ExtensionResources.ru.xlf | 150 +++++++ .../Resources/xlf/ExtensionResources.tr.xlf | 150 +++++++ .../xlf/ExtensionResources.zh-Hans.xlf | 150 +++++++ .../xlf/ExtensionResources.zh-Hant.xlf | 150 +++++++ .../RetryCommandLineOptionsProvider.cs | 85 ++++ .../RetryDataConsumer.cs | 79 ++++ .../RetryExecutionFilterFactory.cs | 50 +++ .../RetryExtensions.cs | 38 ++ .../RetryFailedTestsPipeServer.cs | 75 ++++ .../RetryLifecycleCallbacks.cs | 89 +++++ .../RetryOrchestrator.cs | 348 +++++++++++++++++ .../Serializers/FailedTestRequest.cs | 29 ++ .../Serializers/GetListOfFailedTests.cs | 20 + .../GetListOfFailedTestsResponse.cs | 40 ++ .../Serializers/TotalTestsRunRequest.cs | 29 ++ .../TestingPlatformBuilderHook.cs | 12 + .../Microsoft.Testing.Extensions.Retry.props | 3 + .../Microsoft.Testing.Extensions.Retry.props | 9 + .../Microsoft.Testing.Extensions.Retry.props | 3 + .../NativeAotTests.cs | 1 - .../DiagnosticTests.cs | 3 +- .../ExecutionTests.cs | 6 +- .../HelpInfoTests.cs | 10 +- .../Helpers/AcceptanceTestBase.cs | 4 - .../MSBuild.KnownExtensionRegistration.cs | 9 +- .../MSBuildTests.ConfigurationFile.cs | 6 +- .../MSBuildTests.GenerateEntryPoint.cs | 4 +- .../MSBuildTests.Solution.cs | 3 +- .../Properties/launchSettings.json | 2 +- .../RetryFailedTestsTests.cs | 366 ++++++++++++++++++ .../TimeoutTests.cs | 3 +- .../TrxTests.cs | 3 +- ...rosoft.Testing.Extensions.UnitTests.csproj | 3 + .../RetryTests.cs | 115 ++++++ 87 files changed, 4904 insertions(+), 85 deletions(-) create mode 100644 LICENSE.PLATFORMTOOLS.txt delete mode 100644 eng/stylecop.json delete mode 100644 eng/stylecop.ruleset delete mode 100644 eng/stylecop.test.ruleset create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/.editorconfig create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/BannedSymbols.txt create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadExtensions.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadHandler.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadTestHostTestFrameworkInvoker.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Microsoft.Testing.Extensions.HotReload.csproj create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/PACKAGE.md create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/PublicAPI/PublicAPI.Shipped.txt create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/PublicAPI/PublicAPI.Unshipped.txt create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/ExtensionResources.Designer.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/ExtensionResources.resx create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/TestingPlatformBuilderHook.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/build/Microsoft.Testing.Extensions.HotReload.props create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/buildMultiTargeting/Microsoft.Testing.Extensions.HotReload.props create mode 100644 src/Platform/Microsoft.Testing.Extensions.HotReload/buildTransitive/Microsoft.Testing.Extensions.HotReload.props create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/.editorconfig create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/BannedSymbols.txt create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/PACKAGE.md create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/PublicAPI/PublicAPI.Shipped.txt create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/PublicAPI/PublicAPI.Unshipped.txt create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/RandomId.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/ExtensionResources.Designer.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/ExtensionResources.resx create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/RetryCommandLineOptionsProvider.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/RetryDataConsumer.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/RetryExecutionFilterFactory.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/RetryExtensions.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/RetryFailedTestsPipeServer.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/RetryLifecycleCallbacks.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/FailedTestRequest.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTests.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTestsResponse.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/TotalTestsRunRequest.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/TestingPlatformBuilderHook.cs create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/build/Microsoft.Testing.Extensions.Retry.props create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/buildMultiTargeting/Microsoft.Testing.Extensions.Retry.props create mode 100644 src/Platform/Microsoft.Testing.Extensions.Retry/buildTransitive/Microsoft.Testing.Extensions.Retry.props create mode 100644 test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/RetryFailedTestsTests.cs create mode 100644 test/UnitTests/Microsoft.Testing.Extensions.UnitTests/RetryTests.cs diff --git a/.editorconfig b/.editorconfig index 59a6b86f57..742a013007 100644 --- a/.editorconfig +++ b/.editorconfig @@ -249,6 +249,7 @@ dotnet_diagnostic.SA1402.severity = none # SA1402: File may only dotnet_diagnostic.SA1515.severity = none # SA1515: Single-line comment should be preceded by blank line dotnet_diagnostic.SA1611.severity = none # SA1611: Element parameters should be documented dotnet_diagnostic.SA1615.severity = none # SA1615: Element return value should be documented +dotnet_diagnostic.SA1633.severity = none # SA1633: File should have header dotnet_diagnostic.SA1649.severity = none # SA1649: File name should match first type name # ----------------------------------------------------------------------------------------- diff --git a/LICENSE.PLATFORMTOOLS.txt b/LICENSE.PLATFORMTOOLS.txt new file mode 100644 index 0000000000..0be60953c8 --- /dev/null +++ b/LICENSE.PLATFORMTOOLS.txt @@ -0,0 +1,110 @@ +MICROSOFT SOFTWARE LICENSE TERMS +MICROSOFT TESTING PLATFORM TOOLS + +These license terms are an agreement between you and Microsoft Corporation (or based on where you live, one of its affiliates). They apply to the software named above, and the software listed or available at https://aka.ms/testingplatform/extensions (collectively "Software"). The terms also apply to any Microsoft services and updates for the Software, except to the extent those have different terms. + +IF YOU COMPLY WITH THESE LICENSE TERMS, YOU HAVE THE RIGHTS BELOW. + +1. INSTALLATION AND USE RIGHTS. + +(a) Individuals. If you are an individual working on your own applications, either to sell or for any other purpose, you may install and use the Software to develop and test your applications. + +(b) Organizations. If you are an organization, your users may install and use the Software as follows: + +(i) Any number of your users may use the Software to develop and test applications released under Open Source Initiative ("OSI") approved open source Software licenses. + +(ii) Any number of your users may use the Software to develop and test your applications as part of online or in person classroom training and education, or for performing academic research. + +(iii) If none of the above apply, and you are also not an Enterprise (defined below), then up to five (5) of your individual users can use the Software concurrently to develop and test your applications. + +(iv) If you are an Enterprise, your users may not use the Software to develop or test your applications, except for: (1) open source; and (2) education purposes, each as permitted above. + +An "Enterprise" is any organization and its Affiliates that collectively have either: (A) more than two-hundred fifty (250) PCs or users; or (B) one million ($1,000,000.00) U.S. dollars (or the equivalent in other currencies) in annual revenues. As used in this section, "Affiliates" means those entities that control (via majority ownership), are controlled by, or are under common control with an organization. + +(v) Notwithstanding Sections 1(b)(i)-(v), your users may install and use copies of the Software on your devices to develop and test applications while you have a valid paid entitlement (e.g., a paid subscription) to use at least one (1) eligible product or service listed in the supplemental licensing documentation available at https://aka.ms/vs/eligible-entitlements. Additionally: + +- the number of your users permitted to use the Software, and other relevant limitations, are specified in the supplemental licensing documentation referenced above; and + +- paid entitlements to the eligible products and services require a separate agreement with Microsoft or a Microsoft affiliate. + +(vi) You are responsible for your users' compliance with the terms of this agreement, as applicable. + +(c) Permitted Environments. You may not separate the components of the Software (except as otherwise stated in this agreement) and run those in a production environment, or on third party devices, or for any purpose other than developing and testing your applications. + +(d) Backup Copy. You may make one (1) backup copy of the Software, for reinstalling the Software. + +(e) Online Services in the Software. Some features of the Software make use of online services to provide you information about updates to the Software or extensions, or to enable you to retrieve content, collaborate with others, or otherwise supplement your development experience. As used throughout this agreement, the term "Software" includes these online service features, and by using them, you consent to the transmission of information as described in Section 3 (Data). + +(f) Demo Use. The use rights permitted above include using the Software to demonstrate your applications. + +(g) Third Party Components. The Software may include third party components with separate legal notices or governed by other agreements, as may be described in the notices file(s) accompanying the Software. + +(h) Use on Azure. Running the Software on Microsoft Azure may require separate online usage fees. + +(i) Previews. Microsoft may also make preview versions of the Software available to you. Preview versions of the Software follow semantic versioning, as that standard is described here, https://semver.org/, and preview versions may be released on multiple websites (see https://aka.ms/testingplatform/extensions). You may use any number of copies of the preview Software, components, or features consistent with the terms of these license terms. Previews are experimental and may be substantially different from the commercially released version. They may not operate correctly or work the way a final version will. Microsoft may change previews for the final, commercial version, if any. Microsoft is not obligated to provide maintenance, technical support or updates to you for previews. + +2. FEEDBACK. If you give feedback about the Software to Microsoft, you give to Microsoft, without charge, the right to use, share, and commercialize your feedback in any way and for any purpose. You will not give feedback that is subject to a license that requires Microsoft to license its Software or documentation to third parties because we include your feedback in them. These rights survive this agreement. + +3. DATA. + +(a) Data Collection. The Software may collect information about you and your use of the Software, and send that to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may opt-out of many of these scenarios, but not all, as described in the Software documentation. There are also some features in the Software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft's privacy statement. Our privacy statement is located at https://aka.ms/privacy. You can learn more about data collection and its use in the Software documentation and our privacy statement. Your use of the Software operates as your consent to these practices. + +(b) Processing of Personal Data. To the extent Microsoft is a processor or subprocessor of personal data in connection with the software, Microsoft makes the commitments in the European Union General Data Protection Regulation Terms of the Microsoft Products and Services Data Protection Addendum to all customers effective May 25, 2018, at https://learn.microsoft.com/legal/gdpr. + +4. SCOPE OF LICENSE. The Software is licensed, not sold. These license terms only gives you some rights to use the Software. Microsoft reserves all other rights. Unless applicable law gives you more rights despite this limitation, you may use the Software only as expressly permitted in these license terms. In doing so, you must comply with any technical limitations in the Software that only allow you to use it in certain ways. For example, if Microsoft technically limits or disables extensibility for the Software, you may not extend the Software by, among other things, loading or injecting into the Software any non-Microsoft add-ins, macros, or packages; modifying the software registry settings; or adding features or functionality equivalent to that found in Microsoft products and services. In addition, you may not: + +(a) work around any technical limitations in the Software; + +(b) reverse engineer, decompile or disassemble the Software, or otherwise attempt to derive the source code for the Software, except and only to the extent required by third party licensing terms governing use of certain open-source components that may be included with the Software; + +(c) remove, minimize, block or modify any notices of Microsoft or its suppliers in the Software; + +(d) use the Software in any way that is against the law; + +(e) share, publish, rent, or lease the Software; or + +(f) provide the Software as a stand-alone offering or combine it with any of your applications for others to use, or transfer the Software or this agreement to any third party. + +5. EXPORT RESTRICTIONS. You must comply with all domestic and international export laws and regulations that apply to the Software, which include restrictions on destinations, end users and end use. For further information on export restrictions, visit (aka.ms/exporting). + +6. SUPPORT SERVICES. Because this Software is "as is," we may not provide support services for it. + +7. ENTIRE AGREEMENT. This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the Software and support services. + +8. APPLICABLE LAW. If you acquired the Software in the United States, Washington law applies to interpretation of and claims for breach of this agreement, and the laws of the state where you live apply to all other claims. If you acquired the Software in any other country, its laws apply. + +9. CONSUMER RIGHTS; REGIONAL VARIATIONS. This agreement describes certain legal rights. You may have other rights, including consumer rights, under the laws of your state or country. Separate and apart from your relationship with Microsoft, you may also have rights with respect to the party from which you acquired the Software. This agreement does not change those other rights if the laws of your state or country do not permit it to do so. For example, if you acquired the Software in one of the below regions, or mandatory country law applies, then the following provisions apply to you: + +(a) Australia. You have statutory guarantees under the Australian Consumer Law and nothing in this agreement is intended to affect those rights. + +(b) Canada. If you acquired this Software in Canada, you may stop receiving updates by turning off the automatic update feature, disconnecting your device from the Internet (if and when you re-connect to the Internet, however, the Software will resume checking for and installing updates), or uninstalling the Software. The product documentation, if any, may also specify how to turn off updates for your specific device or Software. + +(c) Germany and Austria. + +(i) Warranty. The properly licensed Software will perform substantially as described in any Microsoft materials that accompany the Software. However, Microsoft gives no contractual guarantee in relation to the licensed Software. + +(ii) Limitation of Liability. In case of intentional conduct, gross negligence, claims based on the Product Liability Act, as well as, in case of death or personal or physical injury, Microsoft is liable according to the statutory law. + +Subject to the foregoing clause (ii), Microsoft will only be liable for slight negligence if Microsoft is in breach of such material contractual obligations, the fulfillment of which facilitate the due performance of this agreement, the breach of which would endanger the purpose of this agreement and the compliance with which a party may constantly trust in (so-called "cardinal obligations"). In other cases of slight negligence, Microsoft will not be liable for slight negligence. + +10. DISCLAIMER OF WARRANTY. THE SOFTWARE IS LICENSED "AS-IS." YOU BEAR THE RISK OF USING IT. MICROSOFT GIVES NO EXPRESS WARRANTIES, GUARANTEES OR CONDITIONS. TO THE EXTENT PERMITTED UNDER YOUR LOCAL LAWS, MICROSOFT EXCLUDES THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + +11. LIMITATION ON AND EXCLUSION OF DAMAGES. YOU CAN RECOVER FROM MICROSOFT AND ITS SUPPLIERS ONLY DIRECT DAMAGES UP TO U.S. $5.00. YOU CANNOT RECOVER ANY OTHER DAMAGES, INCLUDING CONSEQUENTIAL, LOST PROFITS, SPECIAL, INDIRECT OR INCIDENTAL DAMAGES. + +This limitation applies to (a) anything related to the Software, services, content (including code) on third party Internet sites, or third party applications; and (b) claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law. It also applies even if Microsoft knew or should have known about the possibility of the damages. The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages. + +Please note: As this Software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French. + +Remarque: Ce Logiciel tant distribu au Qubec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en franais. + +EXONRATION DE GARANTIE. Le Logiciel vis par une licence est offert tel quel . Toute utilisation de ce Logiciel est votre seule risque et pril. Microsoft n'accorde aucune autre garantie expresse. Vous pouvez bnficier de droits additionnels en vertu du droit local sur la protection des consommateurs, que ce contrat ne peut modifier. L u elles sont permises par le droit locale, les garanties implicites de qualit marchande, d'adquation un usage particulier et d'absence de contrefaon sont exclues. + +LIMITATION DES DOMMAGES-INTRTS ET EXCLUSION DE RESPONSABILIT POUR LES DOMMAGES. Vous pouvez obtenir de Microsoft et de ses fournisseurs une indemnisation en cas de dommages directs uniquement hauteur de 5,00 $ US. Vous ne pouvez prtendre aucune indemnisation pour les autres dommages, y compris les dommages spciaux, indirects ou accessoires et pertes de bnfices. Cette limitation concerne: + +- tout ce qui est reli au Logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers; et + +- les rclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit stricte, de ngligence ou d'une autre faute dans la limite autorise par la loi en vigueur. +Elle s'applique galement, mme si Microsoft connaissait ou devrait connatre l'ventualit d'un tel dommage. Si votre pays n'autorise pas l'exclusion ou la limitation de responsabilit pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l'exclusion ci-dessus ne s'appliquera pas votre gard. + +EFFET JURIDIQUE. Le prsent contrat dcrit certains droits juridiques. Vous pourriez avoir d'autres droits prvus par les lois de votre pays. Le prsent contrat ne modifie pas les droits que vous confrent les lois de votre pays si celles-ci ne le permettent pas. + diff --git a/TestFx.sln b/TestFx.sln index 2a974cdced..d014ea3643 100644 --- a/TestFx.sln +++ b/TestFx.sln @@ -56,7 +56,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "eng", "eng", "{FE0DF239-0D8 eng\Build.props = eng\Build.props eng\coverage.config = eng\coverage.config eng\install-windows-sdk.ps1 = eng\install-windows-sdk.ps1 - eng\stylecop.json = eng\stylecop.json eng\verify-nupkgs.ps1 = eng\verify-nupkgs.ps1 eng\Version.Details.xml = eng\Version.Details.xml eng\Versions.props = eng\Versions.props @@ -211,6 +210,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Testing.Extension EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MSTest.Internal.Analyzers", "src\Analyzers\MSTest.Internal.Analyzers\MSTest.Internal.Analyzers.csproj", "{4A93E1A2-B61E-31B2-33F2-478156A9B5E7}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Testing.Extensions.HotReload", "src\Platform\Microsoft.Testing.Extensions.HotReload\Microsoft.Testing.Extensions.HotReload.csproj", "{53EBA540-F6CF-0715-1F62-241A53F537EC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Testing.Extensions.Retry", "src\Platform\Microsoft.Testing.Extensions.Retry\Microsoft.Testing.Extensions.Retry.csproj", "{FB4ED3AA-A12E-4192-861F-4B025876AA0F}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -489,6 +492,14 @@ Global {4A93E1A2-B61E-31B2-33F2-478156A9B5E7}.Debug|Any CPU.Build.0 = Debug|Any CPU {4A93E1A2-B61E-31B2-33F2-478156A9B5E7}.Release|Any CPU.ActiveCfg = Release|Any CPU {4A93E1A2-B61E-31B2-33F2-478156A9B5E7}.Release|Any CPU.Build.0 = Release|Any CPU + {53EBA540-F6CF-0715-1F62-241A53F537EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {53EBA540-F6CF-0715-1F62-241A53F537EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {53EBA540-F6CF-0715-1F62-241A53F537EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {53EBA540-F6CF-0715-1F62-241A53F537EC}.Release|Any CPU.Build.0 = Release|Any CPU + {FB4ED3AA-A12E-4192-861F-4B025876AA0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FB4ED3AA-A12E-4192-861F-4B025876AA0F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FB4ED3AA-A12E-4192-861F-4B025876AA0F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FB4ED3AA-A12E-4192-861F-4B025876AA0F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -574,6 +585,8 @@ Global {F422398C-72CD-43EA-AC8E-E0DBD08E5563} = {BB874DF1-44FE-415A-B634-A6B829107890} {8CE782A2-7374-4916-9C69-1F87E51A64A9} = {6AEE1440-FDF0-4729-8196-B24D0E333550} {4A93E1A2-B61E-31B2-33F2-478156A9B5E7} = {E7F15C9C-3928-47AD-8462-64FD29FFCA54} + {53EBA540-F6CF-0715-1F62-241A53F537EC} = {6AEE1440-FDF0-4729-8196-B24D0E333550} + {FB4ED3AA-A12E-4192-861F-4B025876AA0F} = {6AEE1440-FDF0-4729-8196-B24D0E333550} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {31E0F4D5-975A-41CC-933E-545B2201FAF9} diff --git a/eng/Analyzers.props b/eng/Analyzers.props index a9699b919e..1283f82e91 100644 --- a/eng/Analyzers.props +++ b/eng/Analyzers.props @@ -12,7 +12,6 @@ - diff --git a/eng/stylecop.json b/eng/stylecop.json deleted file mode 100644 index 219f294da1..0000000000 --- a/eng/stylecop.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "$schema": "https://raw.githubusercontent.com/DotNetAnalyzers/StyleCopAnalyzers/master/StyleCop.Analyzers/StyleCop.Analyzers/Settings/stylecop.schema.json", - "settings": { - "documentationRules": { - "companyName": "Microsoft Corporation", - "copyrightText": "Copyright (c) {companyName}. All rights reserved.\nLicensed under the MIT license. See LICENSE file in the project root for full license information.", - "xmlHeader": false, - "fileNamingConvention": "metadata" - } - } -} diff --git a/eng/stylecop.ruleset b/eng/stylecop.ruleset deleted file mode 100644 index bba4a0b95c..0000000000 --- a/eng/stylecop.ruleset +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/eng/stylecop.test.ruleset b/eng/stylecop.test.ruleset deleted file mode 100644 index 40fc485f7c..0000000000 --- a/eng/stylecop.test.ruleset +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/.editorconfig b/src/Platform/Microsoft.Testing.Extensions.HotReload/.editorconfig new file mode 100644 index 0000000000..7d7bac49f4 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/.editorconfig @@ -0,0 +1,2 @@ +[*.{cs,vb}] +file_header_template = Copyright (c) Microsoft Corporation. All rights reserved.\nLicensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/BannedSymbols.txt b/src/Platform/Microsoft.Testing.Extensions.HotReload/BannedSymbols.txt new file mode 100644 index 0000000000..5bc5c2fb96 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/BannedSymbols.txt @@ -0,0 +1,10 @@ +T:System.ArgumentNullException; Use 'Guard' instead +P:System.DateTime.Now; Use 'IClock' instead +P:System.DateTime.UtcNow; Use 'IClock' instead +M:System.Threading.Tasks.Task.Run(System.Action); Use 'ITask' instead +M:System.Threading.Tasks.Task.WhenAll(System.Threading.Tasks.Task[]); Use 'ITask' instead +M:System.Threading.Tasks.Task.WhenAll(System.Collections.Generic.IEnumerable{System.Threading.Tasks.Task}); Use 'ITask' instead +M:System.String.IsNullOrEmpty(System.String); Use 'RoslynString.IsNullOrEmpty' instead +M:System.String.IsNullOrWhiteSpace(System.String); Use 'RoslynString.IsNullOrWhiteSpace' instead +M:System.Diagnostics.Debug.Assert(System.Boolean); Use 'RoslynDebug.Assert' instead +M:System.Diagnostics.Debug.Assert(System.Boolean,System.String); Use 'RoslynDebug.Assert' instead diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadExtensions.cs b/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadExtensions.cs new file mode 100644 index 0000000000..c0578a889b --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadExtensions.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Extensions.Hosting; +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.TestHost; + +namespace Microsoft.Testing.Extensions; + +public static class HotReloadExtensions +{ + public static void AddHotReloadProvider(this ITestApplicationBuilder builder) + => ((TestHostManager)builder.TestHost).AddTestFrameworkInvoker(serviceProvider => + new HotReloadTestHostTestFrameworkInvoker(serviceProvider)); +} diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadHandler.cs b/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadHandler.cs new file mode 100644 index 0000000000..669ee80882 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadHandler.cs @@ -0,0 +1,91 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Extensions.Hosting.Resources; +using Microsoft.Testing.Platform.Extensions.OutputDevice; +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.OutputDevice; + +#if NETCOREAPP +using System.Reflection.Metadata; + +using Microsoft.Testing.Extensions.Hosting; + +[assembly: MetadataUpdateHandler(typeof(HotReloadHandler))] +#endif + +namespace Microsoft.Testing.Extensions.Hosting; + +internal sealed class HotReloadHandler +{ + private static readonly SemaphoreSlim SemaphoreSlim = new(1, 1); + private static bool s_shutdownProcess; + private readonly IConsole _console; + private readonly IOutputDevice _outputDevice; + private readonly IOutputDeviceDataProducer _outputDeviceDataProducer; + + public HotReloadHandler(IConsole console, IOutputDevice outputDevice, IOutputDeviceDataProducer outputDeviceDataProducer) + { + _console = console; + _outputDevice = outputDevice; + _outputDeviceDataProducer = outputDeviceDataProducer; + _console.CancelKeyPress += (_, _) => + { + if (!s_shutdownProcess) + { + s_shutdownProcess = true; + SemaphoreSlim.Release(); + } + }; + } + + // Called automatically by the runtime through the MetadataUpdateHandlerAttribute + public static void ClearCache(Type[]? _) + { + } + + // Called automatically by the runtime through the MetadataUpdateHandlerAttribute + public static void UpdateApplication(Type[]? _) => SemaphoreSlim.Release(); + +#if !NET6_0_OR_GREATER + public Task ShouldRunAsync(Task? waitExecutionCompletion, CancellationToken cancellationToken) + { + // Avoid warnings about unused parameters and fields. + _ = _outputDevice; + _ = _outputDeviceDataProducer; + _ = waitExecutionCompletion; + _ = cancellationToken; + throw new NotSupportedException(ExtensionResources.HotReloadHandlerUnsupportedFrameworkErrorMessage); + } +#else + public async Task ShouldRunAsync(Task? waitExecutionCompletion, CancellationToken cancellationToken) + { + if (s_shutdownProcess) + { + return false; + } + + cancellationToken.Register(() => s_shutdownProcess = true); + + if (waitExecutionCompletion is not null) + { + await waitExecutionCompletion; + await _outputDevice!.DisplayAsync(_outputDeviceDataProducer, new TextOutputDeviceData(ExtensionResources.HotReloadSessionCompleted)); + } + + try + { + await SemaphoreSlim.WaitAsync(cancellationToken); + } + catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) + { + // We're closing + } + + _console!.Clear(); + await _outputDevice.DisplayAsync(_outputDeviceDataProducer, new TextOutputDeviceData(ExtensionResources.HotReloadSessionStarted)); + + return !s_shutdownProcess; + } +#endif +} diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadTestHostTestFrameworkInvoker.cs b/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadTestHostTestFrameworkInvoker.cs new file mode 100644 index 0000000000..df6c08a9d4 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/HotReloadTestHostTestFrameworkInvoker.cs @@ -0,0 +1,68 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.Messages; +using Microsoft.Testing.Platform.OutputDevice; +using Microsoft.Testing.Platform.Requests; +using Microsoft.Testing.Platform.Services; + +namespace Microsoft.Testing.Extensions.Hosting; + +internal sealed class HotReloadTestHostTestFrameworkInvoker : TestHostTestFrameworkInvoker +{ + private readonly bool _isHotReloadEnabled; + + public HotReloadTestHostTestFrameworkInvoker(IServiceProvider serviceProvider) + : base(serviceProvider) + { + _isHotReloadEnabled = IsHotReloadEnabled(serviceProvider.GetEnvironment()); + if (_isHotReloadEnabled) + { + ((SystemRuntimeFeature)serviceProvider.GetRuntimeFeature()).EnableHotReload(); + } + } + + private static bool IsHotReloadEnabled(IEnvironment environment) + => environment.GetEnvironmentVariable(EnvironmentVariableConstants.DOTNET_WATCH) == "1" + || environment.GetEnvironmentVariable(EnvironmentVariableConstants.TESTINGPLATFORM_HOTRELOAD_ENABLED) == "1"; + + public override async Task ExecuteRequestAsync(ITestFramework testFrameworkAdapter, TestExecutionRequest request, + IMessageBus messageBus, CancellationToken cancellationToken) + { + if (!_isHotReloadEnabled) + { + await base.ExecuteRequestAsync(testFrameworkAdapter, request, messageBus, cancellationToken); + return; + } + + // Using the output device here rather than Console WriteLine ensures that we don't break live logger output. + IOutputDevice outputDevice = ServiceProvider.GetOutputDevice(); + var hotReloadHandler = new HotReloadHandler(ServiceProvider.GetConsole(), outputDevice, this); + TaskCompletionSource? executionCompleted = null; + while (await hotReloadHandler.ShouldRunAsync(executionCompleted?.Task, ServiceProvider.GetTestApplicationCancellationTokenSource().CancellationToken)) + { + executionCompleted = new(); + using SemaphoreSlim requestSemaphore = new(1); + var hotReloadOutputDevice = ServiceProvider.GetPlatformOutputDevice() as IHotReloadPlatformOutputDevice; + if (hotReloadOutputDevice is not null) + { + await hotReloadOutputDevice.DisplayBeforeHotReloadSessionStartAsync(); + } + +#pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + await testFrameworkAdapter.ExecuteRequestAsync(new(request, messageBus, new SemaphoreSlimRequestCompleteNotifier(requestSemaphore), cancellationToken)); +#pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + + await requestSemaphore.WaitAsync(cancellationToken); + await ServiceProvider.GetBaseMessageBus().DrainDataAsync(); + if (hotReloadOutputDevice is not null) + { + await hotReloadOutputDevice.DisplayAfterHotReloadSessionEndAsync(); + } + + executionCompleted.SetResult(0); + } + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Microsoft.Testing.Extensions.HotReload.csproj b/src/Platform/Microsoft.Testing.Extensions.HotReload/Microsoft.Testing.Extensions.HotReload.csproj new file mode 100644 index 0000000000..a7e8e9b6f7 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Microsoft.Testing.Extensions.HotReload.csproj @@ -0,0 +1,61 @@ + + + + netstandard2.0;$(MicrosoftTestingTargetFrameworks) + Microsoft.Testing.Extensions.Hosting + + + License.txt + + + + + + + + + + + + + + + + + + + + true + buildMultiTargeting + + + + buildTransitive/$(TargetFramework) + + + build/$(TargetFramework) + + + + + + + + + + True + True + ExtensionResources.resx + + + + + + ResXFileCodeGenerator + ExtensionResources.Designer.cs + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/PACKAGE.md b/src/Platform/Microsoft.Testing.Extensions.HotReload/PACKAGE.md new file mode 100644 index 0000000000..7975720586 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/PACKAGE.md @@ -0,0 +1,9 @@ +# Microsoft.Testing + +Microsoft Testing is a set of platform, framework and protocol intended to make it possible to run any test on any target or device. + +Documentation can be found at . + +## About + +This package extends Microsoft Testing Platform to provide Hot Reload support. diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/PublicAPI/PublicAPI.Shipped.txt b/src/Platform/Microsoft.Testing.Extensions.HotReload/PublicAPI/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..16e56fe341 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/PublicAPI/PublicAPI.Shipped.txt @@ -0,0 +1,5 @@ +#nullable enable +Microsoft.Testing.Extensions.HotReload.TestingPlatformBuilderHook +Microsoft.Testing.Extensions.HotReloadExtensions +static Microsoft.Testing.Extensions.HotReload.TestingPlatformBuilderHook.AddExtensions(Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! testApplicationBuilder, string![]! _) -> void +static Microsoft.Testing.Extensions.HotReloadExtensions.AddHotReloadProvider(this Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! builder) -> void diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/PublicAPI/PublicAPI.Unshipped.txt b/src/Platform/Microsoft.Testing.Extensions.HotReload/PublicAPI/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/PublicAPI/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/ExtensionResources.Designer.cs b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/ExtensionResources.Designer.cs new file mode 100644 index 0000000000..4e6bc289c6 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/ExtensionResources.Designer.cs @@ -0,0 +1,90 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.Testing.Extensions.Hosting.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class ExtensionResources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal ExtensionResources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Testing.Extensions.Hosting.Resources.ExtensionResources", typeof(ExtensionResources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Hot reload is only supported on .NET 6.0 or greater. + /// + internal static string HotReloadHandlerUnsupportedFrameworkErrorMessage { + get { + return ResourceManager.GetString("HotReloadHandlerUnsupportedFrameworkErrorMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hot reload test session completed. + /// + internal static string HotReloadSessionCompleted { + get { + return ResourceManager.GetString("HotReloadSessionCompleted", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Hot reload test session started. + /// + internal static string HotReloadSessionStarted { + get { + return ResourceManager.GetString("HotReloadSessionStarted", resourceCulture); + } + } + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/ExtensionResources.resx b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/ExtensionResources.resx new file mode 100644 index 0000000000..931f443665 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/ExtensionResources.resx @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hot reload is only supported on .NET 6.0 or greater + + + Hot reload test session completed + + + Hot reload test session started + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf new file mode 100644 index 0000000000..bf24eb49fe --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + Opětovné načítání za provozu se podporuje pouze v rozhraní .NET 6.0 nebo novějším. + + + + Hot reload test session completed + Testovací relace opětovného načítání za provozu byla dokončena. + + + + Hot reload test session started + Testovací relace opětovného načítání za provozu byla spuštěna. + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf new file mode 100644 index 0000000000..426d75c690 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + Hot Reload wird nur unter .NET 6.0 oder höher unterstützt. + + + + Hot reload test session completed + Hot Reload-Testsitzung abgeschlossen + + + + Hot reload test session started + Hot Reload-Testsitzung gestartet + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf new file mode 100644 index 0000000000..e014452c97 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + La recarga activa solo se admite en .NET 6.0 o posterior + + + + Hot reload test session completed + Sesión de prueba de recarga activa completada + + + + Hot reload test session started + Se inició la sesión de prueba de recarga activa + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf new file mode 100644 index 0000000000..311d81deac --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + Le rechargement à chaud est uniquement pris en charge sur .NET 6.0 ou version ultérieure + + + + Hot reload test session completed + Session de test de rechargement à chaud terminée + + + + Hot reload test session started + Session de test de rechargement à chaud démarrée + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf new file mode 100644 index 0000000000..f8c8801628 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + Il ricaricamento rapido è supportato solo in .NET 6.0 o versione successiva + + + + Hot reload test session completed + Sessione di test di ricaricamento rapido completata + + + + Hot reload test session started + Sessione di test di ricaricamento rapido avviata + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf new file mode 100644 index 0000000000..73be365a65 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + ホット リロードは .NET 6.0 以降でのみサポートされています + + + + Hot reload test session completed + ホット リロード テスト セッションが完了しました + + + + Hot reload test session started + ホット リロード テスト セッションが開始されました + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf new file mode 100644 index 0000000000..6dbdebaba2 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + 핫 다시 로드는 .NET 6.0 이상에서만 지원됩니다. + + + + Hot reload test session completed + 핫 다시 로드 테스트 세션 완료 + + + + Hot reload test session started + 핫 다시 로드 테스트 세션 시작됨 + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf new file mode 100644 index 0000000000..5b74462a80 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + Ponowne ładowanie na gorąco jest obsługiwane tylko na platformie .NET 6.0 lub nowszej + + + + Hot reload test session completed + Sesja testu ponownego ładowania na gorąco została ukończona + + + + Hot reload test session started + Rozpoczęto sesję testu ponownego ładowania na gorąco + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf new file mode 100644 index 0000000000..743f052c79 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + Só há suporte para a recarga dinâmica no .NET 6.0 ou superior + + + + Hot reload test session completed + Sessão de teste de recarga dinâmica concluída + + + + Hot reload test session started + Sessão de teste de recarga dinâmica iniciada + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf new file mode 100644 index 0000000000..1f26adfb86 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + Горячая перезагрузка поддерживается только в версии .NET 6.0 или более поздних версиях + + + + Hot reload test session completed + Тестовый сеанс горячей перезагрузки завершен + + + + Hot reload test session started + Запущен тестовый сеанс горячей перезагрузки + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf new file mode 100644 index 0000000000..70125a0e05 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + Çalışırken yeniden yükleme yalnızca .NET 6.0 veya üzeri sürümlerde desteklenir + + + + Hot reload test session completed + Çalışırken yeniden yükleme test oturumu tamamlandı + + + + Hot reload test session started + Çalışırken yeniden yükleme test oturumu başlatıldı + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf new file mode 100644 index 0000000000..af518ebd73 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + 仅 .NET 6.0 或更高版本支持热重载 + + + + Hot reload test session completed + 热重载测试会话已完成 + + + + Hot reload test session started + 热重载测试会话已启动 + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf new file mode 100644 index 0000000000..0fd9224ca7 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf @@ -0,0 +1,22 @@ + + + + + + Hot reload is only supported on .NET 6.0 or greater + 只有 .NET 6.0 或更新版本才支援熱重新載入 + + + + Hot reload test session completed + 熱重新載入測試工作階段已完成 + + + + Hot reload test session started + 熱重新載入測試工作階段已開始 + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/TestingPlatformBuilderHook.cs b/src/Platform/Microsoft.Testing.Extensions.HotReload/TestingPlatformBuilderHook.cs new file mode 100644 index 0000000000..b76e5d5b53 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/TestingPlatformBuilderHook.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Platform.Builder; + +namespace Microsoft.Testing.Extensions.HotReload; + +public static class TestingPlatformBuilderHook +{ + public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, string[] _) + => testApplicationBuilder.AddHotReloadProvider(); +} diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/build/Microsoft.Testing.Extensions.HotReload.props b/src/Platform/Microsoft.Testing.Extensions.HotReload/build/Microsoft.Testing.Extensions.HotReload.props new file mode 100644 index 0000000000..aaa0f36baa --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/build/Microsoft.Testing.Extensions.HotReload.props @@ -0,0 +1,3 @@ + + + diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/buildMultiTargeting/Microsoft.Testing.Extensions.HotReload.props b/src/Platform/Microsoft.Testing.Extensions.HotReload/buildMultiTargeting/Microsoft.Testing.Extensions.HotReload.props new file mode 100644 index 0000000000..7fccd7490e --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/buildMultiTargeting/Microsoft.Testing.Extensions.HotReload.props @@ -0,0 +1,9 @@ + + + + + Microsoft.Testing.Extensions.HotReload + Microsoft.Testing.Extensions.HotReload.TestingPlatformBuilderHook + + + diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/buildTransitive/Microsoft.Testing.Extensions.HotReload.props b/src/Platform/Microsoft.Testing.Extensions.HotReload/buildTransitive/Microsoft.Testing.Extensions.HotReload.props new file mode 100644 index 0000000000..aaa0f36baa --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/buildTransitive/Microsoft.Testing.Extensions.HotReload.props @@ -0,0 +1,3 @@ + + + diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/.editorconfig b/src/Platform/Microsoft.Testing.Extensions.Retry/.editorconfig new file mode 100644 index 0000000000..7d7bac49f4 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/.editorconfig @@ -0,0 +1,2 @@ +[*.{cs,vb}] +file_header_template = Copyright (c) Microsoft Corporation. All rights reserved.\nLicensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/BannedSymbols.txt b/src/Platform/Microsoft.Testing.Extensions.Retry/BannedSymbols.txt new file mode 100644 index 0000000000..5bc5c2fb96 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/BannedSymbols.txt @@ -0,0 +1,10 @@ +T:System.ArgumentNullException; Use 'Guard' instead +P:System.DateTime.Now; Use 'IClock' instead +P:System.DateTime.UtcNow; Use 'IClock' instead +M:System.Threading.Tasks.Task.Run(System.Action); Use 'ITask' instead +M:System.Threading.Tasks.Task.WhenAll(System.Threading.Tasks.Task[]); Use 'ITask' instead +M:System.Threading.Tasks.Task.WhenAll(System.Collections.Generic.IEnumerable{System.Threading.Tasks.Task}); Use 'ITask' instead +M:System.String.IsNullOrEmpty(System.String); Use 'RoslynString.IsNullOrEmpty' instead +M:System.String.IsNullOrWhiteSpace(System.String); Use 'RoslynString.IsNullOrWhiteSpace' instead +M:System.Diagnostics.Debug.Assert(System.Boolean); Use 'RoslynDebug.Assert' instead +M:System.Diagnostics.Debug.Assert(System.Boolean,System.String); Use 'RoslynDebug.Assert' instead diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj b/src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj new file mode 100644 index 0000000000..d2a73307d6 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Microsoft.Testing.Extensions.Retry.csproj @@ -0,0 +1,65 @@ + + + + netstandard2.0;$(MicrosoftTestingTargetFrameworks) + Microsoft.Testing.Extensions.Policy + + + License.txt + + + + + + + + + + + + + + + + + + + + + true + buildMultiTargeting + + + buildTransitive/$(TargetFramework) + + + build/$(TargetFramework) + + + + + + + + + + True + True + ExtensionResources.resx + + + + + + ResXFileCodeGenerator + ExtensionResources.Designer.cs + + + + + + + + diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/PACKAGE.md b/src/Platform/Microsoft.Testing.Extensions.Retry/PACKAGE.md new file mode 100644 index 0000000000..1d728ad78d --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/PACKAGE.md @@ -0,0 +1,9 @@ +# Microsoft.Testing + +Microsoft Testing is a set of platform, framework and protocol intended to make it possible to run any test on any target or device. + +Documentation can be found at . + +## About + +This package extends Microsoft Testing Platform to provide a retry policy system that allows to restart tests on failure. diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/PublicAPI/PublicAPI.Shipped.txt b/src/Platform/Microsoft.Testing.Extensions.Retry/PublicAPI/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..2162ba1c98 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/PublicAPI/PublicAPI.Shipped.txt @@ -0,0 +1,5 @@ +#nullable enable +Microsoft.Testing.Extensions.Retry.TestingPlatformBuilderHook +Microsoft.Testing.Extensions.RetryExtensions +static Microsoft.Testing.Extensions.Retry.TestingPlatformBuilderHook.AddExtensions(Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! testApplicationBuilder, string![]! _) -> void +static Microsoft.Testing.Extensions.RetryExtensions.AddRetryProvider(this Microsoft.Testing.Platform.Builder.ITestApplicationBuilder! builder) -> void diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/PublicAPI/PublicAPI.Unshipped.txt b/src/Platform/Microsoft.Testing.Extensions.Retry/PublicAPI/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/PublicAPI/PublicAPI.Unshipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RandomId.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RandomId.cs new file mode 100644 index 0000000000..1f1181702a --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RandomId.cs @@ -0,0 +1,44 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +// Copy from https://github.com/microsoft/testfx/blob/b769496b8992bf8f51e000f7a5626b5ec6bb3d27/test/Utilities/Microsoft.Testing.TestInfrastructure/RandomId.cs +using System.Security.Cryptography; + +namespace Microsoft.Testing.Extensions; + +/// +/// Slightly random id that is just good enough for creating distinct directories for each test. +/// +internal static class RandomId +{ + private const string Pool = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + private static readonly RandomNumberGenerator Rng = RandomNumberGenerator.Create(); + + /// + /// 5 character long id from 0-9A-Za-z0, for example fUfko, A6uvM, sOMXa, RY1ei, KvdJZ. + /// + public static string Next() => Next(5); + + private static string Next(int length) + { + int poolLength = Pool.Length; + char[] id = new char[length]; + lock (Pool) + { + for (int idIndex = 0; idIndex < length; idIndex++) + { + int poolIndex = poolLength + 1; + while (poolIndex >= poolLength) + { + byte[] bytes = new byte[1]; + Rng.GetNonZeroBytes(bytes); + poolIndex = bytes[0]; + } + + id[idIndex] = Pool[poolIndex]; + } + } + + return new string(id); + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/ExtensionResources.Designer.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/ExtensionResources.Designer.cs new file mode 100644 index 0000000000..79b07ef2dc --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/ExtensionResources.Designer.cs @@ -0,0 +1,284 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Microsoft.Testing.Extensions.Policy.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class ExtensionResources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal ExtensionResources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Testing.Extensions.Policy.Resources.ExtensionResources", typeof(ExtensionResources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Failed to create retries directory due to collisions in '{0}' despite re-trying.. + /// + internal static string FailedToCreateRetryDirectoryBecauseOfCollision { + get { + return ResourceManager.GetString("FailedToCreateRetryDirectoryBecauseOfCollision", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Failure threshold policy is enabled, failed tests will not be restarted.. + /// + internal static string FailureThresholdPolicy { + get { + return ResourceManager.GetString("FailureThresholdPolicy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Maximum failed tests threshold is {0} and {1} tests failed. + /// + internal static string FailureThresholdPolicyMaxCount { + get { + return ResourceManager.GetString("FailureThresholdPolicyMaxCount", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}). + /// + internal static string FailureThresholdPolicyMaxPercentage { + get { + return ResourceManager.GetString("FailureThresholdPolicyMaxPercentage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to + ///===================== + ///Moving last attempt asset files to the default result directory + ///===================== + ///. + /// + internal static string MoveFiles { + get { + return ResourceManager.GetString("MoveFiles", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Moving file '{0}' to '{1}'. + /// + internal static string MovingFileToLocation { + get { + return ResourceManager.GetString("MovingFileToLocation", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Failed to start process '{0}'. + /// + internal static string RetryFailedTestsCannotStartProcessErrorMessage { + get { + return ResourceManager.GetString("RetryFailedTestsCannotStartProcessErrorMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Retry failed tests feature allows to restart test execution upon failure.. + /// + internal static string RetryFailedTestsExtensionDescription { + get { + return ResourceManager.GetString("RetryFailedTestsExtensionDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Retry failed tests. + /// + internal static string RetryFailedTestsExtensionDisplayName { + get { + return ResourceManager.GetString("RetryFailedTestsExtensionDisplayName", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder'. + /// + internal static string RetryFailedTestsInvalidTestApplicationBuilderErrorMessage { + get { + return ResourceManager.GetString("RetryFailedTestsInvalidTestApplicationBuilderErrorMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Disable retry mechanism if the percentage of failed tests is greater than the specified value. + /// + internal static string RetryFailedTestsMaxPercentageOptionDescription { + get { + return ResourceManager.GetString("RetryFailedTestsMaxPercentageOptionDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Disable retry mechanism if the number of failed tests is greater than the specified value. + /// + internal static string RetryFailedTestsMaxTestsOptionDescription { + get { + return ResourceManager.GetString("RetryFailedTestsMaxTestsOptionDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Retry failed tests feature is not supported in hot reload mode. + /// + internal static string RetryFailedTestsNotSupportedInHotReloadErrorMessage { + get { + return ResourceManager.GetString("RetryFailedTestsNotSupportedInHotReloadErrorMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Retry failed tests feature is not supported in server mode. + /// + internal static string RetryFailedTestsNotSupportedInServerModeErrorMessage { + get { + return ResourceManager.GetString("RetryFailedTestsNotSupportedInServerModeErrorMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Enable retry failed tests. + /// + internal static string RetryFailedTestsOptionDescription { + get { + return ResourceManager.GetString("RetryFailedTestsOptionDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Option '{0}' requires option '{1}' to be specified. + /// + internal static string RetryFailedTestsOptionIsMissingErrorMessage { + get { + return ResourceManager.GetString("RetryFailedTestsOptionIsMissingErrorMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Option '{0}' expects a single integer argument. + /// + internal static string RetryFailedTestsOptionSingleIntegerArgumentErrorMessage { + get { + return ResourceManager.GetString("RetryFailedTestsOptionSingleIntegerArgumentErrorMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Options '{0}' and '{1}' cannot be used together. + /// + internal static string RetryFailedTestsPercentageAndCountCannotBeMixedErrorMessage { + get { + return ResourceManager.GetString("RetryFailedTestsPercentageAndCountCannotBeMixedErrorMessage", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Test host process exited before the retry service could connect to it. Exit code: {0}. + /// + internal static string TestHostProcessExitedBeforeRetryCouldConnect { + get { + return ResourceManager.GetString("TestHostProcessExitedBeforeRetryCouldConnect", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to + ///===================== + ///Tests suite completed successfully in {0} attempts + ///=====================. + /// + internal static string TestSuiteCompletedSuccessfully { + get { + return ResourceManager.GetString("TestSuiteCompletedSuccessfully", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to + ///===================== + ///Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} + ///===================== + ///. + /// + internal static string TestSuiteFailed { + get { + return ResourceManager.GetString("TestSuiteFailed", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to + ///===================== + ///Tests suite failed in all {0} attempts + ///=====================. + /// + internal static string TestSuiteFailedInAllAttempts { + get { + return ResourceManager.GetString("TestSuiteFailedInAllAttempts", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}'. + /// + internal static string TestSuiteFailedWithWrongExitCode { + get { + return ResourceManager.GetString("TestSuiteFailedWithWrongExitCode", resourceCulture); + } + } + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/ExtensionResources.resx b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/ExtensionResources.resx new file mode 100644 index 0000000000..65122496a7 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/ExtensionResources.resx @@ -0,0 +1,204 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + + + Maximum failed tests threshold is {0} and {1} tests failed + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + + + Moving file '{0}' to '{1}' + + + Failed to start process '{0}' + + + Retry failed tests feature allows to restart test execution upon failure. + + + Retry failed tests + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + + + Disable retry mechanism if the number of failed tests is greater than the specified value + + + Retry failed tests feature is not supported in hot reload mode + + + Retry failed tests feature is not supported in server mode + + + Enable retry failed tests + + + Option '{0}' requires option '{1}' to be specified + + + Option '{0}' expects a single integer argument + + + Options '{0}' and '{1}' cannot be used together + + + Test host process exited before the retry service could connect to it. Exit code: {0} + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + + + +===================== +Tests suite failed in all {0} attempts +===================== + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf new file mode 100644 index 0000000000..fa82dcccef --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + Nepovedlo se vytvořit adresář opakovaných pokusů kvůli kolizím v adresáři {0}, a to ani přes opakované pokusy. + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + Je povolena zásada prahové hodnoty selhání, neúspěšné testy se nerestartují. + + + + Maximum failed tests threshold is {0} and {1} tests failed + Prahová hodnota maximálního počtu neúspěšných testů je {0} a tento počet testů selhal: {1}. + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Procentuální prahová hodnota selhání je {0} % a toto procento testů selhalo: {1} % ({2}/{3}). + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +Přesouvání souborů prostředků posledního pokusu do výchozího adresáře výsledků +===================== + + + + + Moving file '{0}' to '{1}' + Soubor {0} se přesouvá do umístění {1}. + + + + Failed to start process '{0}' + Nepovedlo se spustit proces {0}. + + + + Retry failed tests feature allows to restart test execution upon failure. + Funkce opakování neúspěšných testů umožňuje po selhání znovu spustit test. + + + + Retry failed tests + Opakovat neúspěšné testy + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Opakování neúspěšných testů funguje pouze s tvůrci typu Microsoft.Testing.Platform.Builder.TestApplicationBuilder. + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + Zakázat mechanismus opakování, pokud je procento neúspěšných testů větší než zadaná hodnota + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + Zakázat mechanismus opakování, pokud je počet neúspěšných testů větší než zadaná hodnota + + + + Retry failed tests feature is not supported in hot reload mode + Funkce opakování neúspěšných testů není v režimu opětovného načítání za provozu podporovaná. + + + + Retry failed tests feature is not supported in server mode + Funkce opakování neúspěšných testů není v režimu serveru podporovaná. + + + + Enable retry failed tests + Povolit opakování neúspěšných testů + + + + Option '{0}' requires option '{1}' to be specified + Možnost {0} vyžaduje, aby byla zadaná možnost {1}. + + + + Option '{0}' expects a single integer argument + Možnost {0} očekává jeden celočíselný argument. + + + + Options '{0}' and '{1}' cannot be used together + Možnost {0} nelze používat společně s možností {1}. + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + Hostitelský proces testu byl ukončen dříve, než se k němu mohla služba opakování připojit. Ukončovací kód: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +Sada testů byla úspěšně dokončena při {0} pokusech +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +Sada testů selhala, celkový počet neúspěšných testů: {0}, ukončovací kód: {1}, pokus: {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +Sada testů selhala při všech {0} pokusech +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Sada testů neproběhla úspěšně a ukončovací kód je jiný než 2 (neúspěšné testy). Selhání související s neočekávanou podmínkou. Ukončovací kód: {0} + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf new file mode 100644 index 0000000000..c7e44a2b31 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + Fehler beim Erstellen des Wiederholungsverzeichnisses aufgrund von Konflikten in „{0}“ trotz erneuter Versuche. + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + Wenn die Richtlinie für fehlgeschlagene Tests aktiviert ist, werden fehlgeschlagene Tests nicht neu gestartet. + + + + Maximum failed tests threshold is {0} and {1} tests failed + Der Schwellenwert für die maximale Anzahl fehlerhafter Tests ist {0} und {1} Tests mit Fehlern + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Der Schwellenwert für den Prozentsatz fehlgeschlagener Tests ist {0} %, und {1} % Tests mit Fehlern ({2}/{3}) + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +Medienobjektdateien des letzten Versuchs werden in das Standardergebnisverzeichnis verschoben. +===================== + + + + + Moving file '{0}' to '{1}' + Die Datei "{0}" wird nach "{1}" verschoben + + + + Failed to start process '{0}' + Fehler beim Starten von Prozess "{0}". + + + + Retry failed tests feature allows to restart test execution upon failure. + Das Feature zum Wiederholen fehlerhafter Tests ermöglicht es, die Testausführung bei einem Fehler neu zu starten. + + + + Retry failed tests + Tests mit Wiederholungsfehlern + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Das Wiederholen fehlerhafter Tests funktioniert nur mit Generatoren vom Typ "Microsoft.Testing.Platform.Builder.TestApplicationBuilder". + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + Wiederholungsmechanismus deaktivieren, wenn der Prozentsatz fehlerhafter Tests größer als der angegebene Wert ist + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + Wiederholungsmechanismus deaktivieren, wenn die Anzahl fehlerhafter Tests größer als der angegebene Wert ist + + + + Retry failed tests feature is not supported in hot reload mode + Das Feature zum Wiederholen fehlerhafter Tests wird im Hot Reload-Modus nicht unterstützt + + + + Retry failed tests feature is not supported in server mode + Das Feature zum Wiederholen fehlerhafter Tests wird im Servermodus nicht unterstützt + + + + Enable retry failed tests + Tests mit Wiederholungsfehlern aktivieren + + + + Option '{0}' requires option '{1}' to be specified + Die "{0}"-Option erfordert, dass "{1}" angegeben ist + + + + Option '{0}' expects a single integer argument + Option "{0}" erwartet ein einzelnes ganzzahliges Argument + + + + Options '{0}' and '{1}' cannot be used together + Optionen "{0}" und "{1}" können nicht zusammen verwendet werden + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + Der Testhostprozess wurde beendet, bevor der Wiederholungsdienst eine Verbindung herstellen konnte. Exitcode: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +Die Testsammlung wurde in {0} Versuchen erfolgreich abgeschlossen. +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +Fehler bei der Testsammlung. Fehlerhafte Tests gesamt: {0}, Exitcode: {1}, Versuch: {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +Fehler bei der Testsammlung bei allen {0} Versuchen. +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Bei der Testsammlung ist ein Fehler aufgetreten, und der Exitcode unterscheidet sich von 2 (fehlgeschlagene Tests). Fehler im Zusammenhang mit einer unerwarteten Bedingung. Exitcode "{0}" + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf new file mode 100644 index 0000000000..5e008904ad --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf @@ -0,0 +1,151 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + No se pudo crear el directorio de reintentos debido a colisiones en '{0}' a pesar de volver a intentarlo. + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + La directiva de umbral de errores está habilitada; no se reiniciarán las pruebas con errores. + + + + Maximum failed tests threshold is {0} and {1} tests failed + El umbral máximo de pruebas con errores es {0} y {1} pruebas erróneas + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + El umbral de porcentaje de errores es {0}% y {1}% de pruebas no superadas ({2}/{3}) + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +======================== +Moviendo los archivos de recursos del último intento al directorio de resultados predeterminado +======================== + + + + + Moving file '{0}' to '{1}' + Moviendo el archivo '{0}' a '{1}' + + + + Failed to start process '{0}' + No se pudo iniciar el proceso '{0}' + + + + Retry failed tests feature allows to restart test execution upon failure. + La característica Reintentar pruebas con errores permite reiniciar la ejecución de pruebas en caso de error. + + + + Retry failed tests + Reintentar pruebas con errores + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Reintentar pruebas con errores solo funciona con generadores de tipo "Microsoft.Testing.Platform.Builder.TestApplicationBuilder" + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + Deshabilitar el mecanismo de reintento si el porcentaje de pruebas con errores es mayor que el valor especificado + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + Deshabilitar el mecanismo de reintento si el número de pruebas con errores es mayor que el valor especificado + + + + Retry failed tests feature is not supported in hot reload mode + La característica Reintentar pruebas con errores no se admite en el modo de recarga activa + + + + Retry failed tests feature is not supported in server mode + La característica reintentar pruebas con errores no se admite en el modo de servidor + + + + Enable retry failed tests + Habilitar pruebas con errores de reintento + + + + Option '{0}' requires option '{1}' to be specified + La opción '{0}' requiere que se especifique la opción '{1}' + + + + Option '{0}' expects a single integer argument + La opción '{0}' espera un único argumento entero + + + + Options '{0}' and '{1}' cannot be used together + Las opciones '{0}' y '{1}' no se pueden usar juntas + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + El proceso de host de prueba se cerró antes de que el servicio de reintento pudiera conectarse a él. Código de salida: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +======================== +El conjunto de pruebas se completó correctamente en {0} intentos +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +======================== +Error del conjunto de pruebas, total de pruebas erróneas: {0}, código de salida: {1}, intento: {2}/{3} +======================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +======================== +Error del conjunto de pruebas en todos los + intentos{0} +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Error del conjunto de pruebas con el código de salida distinto de 2 (pruebas con error). Error relacionado con una condición inesperada. Código de salida ''{0}'' + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf new file mode 100644 index 0000000000..debdb1c84f --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + Échec de la création du répertoire des nouvelles tentatives en raison de collisions dans « {0} » malgré une nouvelle tentative. + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + La stratégie de seuil d’échec est activée, les tests ayant échoué ne seront pas redémarrés. + + + + Maximum failed tests threshold is {0} and {1} tests failed + Le seuil maximal des tests ayant échoué est {0} et {1} tests ont échoué + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Le seuil de pourcentage d’échec est {0}% et {1}% de tests ont échoué ({2}/{3}) + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +Déplacement des fichiers de ressources de la dernière tentative vers le répertoire de résultats par défaut +===================== + + + + + Moving file '{0}' to '{1}' + Déplacement du fichier '{0}' vers '{1}' + + + + Failed to start process '{0}' + Échec de démarrage du processus « {0} » + + + + Retry failed tests feature allows to restart test execution upon failure. + La fonctionnalité de nouvelles tentatives de tests ayant échoué permet de redémarrer l’exécution des tests en cas d’échec. + + + + Retry failed tests + Nouvelle tentative de tests ayant échoué + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Les nouvelles tentatives de tests ayant échoué fonctionnent uniquement avec les générateurs de type « Microsoft.Testing.Platform.Builder.TestApplicationBuilder » + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + Désactiver le mécanisme de nouvelle tentative si le pourcentage de tests ayant échoué est supérieur à la valeur spécifiée + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + Désactiver le mécanisme de nouvelle tentative si le nombre de tests ayant échoué est supérieur à la valeur spécifiée + + + + Retry failed tests feature is not supported in hot reload mode + La fonctionnalité de nouvelles tentatives de tests ayant échoué n’est pas prise en charge en mode rechargement à chaud + + + + Retry failed tests feature is not supported in server mode + La fonctionnalité de nouvelles tentatives de tests ayant échoué n’est pas prise en charge en mode serveur + + + + Enable retry failed tests + Activer les nouvelles tentatives de tests ayant échoué + + + + Option '{0}' requires option '{1}' to be specified + L’option '{0}' nécessite la spécification de l’option '{1}' + + + + Option '{0}' expects a single integer argument + L’option '{0}' attend un seul argument entier + + + + Options '{0}' and '{1}' cannot be used together + Les options «{0}» et «{1}» ne peuvent pas être utilisées ensemble + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + Le processus hôte de test s’est arrêté avant que le service de nouvelle tentative puisse s’y connecter. Code de sortie : {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +La suite de tests s’est terminée correctement dans les {0} tentatives +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +Échec de la suite de tests, nombre total de tests ayant échoué : {0}, code de sortie : {1}, tentative : {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +Échec de la suite de tests dans toutes les {0} tentatives +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + La suite de tests a échoué avec un code de sortie différent de 2 (tests échoués). Défaillance liée à une condition inattendue. Code de sortie « {0} » + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf new file mode 100644 index 0000000000..18d2389948 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + Non è possibile creare la directory dei tentativi a causa di collisioni in “{0}” nonostante i tentativi ripetuti. + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + Se il criterio della soglia di errore è abilitato, i test non riusciti non verranno riavviati. + + + + Maximum failed tests threshold is {0} and {1} tests failed + La soglia massima dei test non superati è {0} e i test {1} non sono riusciti + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + La soglia percentuale di operazioni non riuscite è del {0}% e del {1}% di test non riusciti ({2}/{3}) + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +Spostamento dei file di asset dell'ultimo tentativo nella directory dei risultati predefinita +===================== + + + + + Moving file '{0}' to '{1}' + Spostamento del file '{0}' in '{1}' + + + + Failed to start process '{0}' + Impossibile avviare il processo '{0}' + + + + Retry failed tests feature allows to restart test execution upon failure. + La funzionalità di ripetizione dei test non riusciti consente di riavviare l'esecuzione dei test in caso di errore. + + + + Retry failed tests + Ripeti i test non riusciti + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + La ripetizione dei test non riusciti funziona solo con i generatori di tipo 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder'. + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + Disabilita il meccanismo di ripetizione dei tentativi se la percentuale di test non riusciti è maggiore del valore specificato. + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + Disabilita il meccanismo di ripetizione dei tentativi se il numero di test non riusciti è maggiore del valore specificato. + + + + Retry failed tests feature is not supported in hot reload mode + La funzionalità di ripetizione dei test non riusciti non è supportata nella modalità di ricaricamento rapido. + + + + Retry failed tests feature is not supported in server mode + La funzionalità di ripetizione dei test non riusciti non è supportata in modalità server + + + + Enable retry failed tests + Abilita la ripetizione dei test non riusciti + + + + Option '{0}' requires option '{1}' to be specified + L'opzione '{0}' richiede l'opzione '{1}' da specificare + + + + Option '{0}' expects a single integer argument + L'opzione '{0}' prevede un singolo argomento integer + + + + Options '{0}' and '{1}' cannot be used together + Le opzioni '{0}' e '{1}' non possono essere usate insieme + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + Il processo host di test è stato chiuso prima che il servizio di ripetizione potesse connettersi ad esso. Codice di uscita: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +Il gruppo di test è stato completato correttamente in {0} tentativi +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +Gruppo di test non riuscito, totale test non superati: {0}, codice di uscita: {1}, tentativo: {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +Gruppo di test non riuscito in tutti i {0} tentativi +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Il gruppo di test non è riuscito e il codice di uscita è diverso da 2 (test non superati). Errore correlato a una condizione imprevista. Codice di uscita "{0}" + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf new file mode 100644 index 0000000000..1e003faeed --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + 再試行中に '{0}' で競合が発生したため、再試行ディレクトリを作成できませんでした。 + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + 失敗しきい値ポリシーが有効になっているため、失敗したテストは再開されません。 + + + + Maximum failed tests threshold is {0} and {1} tests failed + 失敗したテストの最大しきい値は {0} で、{1} のテストが失敗しました + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + 失敗率のしきい値は {0} % で、失敗したテストは {1} % です ({2}/{3}) + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +最後の試行資産ファイルを既定の結果ディレクトリに移動しています +===================== + + + + + Moving file '{0}' to '{1}' + ファイル '{0}' を '{1}' に移動しています + + + + Failed to start process '{0}' + 処理 '{0}' を開始できませんでした + + + + Retry failed tests feature allows to restart test execution upon failure. + 失敗したテストの再試行機能を使用すると、失敗時にテストの実行を再開できます。 + + + + Retry failed tests + 失敗したテストの再試行 + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + 失敗したテストの再試行は、'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' 型のビルダーでのみ機能します + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + 失敗したテストの割合が指定した値を超える場合は再試行メカニズムを無効にする + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + 失敗したテストの数が指定した値を超える場合は再試行メカニズムを無効にする + + + + Retry failed tests feature is not supported in hot reload mode + 失敗したテストの再試行機能は、ホット リロード モードではサポートされていません + + + + Retry failed tests feature is not supported in server mode + 失敗したテストの再試行機能は、サーバー モードではサポートされていません + + + + Enable retry failed tests + 失敗したテストの再試行を有効にする + + + + Option '{0}' requires option '{1}' to be specified + オプション '{0}' では、オプション '{1}' を指定する必要があります + + + + Option '{0}' expects a single integer argument + オプション '{0}' には 1 つの整数引数が必要です + + + + Options '{0}' and '{1}' cannot be used together + オプション '{0}' と '{1}' を一緒に使用することはできません + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + 再試行サービスが接続する前に、テスト ホスト プロセスが終了しました。終了コード: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +テスト スイートが {0} 回の試行で正常に完了しました +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +テスト スイートが失敗しました。失敗したテストの合計数: {0}、終了コード: {1}、試行: {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +{0} 回の試行すべてでテスト スイートが失敗しました +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + テスト スイートが失敗し、終了コードが 2 (失敗したテスト) と異なりました。予期しない状態に関連するエラーです。終了コード '{0}' + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf new file mode 100644 index 0000000000..d521ae9495 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + 다시 시도에도 불구하고 '{0}'의 충돌로 인해 재시도 디렉터리를 만들지 못했습니다. + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + 실패 임계값 정책을 사용하도록 설정했습니다. 실패한 테스트는 다시 시작되지 않습니다. + + + + Maximum failed tests threshold is {0} and {1} tests failed + 실패한 최대 테스트 임계값이 {0}이고 {1} 테스트가 실패했습니다. + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + 실패한 임계값 백분율은 {0}%이며 {1}% 테스트에 실패했습니다({2}/{3}). + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +마지막 시도 자산 파일을 기본 결과 디렉터리로 이동 +===================== + + + + + Moving file '{0}' to '{1}' + 파일 {0}을(를) {1}(으)로 이동 + + + + Failed to start process '{0}' + 프로세스 '{0}'을(를) 시작하지 못했습니다. + + + + Retry failed tests feature allows to restart test execution upon failure. + 실패한 테스트 다시 시도 기능을 사용하면 실패 시 테스트 실행을 다시 시작할 수 있습니다. + + + + Retry failed tests + 실패한 테스트 다시 시도 + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + 실패한 테스트 다시 시도는 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' 유형의 작성기에서만 작동합니다. + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + 실패한 테스트의 비율이 지정된 값보다 큰 경우 다시 시도 메커니즘을 사용하지 않도록 설정 + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + 실패한 테스트 수가 지정된 값보다 큰 경우 다시 시도 메커니즘을 사용하지 않도록 설정 + + + + Retry failed tests feature is not supported in hot reload mode + 실패한 테스트 다시 시도 기능은 핫 다시 로드 모드에서 지원되지 않습니다. + + + + Retry failed tests feature is not supported in server mode + 실패한 테스트 다시 시도 기능은 서버 모드에서 지원되지 않습니다. + + + + Enable retry failed tests + 실패한 테스트 다시 시도 사용 + + + + Option '{0}' requires option '{1}' to be specified + '{0}' 옵션을(를) 사용하려면 '{1}' 옵션을 지정해야 합니다. + + + + Option '{0}' expects a single integer argument + '{0}' 옵션에는 단일 정수 인수가 필요합니다. + + + + Options '{0}' and '{1}' cannot be used together + '{0}' 및 '{1}' 옵션은 함께 사용할 수 없습니다. + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + 다시 시도 서비스가 연결되기 전에 테스트 호스트 프로세스가 종료되었습니다. 종료 코드: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +테스트 도구 모음이 {0} 시도에서 완료되었습니다. +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +테스트 도구 모음이 실패했습니다. 실패한 총 테스트: {0}, 종료 코드: {1}, 시도: {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +테스트 도구 모음이 모든 {0} 시도에 실패했습니다 +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + 테스트 도구 모음이 2와 다른 종료 코드를 사용하여 실패했습니다(테스트 실패). 예기치 않은 조건과 관련된 오류입니다. 종료 코드 '{0}' + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf new file mode 100644 index 0000000000..a9d22ccaa5 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + Nie można utworzyć katalogu ponownych prób z powodu kolizji w katalogu „{0}” mimo ponownej próby. + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + Zasady progu błędów są włączone, a testy zakończone niepowodzeniem nie zostaną ponownie uruchomione. + + + + Maximum failed tests threshold is {0} and {1} tests failed + Próg maksymalnej liczby testów zakończonych niepowodzeniem to {0} i liczba testów zakończonych niepowodzeniem wyniosła {1} + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Wartość procentowa progu niepowodzenia wynosi {0}% i {1}% testów nie powiodło się ({2}/{3}) + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +Przeniesienie plików zasobów ostatniej próby do domyślnego katalogu wyników +===================== + + + + + Moving file '{0}' to '{1}' + Przenoszenie pliku „{0}” do {1} + + + + Failed to start process '{0}' + Nie można uruchomić procesu „{0}” + + + + Retry failed tests feature allows to restart test execution upon failure. + Funkcja ponawiania testów zakończonych niepowodzeniem umożliwia ponowne uruchomienie wykonywania testu po niepowodzeniu. + + + + Retry failed tests + Ponów próbę testów zakończonych niepowodzeniem + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Ponawianie testów zakończonych niepowodzeniem działa tylko z konstruktorami typu „Microsoft.Testing.Platform.Builder.TestApplicationBuilder” + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + Wyłącz mechanizm ponawiania prób, jeśli procent testów zakończonych niepowodzeniem jest większy niż określona wartość + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + Wyłącz mechanizm ponawiania prób, jeśli liczba testów zakończonych niepowodzeniem jest większa niż określona wartość + + + + Retry failed tests feature is not supported in hot reload mode + Funkcja ponownych testów zakończonych niepowodzeniem nie jest obsługiwana w trybie ponownego ładowania na gorąco + + + + Retry failed tests feature is not supported in server mode + Funkcja ponawiania testów zakończonych niepowodzeniem nie jest obsługiwana w trybie serwera + + + + Enable retry failed tests + Włącz testy zakończone niepowodzeniem ponowień + + + + Option '{0}' requires option '{1}' to be specified + Opcja „{0}” wymaga określenia opcji „{1}” + + + + Option '{0}' expects a single integer argument + Opcja „{0}” oczekuje argumentu pojedynczej liczby całkowitej + + + + Options '{0}' and '{1}' cannot be used together + Opcji „{0}” i „{1}” nie można używać razem + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + Proces hosta testowego zakończył się, zanim usługa ponawiania próby mogła nawiązać z nim połączenie. Kod zakończenia: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +Pomyślnie ukończono zestaw testów w {0} próbach +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +Zestaw testów nie powiódł się, łączna liczba testów zakończonych niepowodzeniem: {0}, kod zakończenia: {1}, próba: {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +Zestaw testów nie powiódł się we wszystkich {0} próbach +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Zestaw testów nie powiódł się. Kod zakończenia jest inny niż 2 (testy zakończone niepowodzeniem). Błąd związany z nieoczekiwanym warunkiem. Kod zakończenia „{0}” + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf new file mode 100644 index 0000000000..48006921c3 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + Falha ao criar o diretório de novas tentativas devido a colisões em '{0}', apesar das novas tentativas. + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + A política de limite de falha está habilitada, os testes com falha não serão reiniciados. + + + + Maximum failed tests threshold is {0} and {1} tests failed + O limite máximo de testes com falha é {0} e {1} testes falharam + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + O limite de porcentagem com falha é {0}% e {1}% dos testes falharam ({2}/{3}) + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +Movendo arquivos de ativo da última tentativa para o diretório de resultados padrão +===================== + + + + + Moving file '{0}' to '{1}' + Movendo o arquivo ''{0}'' para ''{1}'' + + + + Failed to start process '{0}' + Falha ao iniciar o processo '{0}' + + + + Retry failed tests feature allows to restart test execution upon failure. + O recurso repetir testes com falha permite reiniciar a execução de teste após falha. + + + + Retry failed tests + Repetir testes com falha + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + A repetição de testes com falha funciona somente com construtores do tipo ''Microsoft.Testing.Platform.Builder.TestApplicationBuilder'' + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + Desabilitar o mecanismo de repetição se a porcentagem de testes com falha for maior que o valor especificado + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + Desabilitar o mecanismo de repetição se o número de testes com falha for maior que o valor especificado + + + + Retry failed tests feature is not supported in hot reload mode + Não há suporte para o recurso de repetição de testes com falha no modo de recarga dinâmica + + + + Retry failed tests feature is not supported in server mode + Não há suporte para o recurso de repetição de testes com falha no modo de servidor + + + + Enable retry failed tests + Habilitar repetição de testes com falha + + + + Option '{0}' requires option '{1}' to be specified + A opção ''{0}'' requer que a opção ''{1}'' seja especificada + + + + Option '{0}' expects a single integer argument + A opção ''{0}'' espera um único argumento inteiro + + + + Options '{0}' and '{1}' cannot be used together + As opções ''{0}'' e ''{1}'' não podem ser usadas juntas + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + O processo de host de teste foi encerrado antes que o serviço de repetição pudesse se conectar a ele. Código de saída: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +Pacote de testes concluído com êxito em {0} tentativas +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +Falha no pacote de testes, total de testes com falha: {0}, código de saída: {1}, tentativa: {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +Falha no pacote de testes em todas as {0} tentativas +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Falha no conjunto de testes e código de saída diferente de 2 (testes com falha). Falha relacionada a uma condição inesperada. Código de saída "{0}" + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf new file mode 100644 index 0000000000..31fb110066 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + Не удалось создать каталог повторов из-за конфликтов в {0}, несмотря на повторную попытку. + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + Политика порога отказа включена, неудачные тесты не будут перезапущены. + + + + Maximum failed tests threshold is {0} and {1} tests failed + Максимальное пороговое значение для неудачных тестов — {0}, и неудачных тестов — {1} + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Пороговое значение доли неудачных тестов — {0}%, и доля неудачных тестов — {1}% ({2}/{3}) + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +Перемещение файлов ресурсов последней попытки в каталог результатов по умолчанию +===================== + + + + + Moving file '{0}' to '{1}' + Перемещение файла "{0}" в "{1}" + + + + Failed to start process '{0}' + Не удалось запустить процесс "{0}". + + + + Retry failed tests feature allows to restart test execution upon failure. + Функция повтора неудачных тестов позволяет перезапустить выполнение теста после сбоя. + + + + Retry failed tests + Включить повтор неудачных тестов + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Повтор неудачных тестов работает только с построителями типа "Microsoft.Testing.Platform.Builder.TestApplicationBuilder" + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + Отключить механизм повторных попыток, если процент неудачных тестов превышает указанное значение + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + Отключить механизм повторных попыток, если число неудачных тестов превышает указанное значение + + + + Retry failed tests feature is not supported in hot reload mode + Функция повтора неудачных тестов не поддерживается в режиме горячей перезагрузки + + + + Retry failed tests feature is not supported in server mode + Функция повтора неудачных тестов не поддерживается в режиме сервера + + + + Enable retry failed tests + Включить повтор неудачных тестов + + + + Option '{0}' requires option '{1}' to be specified + Параметр "{0}" требует указания параметра "{1}" + + + + Option '{0}' expects a single integer argument + Параметр "{0}" ожидает один целочисленный аргумент + + + + Options '{0}' and '{1}' cannot be used together + Параметры "{0}" и "{1}" не могут использоваться вместе + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + Тестовый хост-процесс завершился прежде, чем к нему смогла подключиться служба повторной попытки. Код выхода: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +Набор тестов успешно завершен за несколько ({0}) попыток +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +Сбой набора тестов. Всего неудачных тестов: {0}, код завершения: {1}, попытка: {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +Сбой набора тестов во всех попытках ({0}) +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Сбой набора тестов с кодом завершения, который отличается от 2 (неудачные тесты). Сбой, связанный с неожиданным условием. Код завершения "{0}" + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf new file mode 100644 index 0000000000..74dd39e0dd --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + Yeniden denemeye rağmen '{0} ' içindeki çakışmalar nedeniyle yeniden deneme dizini oluşturulamadı. + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + Hata eşiği ilkesi etkinleştirildi, başarısız testler yeniden başlatılmaz. + + + + Maximum failed tests threshold is {0} and {1} tests failed + Maksimum başarısız test eşiği {0} ve {1} test başarısız oldu + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Başarısız olan yüzde eşiği %{0} ve başarısız %{1} ({2}/{3}) + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +Son deneme varlık dosyaları, varsayılan sonuç dizinine taşınıyor +===================== + + + + + Moving file '{0}' to '{1}' + '{0}' dosyasını '{1}'e taşıma + + + + Failed to start process '{0}' + '{0}' işlemi başlatılamadı + + + + Retry failed tests feature allows to restart test execution upon failure. + Başarısız testleri yeniden dene özelliği, başarısızlık durumunda test yürütmenin yeniden başlatılmasına olanak tanır. + + + + Retry failed tests + Başarısız testleri yeniden deneyin + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Başarısız testleri yeniden deneme yalnızca 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' türündeki oluşturucularla çalışır + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + Başarısız testlerin yüzdesi belirtilen değerden büyükse yeniden deneme mekanizmasını devre dışı bırak + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + Başarısız testlerin yüzdesi belirtilen değerden büyükse yeniden deneme mekanizmasını devre dışı bırak + + + + Retry failed tests feature is not supported in hot reload mode + Başarısız testleri yeniden deneme özelliği, çalışırken yeniden yükleme modunda desteklenmez + + + + Retry failed tests feature is not supported in server mode + Başarısız testleri yeniden deneme özelliği sunucu modunda desteklenmiyor + + + + Enable retry failed tests + Başarısız testleri yeniden denemeyi etkinleştir + + + + Option '{0}' requires option '{1}' to be specified + '{0}' seçeneği, '{1}' seçeneğinin belirtilmesini gerektirir + + + + Option '{0}' expects a single integer argument + Seçenek '{0}' tek bir tamsayı argümanı bekliyor + + + + Options '{0}' and '{1}' cannot be used together + '{0}' ve '{1}' seçenekleri birlikte kullanılamaz + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + Yeniden deneme hizmeti ona bağlanamadan test ana makinesi işleminden çıkıldı. Çıkış kodu: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +Test paketi {0}denemede başarıyla tamamlandı +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +Test paketi başarısız oldu, toplam başarısız test: {0}, çıkış kodu: {1}, deneme: {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +Test paketi tüm {0} denemede başarısız oldu +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Test paketi 2 (başarısız testler) kodundan farklı bir çıkış koduyla başarısız oldu. Beklenmeyen bir koşulla ilgili hata. Çıkış kodu '{0}' + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf new file mode 100644 index 0000000000..9b66baf8c6 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + 未能创建重试目录,因为尽管重试,但“{0}”中存在冲突。 + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + 已启用失败阈值策略,将不会重新启动失败的测试。 + + + + Maximum failed tests threshold is {0} and {1} tests failed + 最大失败测试阈值为 {0},有 {1} 测试失败 + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + 失败的阈值百分比为 {0}%,有 {1}% 测试失败({2}/{3}) + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +正在将上次尝试资产文件移动到默认结果目录 +===================== + + + + + Moving file '{0}' to '{1}' + 正在将文件“{0}”移动到“{1}” + + + + Failed to start process '{0}' + 无法启动进程“{0}” + + + + Retry failed tests feature allows to restart test execution upon failure. + 重试失败的测试功能允许在失败时重新启动测试执行。 + + + + Retry failed tests + 重试失败的测试 + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + 重试失败的测试仅适用于“Microsoft.Testing.Platform.Builder.TestApplicationBuilder”类型的生成器 + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + 如果失败的测试百分比大于指定值,则禁用重试机制 + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + 如果失败的测试数大于指定值,则禁用重试机制 + + + + Retry failed tests feature is not supported in hot reload mode + 热重载模式下不支持重试失败的测试功能 + + + + Retry failed tests feature is not supported in server mode + 服务器模式不支持重试失败的测试功能 + + + + Enable retry failed tests + 启用重试失败的测试 + + + + Option '{0}' requires option '{1}' to be specified + 选项“{0}”需要指定选项“{1}” + + + + Option '{0}' expects a single integer argument + 选项“{0}”需要单一整数参数 + + + + Options '{0}' and '{1}' cannot be used together + 选项“{0}”和“{1}”不能一起使用 + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + 测试主机进程已在重试服务可以连接到它之前退出。退出代码: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +测试套件在“{0}”次尝试中成功完成 +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +测试套件失败,失败的测试总数: {0},退出代码: {1},尝试次数: {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +测试套件在所有“{0}”尝试中均失败 +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + 测试套件失败,且退出代码不是 2 (测试失败)。与意外情况相关的失败。退出代码“{0}” + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf new file mode 100644 index 0000000000..3113a1b002 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf @@ -0,0 +1,150 @@ + + + + + + Failed to create retries directory due to collisions in '{0}' despite re-trying. + 無法建立重試目錄,因為 '{0}' 中發生衝突,但仍在重試。 + '{0}' is the directory where collisions happen + + + Failure threshold policy is enabled, failed tests will not be restarted. + 已啟用失敗節流原則,將不會重新啟動失敗的測試。 + + + + Maximum failed tests threshold is {0} and {1} tests failed + 失敗的測試閾值上限是 {0},有 {1} 個測試失敗 + + + + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + 失敗的百分比閾值為 {0}%,有 {1}% 個測試失敗 ({2}/{3}) + + + + +===================== +Moving last attempt asset files to the default result directory +===================== + + +===================== +將上次嘗試的資產檔案移至預設結果目錄 +===================== + + + + + Moving file '{0}' to '{1}' + 正在將檔案 '{0}' 移至 '{1}' + + + + Failed to start process '{0}' + 無法啟動處理程序 '{0}' + + + + Retry failed tests feature allows to restart test execution upon failure. + 重試失敗的測試功能允許在失敗時重新啟動測試執行。 + + + + Retry failed tests + 重試失敗的測試 + + + + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + 重試失敗的測試僅適用於類型為 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' 的建立器 + + + + Disable retry mechanism if the percentage of failed tests is greater than the specified value + 如果失敗的測試百分比大於指定的值,則停用重試機制 + + + + Disable retry mechanism if the number of failed tests is greater than the specified value + 如果失敗的測試數目大於指定的值,則停用重試機制 + + + + Retry failed tests feature is not supported in hot reload mode + 熱重新載入模式不支援重試失敗的測試功能 + + + + Retry failed tests feature is not supported in server mode + 伺服器模式不支援重試失敗的測試功能 + + + + Enable retry failed tests + 啟用重試失敗的測試 + + + + Option '{0}' requires option '{1}' to be specified + 使用 '{0}' 選項時必須指定選項 '{1}'。 + + + + Option '{0}' expects a single integer argument + 選項 '{0}' 需要單一整數引數 + + + + Options '{0}' and '{1}' cannot be used together + 選項 '{0}' 和 '{1}' 不能同時使用 + + + + Test host process exited before the retry service could connect to it. Exit code: {0} + 測試主機處理序在重試服務連線到它之前已結束。結束代碼: {0} + + + + +===================== +Tests suite completed successfully in {0} attempts +===================== + +===================== +測試套件已順利在 {0} 次嘗試中完成 +===================== + + + + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== + + +===================== +測試套件失敗,失敗的測試總數: {0},結束代碼: {1},嘗試: {2}/{3} +===================== + + + + + +===================== +Tests suite failed in all {0} attempts +===================== + +===================== +測試套件在所有 {0} 次嘗試中都失敗 +===================== + + + + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + 測試套件失敗,結束代碼與 2 不同 (測試失敗)。與未預期情况有關的失敗。結束代碼 '{0}' + + + + + \ No newline at end of file diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryCommandLineOptionsProvider.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryCommandLineOptionsProvider.cs new file mode 100644 index 0000000000..40ee1ac50d --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryCommandLineOptionsProvider.cs @@ -0,0 +1,85 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using System.Globalization; + +using Microsoft.Testing.Extensions.Policy.Resources; +using Microsoft.Testing.Platform.CommandLine; +using Microsoft.Testing.Platform.Extensions; +using Microsoft.Testing.Platform.Extensions.CommandLine; +using Microsoft.Testing.Platform.Helpers; + +namespace Microsoft.Testing.Extensions.Policy; + +internal sealed class RetryCommandLineOptionsProvider : ICommandLineOptionsProvider +{ + public const string RetryFailedTestsOptionName = "retry-failed-tests"; + public const string RetryFailedTestsMaxPercentageOptionName = "retry-failed-tests-max-percentage"; + public const string RetryFailedTestsMaxTestsOptionName = "retry-failed-tests-max-tests"; + public const string RetryFailedTestsPipeNameOptionName = "internal-retry-pipename"; + + public string Uid => nameof(RetryCommandLineOptionsProvider); + + public string Version => AppVersion.DefaultSemVer; + + public string DisplayName => ExtensionResources.RetryFailedTestsExtensionDisplayName; + + public string Description => ExtensionResources.RetryFailedTestsExtensionDescription; + + public IReadOnlyCollection GetCommandLineOptions() + => new CommandLineOption[] + { + // Hide the extension for now, we will add tests and we will re-enable when will be good. + // We'd like to have some iteration in prod with our dogfooders before. + new(RetryFailedTestsOptionName, ExtensionResources.RetryFailedTestsOptionDescription, ArgumentArity.ExactlyOne, false, isBuiltIn: true), + new(RetryFailedTestsMaxPercentageOptionName, ExtensionResources.RetryFailedTestsMaxPercentageOptionDescription, ArgumentArity.ExactlyOne, false, isBuiltIn: true), + new(RetryFailedTestsMaxTestsOptionName, ExtensionResources.RetryFailedTestsMaxTestsOptionDescription, ArgumentArity.ExactlyOne, false, isBuiltIn: true), + + // Hidden internal args + new(RetryFailedTestsPipeNameOptionName, "Communication between the test host and the retry infra.", ArgumentArity.ExactlyOne, isHidden: true, isBuiltIn: true), + }; + + public Task IsEnabledAsync() => Task.FromResult(true); + + public Task ValidateCommandLineOptionsAsync(ICommandLineOptions commandLineOptions) + { + if (commandLineOptions.IsOptionSet(RetryFailedTestsMaxPercentageOptionName) && commandLineOptions.IsOptionSet(RetryFailedTestsMaxTestsOptionName)) + { + return ValidationResult.InvalidTask(string.Format(CultureInfo.CurrentCulture, ExtensionResources.RetryFailedTestsPercentageAndCountCannotBeMixedErrorMessage, RetryFailedTestsMaxPercentageOptionName, RetryFailedTestsMaxTestsOptionName)); + } + + if (commandLineOptions.IsOptionSet(RetryFailedTestsMaxPercentageOptionName) && !commandLineOptions.IsOptionSet(RetryFailedTestsOptionName)) + { + return ValidationResult.InvalidTask(string.Format(CultureInfo.CurrentCulture, ExtensionResources.RetryFailedTestsOptionIsMissingErrorMessage, RetryFailedTestsMaxPercentageOptionName, RetryFailedTestsOptionName)); + } + + if (commandLineOptions.IsOptionSet(RetryFailedTestsMaxTestsOptionName) && !commandLineOptions.IsOptionSet(RetryFailedTestsOptionName)) + { + return ValidationResult.InvalidTask(string.Format(CultureInfo.CurrentCulture, ExtensionResources.RetryFailedTestsOptionIsMissingErrorMessage, RetryFailedTestsMaxTestsOptionName, RetryFailedTestsOptionName)); + } + + // No problem found + return ValidationResult.ValidTask; + } + + public Task ValidateOptionArgumentsAsync(CommandLineOption commandOption, string[] arguments) + { + if (commandOption.Name == RetryFailedTestsOptionName && !int.TryParse(arguments[0], out int _)) + { + return ValidationResult.InvalidTask(string.Format(CultureInfo.CurrentCulture, ExtensionResources.RetryFailedTestsOptionSingleIntegerArgumentErrorMessage, RetryFailedTestsOptionName)); + } + + if (commandOption.Name == RetryFailedTestsMaxPercentageOptionName && !int.TryParse(arguments[0], out int _)) + { + return ValidationResult.InvalidTask(string.Format(CultureInfo.CurrentCulture, ExtensionResources.RetryFailedTestsOptionSingleIntegerArgumentErrorMessage, RetryFailedTestsMaxPercentageOptionName)); + } + + if (commandOption.Name == RetryFailedTestsMaxTestsOptionName && !int.TryParse(arguments[0], out int _)) + { + return ValidationResult.InvalidTask(string.Format(CultureInfo.CurrentCulture, ExtensionResources.RetryFailedTestsOptionSingleIntegerArgumentErrorMessage, RetryFailedTestsMaxTestsOptionName)); + } + + // No problem found + return ValidationResult.ValidTask; + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryDataConsumer.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryDataConsumer.cs new file mode 100644 index 0000000000..644e934405 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryDataConsumer.cs @@ -0,0 +1,79 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Extensions.Policy.Resources; +using Microsoft.Testing.Platform.CommandLine; +using Microsoft.Testing.Platform.Extensions; +using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Extensions.RetryFailedTests.Serializers; +using Microsoft.Testing.Platform.Extensions.TestHost; +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.IPC.Models; +using Microsoft.Testing.Platform.Messages; +using Microsoft.Testing.Platform.Services; +using Microsoft.Testing.Platform.TestHost; + +namespace Microsoft.Testing.Extensions.Policy; + +internal sealed class RetryDataConsumer : IDataConsumer, ITestSessionLifetimeHandler, IAsyncInitializableExtension +{ + private readonly IServiceProvider _serviceProvider; + private readonly ICommandLineOptions _commandLineOptions; + private RetryLifecycleCallbacks? _retryFailedTestsLifecycleCallbacks; + private int _totalTests; + + public RetryDataConsumer(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + _commandLineOptions = _serviceProvider.GetCommandLineOptions(); + } + + public Type[] DataTypesConsumed => new[] { typeof(TestNodeUpdateMessage) }; + + public string Uid => nameof(RetryDataConsumer); + + public string Version => AppVersion.DefaultSemVer; + + public string DisplayName => ExtensionResources.RetryFailedTestsExtensionDisplayName; + + public string Description => ExtensionResources.RetryFailedTestsExtensionDescription; + + public async Task ConsumeAsync(IDataProducer dataProducer, IData value, CancellationToken cancellationToken) + { + var testNodeUpdateMessage = (TestNodeUpdateMessage)value; + TestNodeStateProperty nodeState = testNodeUpdateMessage.TestNode.Properties.Single(); + if (Array.IndexOf(TestNodePropertiesCategories.WellKnownTestNodeTestRunOutcomeFailedProperties, nodeState.GetType()) != -1) + { + ApplicationStateGuard.Ensure(_retryFailedTestsLifecycleCallbacks is not null); + ApplicationStateGuard.Ensure(_retryFailedTestsLifecycleCallbacks.Client is not null); + await _retryFailedTestsLifecycleCallbacks.Client.RequestReplyAsync(new FailedTestRequest(testNodeUpdateMessage.TestNode.Uid), cancellationToken); + } + + if (Array.IndexOf(TestNodePropertiesCategories.WellKnownTestNodeTestRunOutcomeProperties, nodeState.GetType()) != -1) + { + _totalTests++; + } + } + + public async Task OnTestSessionFinishingAsync(SessionUid sessionUid, CancellationToken cancellationToken) + { + ApplicationStateGuard.Ensure(_retryFailedTestsLifecycleCallbacks is not null); + ApplicationStateGuard.Ensure(_retryFailedTestsLifecycleCallbacks.Client is not null); + await _retryFailedTestsLifecycleCallbacks.Client.RequestReplyAsync(new TotalTestsRunRequest(_totalTests), cancellationToken); + } + + public Task OnTestSessionStartingAsync(SessionUid sessionUid, CancellationToken cancellationToken) + => Task.CompletedTask; + + public Task IsEnabledAsync() + + => Task.FromResult(_commandLineOptions.IsOptionSet(RetryCommandLineOptionsProvider.RetryFailedTestsPipeNameOptionName)); + + public async Task InitializeAsync() + { + if (await IsEnabledAsync()) + { + _retryFailedTestsLifecycleCallbacks = _serviceProvider.GetRequiredService(); + } + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryExecutionFilterFactory.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryExecutionFilterFactory.cs new file mode 100644 index 0000000000..09bedd3afa --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryExecutionFilterFactory.cs @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Extensions.Policy.Resources; +using Microsoft.Testing.Platform.CommandLine; +using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.Requests; +using Microsoft.Testing.Platform.Services; + +namespace Microsoft.Testing.Extensions.Policy; + +internal sealed class RetryExecutionFilterFactory : ITestExecutionFilterFactory +{ + private readonly IServiceProvider _serviceProvider; + private readonly ICommandLineOptions _commandLineOptions; + private RetryLifecycleCallbacks? _retryFailedTestsLifecycleCallbacks; + + public RetryExecutionFilterFactory(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + _commandLineOptions = serviceProvider.GetCommandLineOptions(); + } + + public string Uid => nameof(RetryExecutionFilterFactory); + + public string Version => AppVersion.DefaultSemVer; + + public string DisplayName => ExtensionResources.RetryFailedTestsExtensionDisplayName; + + public string Description => ExtensionResources.RetryFailedTestsExtensionDescription; + + public Task IsEnabledAsync() + => Task.FromResult(_commandLineOptions.IsOptionSet(RetryCommandLineOptionsProvider.RetryFailedTestsPipeNameOptionName)); + + public async Task<(bool, ITestExecutionFilter?)> TryCreateAsync() + { + _retryFailedTestsLifecycleCallbacks = _serviceProvider.GetRequiredService(); + if (_retryFailedTestsLifecycleCallbacks.FailedTestsIDToRetry?.Length > 0) + { + return (true, (ITestExecutionFilter?)new TestNodeUidListFilter(_retryFailedTestsLifecycleCallbacks.FailedTestsIDToRetry + .Select(x => new TestNodeUid(x)).ToArray())); + } + else + { + ConsoleTestExecutionFilterFactory consoleTestExecutionFilterFactory = new(_commandLineOptions); + return await consoleTestExecutionFilterFactory.TryCreateAsync(); + } + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryExtensions.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryExtensions.cs new file mode 100644 index 0000000000..371c3e4606 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryExtensions.cs @@ -0,0 +1,38 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Extensions.Policy; +using Microsoft.Testing.Extensions.Policy.Resources; +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Extensions; +using Microsoft.Testing.Platform.Extensions.TestHostOrchestrator; +using Microsoft.Testing.Platform.TestHost; + +namespace Microsoft.Testing.Extensions; + +public static class RetryExtensions +{ + public static void AddRetryProvider(this ITestApplicationBuilder builder) + { + builder.CommandLine.AddProvider(() => new RetryCommandLineOptionsProvider()); + + builder.TestHost.AddTestApplicationLifecycleCallbacks(serviceProvider + => new RetryLifecycleCallbacks(serviceProvider)); + + CompositeExtensionFactory compositeExtensionFactory + = new(serviceProvider => new RetryDataConsumer(serviceProvider)); + builder.TestHost.AddDataConsumer(compositeExtensionFactory); + builder.TestHost.AddTestSessionLifetimeHandle(compositeExtensionFactory); + + if (builder is not TestApplicationBuilder testApplicationBuilder) + { + throw new InvalidOperationException(ExtensionResources.RetryFailedTestsInvalidTestApplicationBuilderErrorMessage); + } + + // Net yet exposed extension points + ((TestHostOrchestratorManager)testApplicationBuilder.TestHostControllersManager) + .AddTestHostOrchestrator(serviceProvider => new RetryOrchestrator(serviceProvider)); + ((TestHostManager)builder.TestHost) + .AddTestExecutionFilterFactory(serviceProvider => new RetryExecutionFilterFactory(serviceProvider)); + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryFailedTestsPipeServer.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryFailedTestsPipeServer.cs new file mode 100644 index 0000000000..21032e0497 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryFailedTestsPipeServer.cs @@ -0,0 +1,75 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Platform.Extensions.RetryFailedTests.Serializers; +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.IPC; +using Microsoft.Testing.Platform.IPC.Models; +using Microsoft.Testing.Platform.IPC.Serializers; +using Microsoft.Testing.Platform.Logging; +using Microsoft.Testing.Platform.Services; + +namespace Microsoft.Testing.Extensions.Policy; + +internal sealed class RetryFailedTestsPipeServer : IDisposable +{ + private readonly NamedPipeServer _singleConnectionNamedPipeServer; + private readonly PipeNameDescription _pipeNameDescription; + private readonly string[] _failedTests; + + public RetryFailedTestsPipeServer(IServiceProvider serviceProvider, string[] failedTests, ILogger logger) + { + _pipeNameDescription = NamedPipeServer.GetPipeName(Guid.NewGuid().ToString("N")); + logger.LogTrace($"Retry server pipe name: '{_pipeNameDescription.Name}'"); + _singleConnectionNamedPipeServer = new NamedPipeServer(_pipeNameDescription, CallbackAsync, + serviceProvider.GetEnvironment(), + serviceProvider.GetLoggerFactory().CreateLogger(), + serviceProvider.GetTask(), + serviceProvider.GetTestApplicationCancellationTokenSource().CancellationToken); + + _singleConnectionNamedPipeServer.RegisterSerializer(new VoidResponseSerializer(), typeof(VoidResponse)); + _singleConnectionNamedPipeServer.RegisterSerializer(new FailedTestRequestSerializer(), typeof(FailedTestRequest)); + _singleConnectionNamedPipeServer.RegisterSerializer(new GetListOfFailedTestsRequestSerializer(), typeof(GetListOfFailedTestsRequest)); + _singleConnectionNamedPipeServer.RegisterSerializer(new GetListOfFailedTestsResponseSerializer(), typeof(GetListOfFailedTestsResponse)); + _singleConnectionNamedPipeServer.RegisterSerializer(new TotalTestsRunRequestSerializer(), typeof(TotalTestsRunRequest)); + _failedTests = failedTests; + } + + public string PipeName => _pipeNameDescription.Name; + + public List? FailedUID { get; private set; } + + public int TotalTestRan { get; private set; } + + public Task WaitForConnectionAsync(CancellationToken cancellationToken) + => _singleConnectionNamedPipeServer.WaitConnectionAsync(cancellationToken); + + public void Dispose() + { + _singleConnectionNamedPipeServer.Dispose(); + _pipeNameDescription.Dispose(); + } + + private Task CallbackAsync(IRequest request) + { + if (request is FailedTestRequest failed) + { + FailedUID ??= new(); + FailedUID.Add(failed.Uid); + return Task.FromResult((IResponse)VoidResponse.CachedInstance); + } + + if (request is GetListOfFailedTestsRequest) + { + return Task.FromResult((IResponse)new GetListOfFailedTestsResponse(_failedTests)); + } + + if (request is TotalTestsRunRequest totalTestsRunRequest) + { + TotalTestRan = totalTestsRunRequest.TotalTests; + return Task.FromResult((IResponse)VoidResponse.CachedInstance); + } + + throw ApplicationStateGuard.Unreachable(); + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryLifecycleCallbacks.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryLifecycleCallbacks.cs new file mode 100644 index 0000000000..6d019d9fd1 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryLifecycleCallbacks.cs @@ -0,0 +1,89 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Extensions.Policy.Resources; +using Microsoft.Testing.Platform.CommandLine; +using Microsoft.Testing.Platform.Extensions.RetryFailedTests.Serializers; +using Microsoft.Testing.Platform.Extensions.TestHost; +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.IPC; +using Microsoft.Testing.Platform.IPC.Models; +using Microsoft.Testing.Platform.IPC.Serializers; +using Microsoft.Testing.Platform.Logging; +using Microsoft.Testing.Platform.Services; + +using Polyfills; + +namespace Microsoft.Testing.Extensions.Policy; + +internal sealed class RetryLifecycleCallbacks : ITestApplicationLifecycleCallbacks, +#if NETCOREAPP + IAsyncDisposable +#else + IDisposable +#endif +{ + private readonly IServiceProvider _serviceProvider; + private readonly ICommandLineOptions _commandLineOptions; + + public RetryLifecycleCallbacks(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + _commandLineOptions = _serviceProvider.GetCommandLineOptions(); + } + + public NamedPipeClient? Client { get; private set; } + + public string[]? FailedTestsIDToRetry { get; private set; } + + public string Uid => nameof(RetryLifecycleCallbacks); + + public string Version => AppVersion.DefaultSemVer; + + public string DisplayName => ExtensionResources.RetryFailedTestsExtensionDisplayName; + + public string Description => ExtensionResources.RetryFailedTestsExtensionDescription; + + public async Task BeforeRunAsync(CancellationToken cancellationToken) + { + if (!_commandLineOptions.TryGetOptionArgumentList(RetryCommandLineOptionsProvider.RetryFailedTestsPipeNameOptionName, out string[]? pipeName)) + { + throw ApplicationStateGuard.Unreachable(); + } + + ILogger logger = _serviceProvider.GetLoggerFactory().CreateLogger(); + + Guard.NotNull(pipeName); + ArgumentGuard.Ensure(pipeName.Length == 1, nameof(pipeName), "Pipe name expected"); + logger.LogDebug($"Connecting to pipe '{pipeName[0]}'"); + + Client = new(pipeName[0]); + Client.RegisterSerializer(new VoidResponseSerializer(), typeof(VoidResponse)); + Client.RegisterSerializer(new FailedTestRequestSerializer(), typeof(FailedTestRequest)); + Client.RegisterSerializer(new GetListOfFailedTestsRequestSerializer(), typeof(GetListOfFailedTestsRequest)); + Client.RegisterSerializer(new GetListOfFailedTestsResponseSerializer(), typeof(GetListOfFailedTestsResponse)); + Client.RegisterSerializer(new TotalTestsRunRequestSerializer(), typeof(TotalTestsRunRequest)); + await Client.ConnectAsync(cancellationToken); + + GetListOfFailedTestsResponse result = await Client.RequestReplyAsync(new GetListOfFailedTestsRequest(), cancellationToken); + FailedTestsIDToRetry = result.FailedTestIds; + } + + public Task IsEnabledAsync() + => Task.FromResult(_commandLineOptions.IsOptionSet(RetryCommandLineOptionsProvider.RetryFailedTestsPipeNameOptionName)); + + public Task AfterRunAsync(int exitCode, CancellationToken cancellation) + => Task.CompletedTask; + +#if NETCOREAPP + public async ValueTask DisposeAsync() + { + if (Client is not null) + { + await Client.DisposeAsync(); + } + } +#else + public void Dispose() => Client?.Dispose(); +#endif +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs new file mode 100644 index 0000000000..849d286da2 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs @@ -0,0 +1,348 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using System.Diagnostics; +using System.Globalization; +using System.Text; + +using Microsoft.Testing.Extensions.Policy.Resources; +using Microsoft.Testing.Platform.CommandLine; +using Microsoft.Testing.Platform.Configurations; +using Microsoft.Testing.Platform.Extensions.OutputDevice; +using Microsoft.Testing.Platform.Extensions.TestHostOrchestrator; +using Microsoft.Testing.Platform.Helpers; +using Microsoft.Testing.Platform.Logging; +using Microsoft.Testing.Platform.OutputDevice; +using Microsoft.Testing.Platform.Services; + +namespace Microsoft.Testing.Extensions.Policy; + +internal sealed class RetryOrchestrator : ITestHostOrchestrator, IOutputDeviceDataProducer +{ + private readonly IServiceProvider _serviceProvider; + private readonly ICommandLineOptions _commandLineOptions; + + public RetryOrchestrator(IServiceProvider serviceProvider) + { + _serviceProvider = serviceProvider; + _commandLineOptions = _serviceProvider.GetCommandLineOptions(); + } + + public string Uid => nameof(RetryOrchestrator); + + public string Version => AppVersion.DefaultSemVer; + + public string DisplayName => ExtensionResources.RetryFailedTestsExtensionDisplayName; + + public string Description => ExtensionResources.RetryFailedTestsExtensionDescription; + + public Task IsEnabledAsync() + => Task.FromResult(_commandLineOptions.IsOptionSet(RetryCommandLineOptionsProvider.RetryFailedTestsOptionName)); + + private static string CreateRetriesDirectory(string resultDirectory) + { + Exception? lastException = null; + // Quite arbitrary. Keep trying to create the directory for 10 times. + for (int i = 0; i < 10; i++) + { + string retryRootFolder = Path.Combine(resultDirectory, "Retries", RandomId.Next()); + if (Directory.Exists(retryRootFolder)) + { + continue; + } + + try + { + Directory.CreateDirectory(retryRootFolder); + return retryRootFolder; + } + catch (IOException ex) + { + lastException = ex; + } + } + + if (lastException is not null) + { + throw lastException; + } + + throw new IOException(string.Format(CultureInfo.InvariantCulture, ExtensionResources.FailedToCreateRetryDirectoryBecauseOfCollision, resultDirectory)); + } + + public async Task OrchestrateTestHostExecutionAsync() + { + if (_commandLineOptions.IsOptionSet(PlatformCommandLineProvider.ServerOptionKey)) + { + throw new InvalidOperationException(ExtensionResources.RetryFailedTestsNotSupportedInServerModeErrorMessage); + } + + if (IsHotReloadEnabled(_serviceProvider.GetEnvironment())) + { + throw new InvalidOperationException(ExtensionResources.RetryFailedTestsNotSupportedInHotReloadErrorMessage); + } + + ILogger logger = _serviceProvider.GetLoggerFactory().CreateLogger(); + IConfiguration configuration = _serviceProvider.GetConfiguration(); + + ITestApplicationModuleInfo currentTestApplicationModuleInfo = _serviceProvider.GetTestApplicationModuleInfo(); + ExecutableInfo executableInfo = currentTestApplicationModuleInfo.GetCurrentExecutableInfo(); + + if (!_commandLineOptions.TryGetOptionArgumentList(RetryCommandLineOptionsProvider.RetryFailedTestsOptionName, out string[]? cmdRetries)) + { + throw ApplicationStateGuard.Unreachable(); + } + + ApplicationStateGuard.Ensure(cmdRetries is not null); + int userMaxRetryCount = int.Parse(cmdRetries[0], CultureInfo.InvariantCulture); + + // Find out the retry args index inside the arguments to after cleanup the command line when we restart + List indexToCleanup = new(); + string[] executableArguments = executableInfo.Arguments.ToArray(); + int argIndex = GetOptionArgumentIndex(RetryCommandLineOptionsProvider.RetryFailedTestsOptionName, executableArguments); + if (argIndex < 0) + { + throw ApplicationStateGuard.Unreachable(); + } + + indexToCleanup.Add(argIndex); + indexToCleanup.Add(argIndex + 1); + + argIndex = GetOptionArgumentIndex(RetryCommandLineOptionsProvider.RetryFailedTestsMaxPercentageOptionName, executableArguments); + if (argIndex > -1) + { + indexToCleanup.Add(argIndex); + indexToCleanup.Add(argIndex + 1); + } + + argIndex = GetOptionArgumentIndex(RetryCommandLineOptionsProvider.RetryFailedTestsMaxTestsOptionName, executableArguments); + if (argIndex > -1) + { + indexToCleanup.Add(argIndex); + indexToCleanup.Add(argIndex + 1); + } + + argIndex = GetOptionArgumentIndex(PlatformCommandLineProvider.ResultDirectoryOptionKey, executableArguments); + if (argIndex > -1) + { + indexToCleanup.Add(argIndex); + indexToCleanup.Add(argIndex + 1); + } + + // Override the result directory with the attempt one + string resultDirectory = configuration.GetTestResultDirectory(); + + List exitCodes = new(); + IOutputDevice outputDevice = _serviceProvider.GetOutputDevice(); + IFileSystem fileSystem = _serviceProvider.GetFileSystem(); + + int attemptCount = 0; + List finalArguments = new(); + string[]? lastListOfFailedId = null; + string? currentTryResultFolder = null; + bool thresholdPolicyKickedIn = false; + string retryRootFolder = CreateRetriesDirectory(resultDirectory); + bool retryInterrupted = false; + while (attemptCount < userMaxRetryCount + 1) + { + attemptCount++; + + // Cleanup the arguments + for (int i = 0; i < executableArguments.Length; i++) + { + if (indexToCleanup.Contains(i)) + { + continue; + } + + finalArguments.Add(executableArguments[i]); + } + + // Fix result folder + currentTryResultFolder = Path.Combine(retryRootFolder, attemptCount.ToString(CultureInfo.InvariantCulture)); + finalArguments.Add($"--{PlatformCommandLineProvider.ResultDirectoryOptionKey}"); + finalArguments.Add(currentTryResultFolder); + + // Prepare the pipeserver + using RetryFailedTestsPipeServer retryFailedTestsPipeServer = new(_serviceProvider, lastListOfFailedId ?? Array.Empty(), logger); + finalArguments.Add($"--{RetryCommandLineOptionsProvider.RetryFailedTestsPipeNameOptionName}"); + finalArguments.Add(retryFailedTestsPipeServer.PipeName); + + // Prepare the process start + ProcessStartInfo processStartInfo = new() + { + FileName = executableInfo.FileName, +#if !NETCOREAPP + UseShellExecute = false, +#endif + }; + + foreach (string argument in finalArguments) + { +#if !NETCOREAPP + processStartInfo.Arguments += argument + " "; +#else + processStartInfo.ArgumentList.Add(argument); +#endif + } + + await logger.LogDebugAsync($"Starting test host process, attempt {attemptCount}/{userMaxRetryCount}"); + IProcess testHostProcess = _serviceProvider.GetProcessHandler().Start(processStartInfo) + ?? throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, ExtensionResources.RetryFailedTestsCannotStartProcessErrorMessage, processStartInfo.FileName)); + + CancellationTokenSource processExitedCancellationToken = new(); + testHostProcess.Exited += (sender, e) => + { + processExitedCancellationToken.Cancel(); + var processExited = sender as Process; + logger.LogDebug($"Test host process exited, PID: '{processExited?.Id}'"); + }; + + using (var timeout = new CancellationTokenSource(TimeoutHelper.DefaultHangTimeSpanTimeout)) + using (var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, _serviceProvider.GetTestApplicationCancellationTokenSource().CancellationToken)) + using (var linkedToken2 = CancellationTokenSource.CreateLinkedTokenSource(linkedToken.Token, processExitedCancellationToken.Token)) + { + await logger.LogDebugAsync($"Wait connection from the test host process"); + try + { +#if NETCOREAPP + await retryFailedTestsPipeServer.WaitForConnectionAsync(linkedToken2.Token); +#else + // We don't know why but if the cancellation is called quickly in line 171 for netfx we stuck sometime here, like if + // the token we pass to the named pipe is not "correctly" verified inside the pipe implementation self. + // We fallback with our custom agnostic cancellation mechanism in that case. + // We see it happen only in .NET FX and not in .NET Core so for now we don't do it for core. + await retryFailedTestsPipeServer.WaitForConnectionAsync(linkedToken2.Token).WithCancellationAsync(linkedToken2.Token); +#endif + } + catch (OperationCanceledException) when (processExitedCancellationToken.IsCancellationRequested) + { + await outputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, ExtensionResources.TestHostProcessExitedBeforeRetryCouldConnect, testHostProcess.ExitCode))); + return ExitCodes.GenericFailure; + } + } + + await testHostProcess.WaitForExitAsync(); + + exitCodes.Add(testHostProcess.ExitCode); + if (testHostProcess.ExitCode != ExitCodes.Success) + { + if (testHostProcess.ExitCode != ExitCodes.AtLeastOneTestFailed) + { + await outputDevice.DisplayAsync(this, new WarningMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, ExtensionResources.TestSuiteFailedWithWrongExitCode, testHostProcess.ExitCode))); + retryInterrupted = true; + break; + } + + await outputDevice.DisplayAsync(this, new WarningMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, ExtensionResources.TestSuiteFailed, retryFailedTestsPipeServer.FailedUID?.Count ?? 0, testHostProcess.ExitCode, attemptCount, userMaxRetryCount + 1))); + + // Check thresholds + if (attemptCount == 1) + { + double? maxFailedTests = null; + double? maxPercentage = null; + double? maxCount = null; + if (_commandLineOptions.TryGetOptionArgumentList(RetryCommandLineOptionsProvider.RetryFailedTestsMaxPercentageOptionName, out string[]? retryFailedTestsMaxPercentage)) + { + maxPercentage = double.Parse(retryFailedTestsMaxPercentage[0], CultureInfo.InvariantCulture); + maxFailedTests = maxPercentage / 100 * retryFailedTestsPipeServer.TotalTestRan; + } + + if (_commandLineOptions.TryGetOptionArgumentList(RetryCommandLineOptionsProvider.RetryFailedTestsMaxTestsOptionName, out string[]? retryFailedTestsMaxCount)) + { + maxCount = double.Parse(retryFailedTestsMaxCount[0], CultureInfo.InvariantCulture); + maxFailedTests = maxCount.Value; + } + + // If threshold policy enable + if (maxFailedTests is not null) + { + if ((retryFailedTestsPipeServer.FailedUID?.Count ?? 0) > maxFailedTests) + { + thresholdPolicyKickedIn = true; + StringBuilder explanation = new(); + explanation.AppendLine(ExtensionResources.FailureThresholdPolicy); + if (maxPercentage is not null) + { + double failedPercentage = Math.Round((double)(retryFailedTestsPipeServer.FailedUID!.Count / (double)retryFailedTestsPipeServer.TotalTestRan * 100), 2); + explanation.AppendLine(string.Format(CultureInfo.InvariantCulture, ExtensionResources.FailureThresholdPolicyMaxPercentage, maxPercentage, failedPercentage, retryFailedTestsPipeServer.FailedUID.Count, retryFailedTestsPipeServer.TotalTestRan)); + } + + if (maxCount is not null) + { + explanation.AppendLine(string.Format(CultureInfo.InvariantCulture, ExtensionResources.FailureThresholdPolicyMaxCount, maxCount, retryFailedTestsPipeServer.FailedUID!.Count)); + } + + await outputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(explanation.ToString())); + break; + } + } + } + + finalArguments.Clear(); + lastListOfFailedId = retryFailedTestsPipeServer.FailedUID?.ToArray(); + continue; + } + else + { + break; + } + } + + if (!thresholdPolicyKickedIn && !retryInterrupted) + { + if (exitCodes[^1] != ExitCodes.Success) + { + await outputDevice.DisplayAsync(this, new ErrorMessageOutputDeviceData(string.Format(CultureInfo.InvariantCulture, ExtensionResources.TestSuiteFailedInAllAttempts, userMaxRetryCount + 1))); + } + else + { + await outputDevice.DisplayAsync(this, new FormattedTextOutputDeviceData(string.Format(CultureInfo.InvariantCulture, ExtensionResources.TestSuiteCompletedSuccessfully, attemptCount)) { ForegroundColor = new SystemConsoleColor { ConsoleColor = ConsoleColor.Green } }); + } + } + + ApplicationStateGuard.Ensure(currentTryResultFolder is not null); + + string[] filesToMove = Directory.GetFiles(currentTryResultFolder, "*.*", SearchOption.AllDirectories); + if (filesToMove.Length > 0) + { + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(ExtensionResources.MoveFiles)); + + // Move last attempt assets + foreach (string file in filesToMove) + { + string finalFileLocation = file.Replace(currentTryResultFolder, resultDirectory); + + // Create the directory if missing + Directory.CreateDirectory(Path.GetDirectoryName(finalFileLocation)!); + + await outputDevice.DisplayAsync(this, new TextOutputDeviceData(string.Format(CultureInfo.InvariantCulture, ExtensionResources.MovingFileToLocation, file, finalFileLocation))); +#if NETCOREAPP + File.Move(file, finalFileLocation, overwrite: true); +#else + File.Copy(file, finalFileLocation, overwrite: true); + File.Delete(file); +#endif + } + } + + return exitCodes[^1]; + } + + // Copied from HotReloadTestHostTestFrameworkInvoker + private static bool IsHotReloadEnabled(IEnvironment environment) + => environment.GetEnvironmentVariable(EnvironmentVariableConstants.DOTNET_WATCH) == "1" + || environment.GetEnvironmentVariable(EnvironmentVariableConstants.TESTINGPLATFORM_HOTRELOAD_ENABLED) == "1"; + + private static int GetOptionArgumentIndex(string optionName, string[] executableArgs) + { + int index = Array.IndexOf(executableArgs, "-" + optionName); + if (index >= 0) + { + return index; + } + + index = Array.IndexOf(executableArgs, "--" + optionName); + return index >= 0 ? index : -1; + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/FailedTestRequest.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/FailedTestRequest.cs new file mode 100644 index 0000000000..f47a8b2c19 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/FailedTestRequest.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Platform.IPC; +using Microsoft.Testing.Platform.IPC.Serializers; + +namespace Microsoft.Testing.Platform.Extensions.RetryFailedTests.Serializers; + +internal sealed class FailedTestRequest(string uid) : IRequest +{ + public string Uid { get; } = uid; +} + +internal sealed class FailedTestRequestSerializer : BaseSerializer, INamedPipeSerializer +{ + public int Id => 1; + + public object Deserialize(Stream stream) + { + string uid = ReadString(stream); + return new FailedTestRequest(uid); + } + + public void Serialize(object obj, Stream stream) + { + var testHostProcessExitRequest = (FailedTestRequest)obj; + WriteString(stream, testHostProcessExitRequest.Uid); + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTests.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTests.cs new file mode 100644 index 0000000000..1e8f38c1a2 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTests.cs @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Platform.IPC; +using Microsoft.Testing.Platform.IPC.Serializers; + +namespace Microsoft.Testing.Platform.Extensions.RetryFailedTests.Serializers; + +internal sealed class GetListOfFailedTestsRequest : IRequest; + +internal sealed class GetListOfFailedTestsRequestSerializer : BaseSerializer, INamedPipeSerializer +{ + public int Id => 2; + + public object Deserialize(Stream stream) => new GetListOfFailedTestsRequest(); + + public void Serialize(object obj, Stream stream) + { + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTestsResponse.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTestsResponse.cs new file mode 100644 index 0000000000..e959df04bc --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/GetListOfFailedTestsResponse.cs @@ -0,0 +1,40 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Platform.IPC; +using Microsoft.Testing.Platform.IPC.Serializers; + +namespace Microsoft.Testing.Platform.Extensions.RetryFailedTests.Serializers; + +internal sealed class GetListOfFailedTestsResponse(string[] failedTestIds) : IResponse +{ + public string[] FailedTestIds { get; } = failedTestIds; +} + +internal sealed class GetListOfFailedTestsResponseSerializer : BaseSerializer, INamedPipeSerializer +{ + public int Id => 3; + + public object Deserialize(Stream stream) + { + int totalFailedTests = ReadInt(stream); + + string[] testsId = new string[totalFailedTests]; + for (int i = 0; i < totalFailedTests; i++) + { + testsId[i] = ReadString(stream); + } + + return new GetListOfFailedTestsResponse(testsId); + } + + public void Serialize(object obj, Stream stream) + { + var getListOfFailedTestsResponse = (GetListOfFailedTestsResponse)obj; + WriteInt(stream, getListOfFailedTestsResponse.FailedTestIds.Length); + foreach (string testId in getListOfFailedTestsResponse.FailedTestIds) + { + WriteString(stream, testId); + } + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/TotalTestsRunRequest.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/TotalTestsRunRequest.cs new file mode 100644 index 0000000000..bfd5e8b4fb --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Serializers/TotalTestsRunRequest.cs @@ -0,0 +1,29 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Platform.IPC; +using Microsoft.Testing.Platform.IPC.Serializers; + +namespace Microsoft.Testing.Platform.Extensions.RetryFailedTests.Serializers; + +internal sealed class TotalTestsRunRequest(int totalTests) : IRequest +{ + public int TotalTests { get; } = totalTests; +} + +internal sealed class TotalTestsRunRequestSerializer : BaseSerializer, INamedPipeSerializer +{ + public int Id => 4; + + public object Deserialize(Stream stream) + { + int totalTestRun = ReadInt(stream); + return new TotalTestsRunRequest(totalTestRun); + } + + public void Serialize(object obj, Stream stream) + { + var totalTestsRunRequest = (TotalTestsRunRequest)obj; + WriteInt(stream, totalTestsRunRequest.TotalTests); + } +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/TestingPlatformBuilderHook.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/TestingPlatformBuilderHook.cs new file mode 100644 index 0000000000..5e4b1dfe26 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/TestingPlatformBuilderHook.cs @@ -0,0 +1,12 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. + +using Microsoft.Testing.Platform.Builder; + +namespace Microsoft.Testing.Extensions.Retry; + +public static class TestingPlatformBuilderHook +{ + public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, string[] _) + => testApplicationBuilder.AddRetryProvider(); +} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/build/Microsoft.Testing.Extensions.Retry.props b/src/Platform/Microsoft.Testing.Extensions.Retry/build/Microsoft.Testing.Extensions.Retry.props new file mode 100644 index 0000000000..9e3d7f70c0 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/build/Microsoft.Testing.Extensions.Retry.props @@ -0,0 +1,3 @@ + + + diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/buildMultiTargeting/Microsoft.Testing.Extensions.Retry.props b/src/Platform/Microsoft.Testing.Extensions.Retry/buildMultiTargeting/Microsoft.Testing.Extensions.Retry.props new file mode 100644 index 0000000000..8247127236 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/buildMultiTargeting/Microsoft.Testing.Extensions.Retry.props @@ -0,0 +1,9 @@ + + + + + Microsoft.Testing.Extensions.Retry + Microsoft.Testing.Extensions.Retry.TestingPlatformBuilderHook + + + diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/buildTransitive/Microsoft.Testing.Extensions.Retry.props b/src/Platform/Microsoft.Testing.Extensions.Retry/buildTransitive/Microsoft.Testing.Extensions.Retry.props new file mode 100644 index 0000000000..9e3d7f70c0 --- /dev/null +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/buildTransitive/Microsoft.Testing.Extensions.Retry.props @@ -0,0 +1,3 @@ + + + diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs index c32d56e656..996d1c683e 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs @@ -104,7 +104,6 @@ await RetryHelper.RetryAsync( "NativeAotTests", SourceCode .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion) .PatchCodeWithReplace("$TargetFramework$", TargetFrameworks.NetCurrent) .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion) .PatchCodeWithReplace("$MSTestEngineVersion$", MSTestEngineVersion), diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs index d584878a83..2bf2316c5b 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs @@ -295,8 +295,7 @@ public Task ExecuteRequestAsync(ExecuteRequestContext context) yield return (AssetName, AssetName, TestCode .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); } } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs index 235c2c376d..55fdea8a53 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs @@ -303,14 +303,12 @@ internal class Capabilities : ITestFrameworkCapabilities yield return (AssetName, AssetName, TestCode .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); yield return (AssetName2, AssetName2, TestCode2 .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); } } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs index 5c6f2f5b98..4006d2af14 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs @@ -655,8 +655,8 @@ public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture. - - + + @@ -773,13 +773,11 @@ public Task ExecuteRequestAsync(ExecuteRequestContext context) yield return (NoExtensionAssetName, NoExtensionAssetName, NoExtensionTestCode .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); yield return (AllExtensionsAssetName, AllExtensionsAssetName, AllExtensionsTestCode .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); } } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs index 7c64902ec6..5ccb4afda2 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs @@ -55,10 +55,8 @@ static AcceptanceTestBase() MicrosoftNETTestSdkVersion = cpmPropFileDoc.Descendants("MicrosoftNETTestSdkVersion").Single().Value; var versionsPropsFileDoc = XDocument.Load(Path.Combine(RootFinder.Find(), "eng", "Versions.props")); - var directoryPackagesPropsFileDoc = XDocument.Load(Path.Combine(RootFinder.Find(), "Directory.Packages.props")); MSTestVersion = ExtractVersionFromPackage(Constants.ArtifactsPackagesShipping, "MSTest.TestFramework."); MicrosoftTestingPlatformVersion = ExtractVersionFromPackage(Constants.ArtifactsPackagesShipping, "Microsoft.Testing.Platform."); - MicrosoftTestingEnterpriseExtensionsVersion = ExtractVersionFromXmlFile(versionsPropsFileDoc, "MicrosoftTestingExtensionsRetryVersion"); MSTestEngineVersion = ExtractVersionFromXmlFile(versionsPropsFileDoc, "MSTestEngineVersion"); } @@ -81,8 +79,6 @@ static AcceptanceTestBase() public static string MicrosoftTestingPlatformVersion { get; private set; } - public static string MicrosoftTestingEnterpriseExtensionsVersion { get; private set; } - [ClassInitialize(InheritanceBehavior.BeforeEachDerivedClass)] [SuppressMessage("Design", "CA1000:Do not declare static members on generic types", Justification = "Fine in this context")] public static async Task ClassInitialize(TestContext testContext) diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuild.KnownExtensionRegistration.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuild.KnownExtensionRegistration.cs index 8ef8d9c03c..6c80392710 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuild.KnownExtensionRegistration.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuild.KnownExtensionRegistration.cs @@ -18,8 +18,7 @@ public async Task Microsoft_Testing_Platform_Extensions_ShouldBe_Correctly_Regis nameof(Microsoft_Testing_Platform_Extensions_ShouldBe_Correctly_Registered), SourceCode .PatchCodeWithReplace("$TargetFrameworks$", tfm) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); await DotnetCli.RunAsync($"restore -r {RID} {testAsset.TargetAssetPath}{Path.DirectorySeparatorChar}MSBuildTests.csproj", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -c {compilationMode} -r {RID} -nodeReuse:false -bl:{binlogFile} {testAsset.TargetAssetPath} -v:n", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); @@ -69,10 +68,8 @@ public async Task Microsoft_Testing_Platform_Extensions_ShouldBe_Correctly_Regis - - - - + + diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs index 8040163b92..12f1a09318 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs @@ -17,8 +17,7 @@ public async Task ConfigFileGeneration_CorrectlyCreateAndCacheAndCleaned(string SourceCode .PatchCodeWithReplace("$TargetFrameworks$", tfm) .PatchCodeWithReplace("$JsonContent$", ConfigurationContent) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); DotnetMuxerResult compilationResult = await DotnetCli.RunAsync($"{(verb == Verb.publish ? $"publish -f {tfm}" : "build")} -v:normal -nodeReuse:false {testAsset.TargetAssetPath} -c {compilationMode}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); @@ -56,8 +55,7 @@ public async Task ConfigFileGeneration_NoConfigurationFile_TaskWontRun(string tf SourceCode .PatchCodeWithReplace("$TargetFrameworks$", tfm) .PatchCodeWithReplace("$JsonContent$", ConfigurationContent) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); File.Delete(Path.Combine(testAsset.TargetAssetPath, "testconfig.json")); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.GenerateEntryPoint.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.GenerateEntryPoint.cs index 9f87d0df98..80e7b6fb18 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.GenerateEntryPoint.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.GenerateEntryPoint.cs @@ -113,9 +113,7 @@ private async Task GenerateAndVerifyLanguageSpecificEntryPoint(string assetName, { string finalSourceCode = sourceCode .PatchCodeWithReplace("$TargetFrameworks$", tfm) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - // We need to pickup local build packages -dev - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingPlatformVersion); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion); using TestAsset testAsset = await TestAsset.GenerateAssetAsync(assetName, finalSourceCode); await DotnetCli.RunAsync($"restore -r {RID} {testAsset.TargetAssetPath}{Path.DirectorySeparatorChar}MSBuildTests.{languageFileExtension}proj", AcceptanceFixture.NuGetGlobalPackagesFolder.Path); string binlogFile = Path.Combine(testAsset.TargetAssetPath, Guid.NewGuid().ToString("N"), "msbuild.binlog"); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs index 936bc59983..f4afa0443f 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Solution.cs @@ -31,8 +31,7 @@ public async Task MSBuildTests_UseMSBuildTestInfrastructure_Should_Run_Solution_ AssetName, SourceCode .PatchCodeWithReplace("$TargetFrameworks$", isMultiTfm ? $"{singleTfmOrMultiTfm}" : $"{singleTfmOrMultiTfm}") - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); string projectContent = File.ReadAllText(Directory.GetFiles(generator.TargetAssetPath, "MSBuildTests.csproj", SearchOption.AllDirectories).Single()); string programSourceContent = File.ReadAllText(Directory.GetFiles(generator.TargetAssetPath, "Program.cs", SearchOption.AllDirectories).Single()); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Properties/launchSettings.json b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Properties/launchSettings.json index aefd9415fa..61a6b36f2f 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Properties/launchSettings.json +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Properties/launchSettings.json @@ -2,7 +2,7 @@ "profiles": { "Microsoft.Testing.Platform.Acceptance.IntegrationTests": { "commandName": "Project", - "commandLineArgs": "", + "commandLineArgs": "--filter ClassName~RetryFailedTestsTests", "environmentVariables": { //"TESTINGPLATFORM_HOTRELOAD_ENABLED": "1" } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/RetryFailedTestsTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/RetryFailedTestsTests.cs new file mode 100644 index 0000000000..e49d603001 --- /dev/null +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/RetryFailedTestsTests.cs @@ -0,0 +1,366 @@ +#pragma warning disable IDE0073 // The file header does not match the required text +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. +#pragma warning restore IDE0073 // The file header does not match the required text + +namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; + +[TestClass] +public class RetryFailedTestsTests : AcceptanceTestBase +{ + private const string AssetName = "RetryFailedTests"; + + internal static IEnumerable<(string Arguments, bool FailOnly)> GetMatrix() + { + foreach (string tfm in TargetFrameworks.All) + { + foreach (bool failOnly in new[] { true, false }) + { + yield return (tfm, failOnly); + } + } + } + + [TestMethod] + [DynamicData(nameof(GetMatrix), DynamicDataSourceType.Method)] + public async Task RetryFailedTests_OnlyRetryTimes_Succeeds(string tfm, bool failOnly) + { + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); + string resultDirectory = Path.Combine(testHost.DirectoryName, Guid.NewGuid().ToString("N")); + TestHostResult testHostResult = await testHost.ExecuteAsync( + $"--retry-failed-tests 3 --results-directory {resultDirectory}", + new() + { + { EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT, "1" }, + { "METHOD1", "1" }, + { "FAIL", failOnly ? "1" : "0" }, + { "RESULTDIR", resultDirectory }, + }); + + if (!failOnly) + { + testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertOutputContains("Tests suite completed successfully in 2 attempts"); + testHostResult.AssertOutputContains("Failed! -"); + testHostResult.AssertOutputContains("Passed! -"); + } + else + { + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContains("Tests suite failed in all 4 attempts"); + testHostResult.AssertOutputContains("Tests suite failed, total failed tests: 1, exit code: 2, attempt: 1/4"); + testHostResult.AssertOutputContains("Tests suite failed, total failed tests: 1, exit code: 2, attempt: 2/4"); + testHostResult.AssertOutputContains("Tests suite failed, total failed tests: 1, exit code: 2, attempt: 3/4"); + testHostResult.AssertOutputContains("Tests suite failed, total failed tests: 1, exit code: 2, attempt: 4/4"); + testHostResult.AssertOutputDoesNotContain("Tests suite failed, total failed tests: 1, exit code: 2, attempt: 5/4"); + testHostResult.AssertOutputContains("Failed! -"); + } + } + + [TestMethod] + [DynamicData(nameof(GetMatrix), DynamicDataSourceType.Method)] + public async Task RetryFailedTests_MaxPercentage_Succeeds(string tfm, bool fail) + { + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); + string resultDirectory = Path.Combine(testHost.DirectoryName, Guid.NewGuid().ToString("N")); + TestHostResult testHostResult = await testHost.ExecuteAsync( + $"--retry-failed-tests 3 --retry-failed-tests-max-percentage 50 --results-directory {resultDirectory}", + new() + { + { EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT, "1" }, + { "RESULTDIR", resultDirectory }, + { "METHOD1", "1" }, + { fail ? "METHOD2" : "UNUSED", "1" }, + }); + + string retriesPath = Path.Combine(resultDirectory, "Retries"); + Assert.IsTrue(Directory.Exists(retriesPath)); + string[] retriesDirectories = Directory.GetDirectories(retriesPath); + Assert.AreEqual(1, retriesDirectories.Length); + string createdDirName = Path.GetFileName(retriesDirectories[0]); + + // Asserts that we are not using long names, to reduce long path issues. + // See https://github.com/microsoft/testfx/issues/4002 + Assert.AreEqual(5, createdDirName.Length, $"Expected directory '{createdDirName}' to be of length 5."); + + if (fail) + { + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContains("Failure threshold policy is enabled, failed tests will not be restarted."); + testHostResult.AssertOutputContains("Percentage failed threshold is 50% and 66.67% tests failed (2/3)"); + testHostResult.AssertOutputContains("Failed! -"); + } + else + { + testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertOutputContains("Tests suite completed successfully in 2 attempts"); + testHostResult.AssertOutputContains("Failed! -"); + testHostResult.AssertOutputContains("Passed! -"); + } + } + + [TestMethod] + [DynamicData(nameof(GetMatrix), DynamicDataSourceType.Method)] + public async Task RetryFailedTests_MaxTestsCount_Succeeds(string tfm, bool fail) + { + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); + string resultDirectory = Path.Combine(testHost.DirectoryName, Guid.NewGuid().ToString("N")); + TestHostResult testHostResult = await testHost.ExecuteAsync( + $"--retry-failed-tests 3 --retry-failed-tests-max-tests 1 --results-directory {resultDirectory}", + new() + { + { EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT, "1" }, + { "RESULTDIR", resultDirectory }, + { "METHOD1", "1" }, + { fail ? "METHOD2" : "UNUSED", "1" }, + }); + + if (fail) + { + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContains("Failure threshold policy is enabled, failed tests will not be restarted."); + testHostResult.AssertOutputContains("Maximum failed tests threshold is 1 and 2 tests failed"); + testHostResult.AssertOutputContains("Failed! -"); + } + else + { + testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertOutputContains("Tests suite completed successfully in 2 attempts"); + testHostResult.AssertOutputContains("Failed! -"); + testHostResult.AssertOutputContains("Passed! -"); + } + } + + // We use crash dump, not supported in NetFramework at the moment + [TestMethod] + [DynamicData(nameof(TargetFrameworks.NetForDynamicData), typeof(TargetFrameworks))] + public async Task RetryFailedTests_MoveFiles_Succeeds(string tfm) + => await RetryHelper.RetryAsync( + async () => + { + var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); + string resultDirectory = Path.Combine(testHost.DirectoryName, Guid.NewGuid().ToString("N")); + TestHostResult testHostResult = await testHost.ExecuteAsync( + $"--report-trx --crashdump --retry-failed-tests 1 --results-directory {resultDirectory}", + new() + { + { EnvironmentVariableConstants.TESTINGPLATFORM_TELEMETRY_OPTOUT, "1" }, + { "RESULTDIR", resultDirectory }, + { "CRASH", "1" }, + }); + + testHostResult.AssertExitCodeIs(ExitCodes.TestHostProcessExitedNonGracefully); + + string[] entries = Directory.GetFiles(resultDirectory, "*.*", SearchOption.AllDirectories) + .Where(x => !x.Contains("Retries", StringComparison.OrdinalIgnoreCase)) + .ToArray(); + + // 1 trx file + Assert.AreEqual(1, entries.Count(x => x.EndsWith("trx", StringComparison.OrdinalIgnoreCase))); + + // Number of dmp files seems to differ locally and in CI + int dumpFilesCount = entries.Count(x => x.EndsWith("dmp", StringComparison.OrdinalIgnoreCase)); + + if (dumpFilesCount == 2) + { + // Dump file inside the trx structure + Assert.AreEqual(1, entries.Count(x => x.Contains($"{Path.DirectorySeparatorChar}In{Path.DirectorySeparatorChar}", StringComparison.OrdinalIgnoreCase) && x.EndsWith("dmp", StringComparison.OrdinalIgnoreCase))); + } + else if (dumpFilesCount is 0 or > 2) + { + Assert.Fail($"Expected 1 or 2 dump files, but found {dumpFilesCount}"); + } + }, 3, TimeSpan.FromSeconds(5)); + + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) + { + public string TargetAssetPath => GetAssetPath(AssetName); + + public override IEnumerable<(string ID, string Name, string Code)> GetAssetsToGenerate() + { + yield return (AssetName, AssetName, + TestCode + .PatchTargetFrameworks(TargetFrameworks.All) + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); + } + + private const string TestCode = """ +#file RetryFailedTests.csproj + + + $TargetFrameworks$ + enable + enable + Exe + true + preview + + + + + + + + +#file Program.cs +using Microsoft.Testing.Extensions; +using Microsoft.Testing.Extensions.TrxReport.Abstractions; +using Microsoft.Testing.Platform.Builder; +using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.Testing.Platform.Extensions.Messages; +using Microsoft.Testing.Platform.Extensions.TestFramework; +using Microsoft.Testing.Platform.Services; + +public class Program +{ + public static async Task Main(string[] args) + { + ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); + builder.RegisterTestFramework( + sp => new TestFrameworkCapabilities(new TrxReportCapability()), + (_,__) => new DummyTestFramework()); + builder.AddCrashDumpProvider(); + builder.AddTrxReportProvider(); + builder.AddRetryProvider(); + using ITestApplication app = await builder.BuildAsync(); + return await app.RunAsync(); + } +} + +public class TrxReportCapability : ITrxReportCapability +{ + bool ITrxReportCapability.IsSupported { get; } = true; + void ITrxReportCapability.Enable() + { + } +} + +public class DummyTestFramework : ITestFramework, IDataProducer +{ + public string Uid => nameof(DummyTestFramework); + + public string Version => "2.0.0"; + + public string DisplayName => nameof(DummyTestFramework); + + public string Description => nameof(DummyTestFramework); + + public Type[] DataTypesProduced => new[] { typeof(TestNodeUpdateMessage) }; + + public Task IsEnabledAsync() => Task.FromResult(true); + + public Task CreateTestSessionAsync(CreateTestSessionContext context) + => Task.FromResult(new CreateTestSessionResult() { IsSuccess = true }); + + public Task CloseTestSessionAsync(CloseTestSessionContext context) + => Task.FromResult(new CloseTestSessionResult() { IsSuccess = true }); + + public async Task ExecuteRequestAsync(ExecuteRequestContext context) + { + bool fail = Environment.GetEnvironmentVariable("FAIL") == "1"; + // Tests are using this env variable so it won't be null. + string resultDir = Environment.GetEnvironmentVariable("RESULTDIR")!; + bool crash = Environment.GetEnvironmentVariable("CRASH") == "1"; + + if (await TestMethod1(fail, resultDir, crash)) + { + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "1", DisplayName = "TestMethod1", Properties = new(PassedTestNodeStateProperty.CachedInstance) })); + } + else + { + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "1", DisplayName = "TestMethod1", Properties = new(new FailedTestNodeStateProperty()) })); + } + + if (await TestMethod2(fail, resultDir)) + { + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "2", DisplayName = "TestMethod2", Properties = new(PassedTestNodeStateProperty.CachedInstance) })); + } + else + { + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "2", DisplayName = "TestMethod2", Properties = new(new FailedTestNodeStateProperty()) })); + } + + if (await TestMethod3(fail, resultDir)) + { + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "3", DisplayName = "TestMethod3", Properties = new(PassedTestNodeStateProperty.CachedInstance) })); + } + else + { + await context.MessageBus.PublishAsync(this, new TestNodeUpdateMessage(context.Request.Session.SessionUid, + new TestNode() { Uid = "3", DisplayName = "TestMethod3", Properties = new(new FailedTestNodeStateProperty()) })); + } + + context.Complete(); + } + + private async Task TestMethod1(bool fail, string resultDir, bool crash) + { + if (crash) + { + Environment.FailFast("CRASH"); + } + + bool envVar = Environment.GetEnvironmentVariable("METHOD1") is null; + + if (envVar) return true; + + string succeededFile = Path.Combine(resultDir, "M1_Succeeds"); + bool fileExits = File.Exists(succeededFile); + bool assert = envVar && fileExits; + + if (!fail) + { + if (fileExits) return true; + if (!assert) File.WriteAllText(succeededFile,""); + } + + return assert; + } + + private async Task TestMethod2(bool fail, string resultDir) + { + bool envVar = Environment.GetEnvironmentVariable("METHOD2") is null; + System.Console.WriteLine("envVar " + envVar); + + if (envVar) return true; + + string succeededFile = Path.Combine(resultDir,"M2_Succeeds"); + bool fileExits = File.Exists(succeededFile); + bool assert = envVar && fileExits; + + if (!fail) + { + if (fileExits) return true; + if (!assert) File.WriteAllText(succeededFile,""); + } + + return assert; + } + + private async Task TestMethod3(bool fail, string resultDir) + { + bool envVar = Environment.GetEnvironmentVariable("METHOD3") is null; + + if (envVar) return true; + + string succeededFile = Path.Combine(resultDir,"M3_Succeeds"); + bool fileExits = File.Exists(succeededFile); + bool assert = envVar && fileExits; + + if (!fail) + { + if (fileExits) return true; + if (!assert) File.WriteAllText(succeededFile,""); + } + + return assert; + } +} +"""; + } +} diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs index 91a7a293f8..0e0bdc1db7 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TimeoutTests.cs @@ -160,8 +160,7 @@ public Task ExecuteRequestAsync(ExecuteRequestContext context) yield return (AssetName, AssetName, TestCode .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); } } } diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs index 9c86e5770a..979364b7e4 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs @@ -347,8 +347,7 @@ public void TestMethod1(string s) yield return (AssetName, AssetName, TestCode .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) - .PatchCodeWithReplace("$MicrosoftTestingEnterpriseExtensionsVersion$", MicrosoftTestingEnterpriseExtensionsVersion)); + .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion)); yield return (WithSkippedTest, AssetNameUsingMSTest, MSTestCode .PatchTargetFrameworks(TargetFrameworks.All) diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Microsoft.Testing.Extensions.UnitTests.csproj b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Microsoft.Testing.Extensions.UnitTests.csproj index e016c30a3a..35150deb12 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Microsoft.Testing.Extensions.UnitTests.csproj +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Microsoft.Testing.Extensions.UnitTests.csproj @@ -13,6 +13,9 @@ TargetFramework=netstandard2.0 + + TargetFramework=netstandard2.0 + diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/RetryTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/RetryTests.cs new file mode 100644 index 0000000000..5fe152714f --- /dev/null +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/RetryTests.cs @@ -0,0 +1,115 @@ +#pragma warning disable IDE0073 // The file header does not match the required text +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. +#pragma warning restore IDE0073 // The file header does not match the required text + +using System.Globalization; + +using Microsoft.Testing.Extensions.Policy; +using Microsoft.Testing.Extensions.UnitTests.Helpers; +using Microsoft.Testing.Platform.Extensions.CommandLine; + +namespace Microsoft.Testing.Extensions.UnitTests; + +[TestClass] +public class RetryTests +{ + [DataRow(RetryCommandLineOptionsProvider.RetryFailedTestsOptionName, "32")] + [DataRow(RetryCommandLineOptionsProvider.RetryFailedTestsMaxPercentageOptionName, "32")] + [DataRow(RetryCommandLineOptionsProvider.RetryFailedTestsMaxTestsOptionName, "32")] + [TestMethod] + public async Task IsValid_If_CorrectInteger_Is_Provided_For_RetryOptions(string optionName, string retries) + { + var provider = new RetryCommandLineOptionsProvider(); + CommandLineOption option = provider.GetCommandLineOptions().First(x => x.Name == optionName); + + ValidationResult validateOptionsResult = await provider.ValidateOptionArgumentsAsync(option, [retries]).ConfigureAwait(false); + Assert.IsTrue(validateOptionsResult.IsValid); + Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); + } + + [DataRow(RetryCommandLineOptionsProvider.RetryFailedTestsOptionName, "invalid")] + [DataRow(RetryCommandLineOptionsProvider.RetryFailedTestsOptionName, "32.32")] + [DataRow(RetryCommandLineOptionsProvider.RetryFailedTestsMaxPercentageOptionName, "invalid")] + [DataRow(RetryCommandLineOptionsProvider.RetryFailedTestsMaxPercentageOptionName, "32.32")] + [DataRow(RetryCommandLineOptionsProvider.RetryFailedTestsMaxTestsOptionName, "invalid")] + [DataRow(RetryCommandLineOptionsProvider.RetryFailedTestsMaxTestsOptionName, "32.32")] + [TestMethod] + public async Task IsInvalid_If_IncorrectInteger_Is_Provided_For_RetryOptions(string optionName, string retries) + { + var provider = new RetryCommandLineOptionsProvider(); + CommandLineOption option = provider.GetCommandLineOptions().First(x => x.Name == optionName); + + ValidationResult validateOptionsResult = await provider.ValidateOptionArgumentsAsync(option, [retries]).ConfigureAwait(false); + Assert.IsFalse(validateOptionsResult.IsValid); + Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, Policy.Resources.ExtensionResources.RetryFailedTestsOptionSingleIntegerArgumentErrorMessage, optionName), validateOptionsResult.ErrorMessage); + } + + [TestMethod] + public async Task IsInvalid_When_MaxPercentage_MaxTests_BothProvided() + { + var provider = new RetryCommandLineOptionsProvider(); + var options = new Dictionary + { + { RetryCommandLineOptionsProvider.RetryFailedTestsMaxPercentageOptionName, [] }, + { RetryCommandLineOptionsProvider.RetryFailedTestsMaxTestsOptionName, [] }, + }; + + ValidationResult validateOptionsResult = await provider.ValidateCommandLineOptionsAsync(new TestCommandLineOptions(options)).ConfigureAwait(false); + Assert.IsFalse(validateOptionsResult.IsValid); + Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, Policy.Resources.ExtensionResources.RetryFailedTestsPercentageAndCountCannotBeMixedErrorMessage, RetryCommandLineOptionsProvider.RetryFailedTestsMaxPercentageOptionName, RetryCommandLineOptionsProvider.RetryFailedTestsMaxTestsOptionName), validateOptionsResult.ErrorMessage); + } + + [TestMethod] + public async Task IsInvalid_When_MaxPercentage_Provided_But_TestOption_Missing() + { + var provider = new RetryCommandLineOptionsProvider(); + var options = new Dictionary + { + { RetryCommandLineOptionsProvider.RetryFailedTestsMaxPercentageOptionName, [] }, + }; + + ValidationResult validateOptionsResult = await provider.ValidateCommandLineOptionsAsync(new TestCommandLineOptions(options)).ConfigureAwait(false); + Assert.IsFalse(validateOptionsResult.IsValid); + Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, Policy.Resources.ExtensionResources.RetryFailedTestsOptionIsMissingErrorMessage, RetryCommandLineOptionsProvider.RetryFailedTestsMaxPercentageOptionName, RetryCommandLineOptionsProvider.RetryFailedTestsOptionName), validateOptionsResult.ErrorMessage); + } + + [TestMethod] + public async Task IsInvalid_When_MaxTests_Provided_But_TestOption_Missing() + { + var provider = new RetryCommandLineOptionsProvider(); + var options = new Dictionary + { + { RetryCommandLineOptionsProvider.RetryFailedTestsMaxTestsOptionName, [] }, + }; + + ValidationResult validateOptionsResult = await provider.ValidateCommandLineOptionsAsync(new TestCommandLineOptions(options)).ConfigureAwait(false); + Assert.IsFalse(validateOptionsResult.IsValid); + Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, Policy.Resources.ExtensionResources.RetryFailedTestsOptionIsMissingErrorMessage, RetryCommandLineOptionsProvider.RetryFailedTestsMaxTestsOptionName, RetryCommandLineOptionsProvider.RetryFailedTestsOptionName), validateOptionsResult.ErrorMessage); + } + + [DataRow(true, false)] + [DataRow(false, true)] + [TestMethod] + public async Task IsValid_When_TestOption_Provided_With_Either_MaxPercentage_MaxTests_Provided(bool isMaxPercentageSet, bool isMaxTestsSet) + { + var provider = new RetryCommandLineOptionsProvider(); + var options = new Dictionary + { + { RetryCommandLineOptionsProvider.RetryFailedTestsOptionName, [] }, + }; + if (isMaxPercentageSet) + { + options.Add(RetryCommandLineOptionsProvider.RetryFailedTestsMaxPercentageOptionName, []); + } + + if (isMaxTestsSet) + { + options.Add(RetryCommandLineOptionsProvider.RetryFailedTestsMaxTestsOptionName, []); + } + + ValidationResult validateOptionsResult = await provider.ValidateCommandLineOptionsAsync(new TestCommandLineOptions(options)).ConfigureAwait(false); + Assert.IsTrue(validateOptionsResult.IsValid); + Assert.IsTrue(string.IsNullOrEmpty(validateOptionsResult.ErrorMessage)); + } +} From a010db2195831ac8eaf1611ce4f557a57a87646a Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 17 Dec 2024 23:19:39 -0800 Subject: [PATCH 129/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2603905 --- .../Resources/xlf/Resource.cs.xlf | 6 +++--- .../Resources/xlf/Resource.de.xlf | 6 +++--- .../Resources/xlf/Resource.es.xlf | 6 +++--- .../Resources/xlf/Resource.fr.xlf | 6 +++--- .../Resources/xlf/Resource.it.xlf | 6 +++--- .../Resources/xlf/Resource.ja.xlf | 6 +++--- .../Resources/xlf/Resource.ko.xlf | 6 +++--- .../Resources/xlf/Resource.pl.xlf | 6 +++--- .../Resources/xlf/Resource.pt-BR.xlf | 6 +++--- .../Resources/xlf/Resource.ru.xlf | 6 +++--- .../Resources/xlf/Resource.tr.xlf | 6 +++--- .../Resources/xlf/Resource.zh-Hans.xlf | 6 +++--- .../Resources/xlf/Resource.zh-Hant.xlf | 6 +++--- .../MSTest.Analyzers/xlf/Resources.cs.xlf | 4 ++-- .../MSTest.Analyzers/xlf/Resources.de.xlf | 20 +++++++++---------- .../MSTest.Analyzers/xlf/Resources.es.xlf | 20 +++++++++---------- .../MSTest.Analyzers/xlf/Resources.fr.xlf | 4 ++-- .../MSTest.Analyzers/xlf/Resources.it.xlf | 20 +++++++++---------- .../MSTest.Analyzers/xlf/Resources.ja.xlf | 4 ++-- .../MSTest.Analyzers/xlf/Resources.ko.xlf | 20 +++++++++---------- .../MSTest.Analyzers/xlf/Resources.pl.xlf | 4 ++-- .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 4 ++-- .../MSTest.Analyzers/xlf/Resources.ru.xlf | 4 ++-- .../MSTest.Analyzers/xlf/Resources.tr.xlf | 4 ++-- .../xlf/Resources.zh-Hans.xlf | 4 ++-- .../xlf/Resources.zh-Hant.xlf | 20 +++++++++---------- 26 files changed, 105 insertions(+), 105 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf index 14333c6b35..8d859f07e9 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf @@ -78,17 +78,17 @@ byl však přijat tento počet argumentů: {4} s typy {5}. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Typ obecného parametru '{0}' nelze odvodit. The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + Obecná testovací metoda '{0}' nemá argumenty, takže obecný parametr nelze odvodit. Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Byly nalezeny dva konfliktní typy pro obecný parametr '{0}'. Konfliktní typy jsou '{1}' a '{2}'. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf index 95ca34eff8..5829dd95ff 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf @@ -78,17 +78,17 @@ aber empfing {4} Argument(e) mit den Typen „{5}“. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Der Typ des generischen Parameters '{0}' konnte nicht abgeleitet werden. The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + Die generische Testmethode '{0}' hat keine Argumente, daher kann der generische Parameter nicht abgeleitet werden. Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Es wurden zwei in Konflikt stehende Typen für den generischen Parameter '{0}' gefunden. Die in Konflikt stehenden Typen sind '{1}' und '{2}'. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf index f10464df2f..915345816f 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf @@ -78,17 +78,17 @@ pero recibió {4} argumento(s), con los tipos "{5}". The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + No se pudo inferir el tipo del parámetro genérico '{0}'. The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + El método de prueba genérico '{0}' no tiene argumentos, por lo que no se puede inferir el parámetro genérico. Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Se encontraron dos tipos en conflicto para el parámetro genérico '{0}'. Los tipos en conflicto son '{1}' y '{2}'. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf index 4c83356a65..60bfc69ee9 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf @@ -78,17 +78,17 @@ mais a reçu {4} argument(s), avec les types « {5} ». The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Impossible de déduire le type du paramètre générique '{0}'. The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + La méthode de test générique '{0}' n’a pas d’arguments. Le paramètre générique ne peut donc pas être déduit. Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Deux types en conflit ont été trouvés pour le paramètre générique '{0}'. Les types en conflit sont '{1}' et '{2}'. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf index c12e6b26a8..74bb819f4e 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf @@ -78,17 +78,17 @@ ma ha ricevuto {4} argomenti, con tipi "{5}". The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Impossibile dedurre il tipo del parametro generico '{0}'. The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + Il metodo di test generico '{0}' non contiene argomenti, di conseguenza non è possibile dedurre il parametro generico. Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Sono stati trovati due tipi in conflitto per il parametro generico '{0}'. I tipi in conflitto sono '{1}' e '{2}'. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf index 6fe9d8a46f..6b7c27488b 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf @@ -79,17 +79,17 @@ but received {4} argument(s), with types '{5}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + ジェネリック パラメーター '{0}' の型を推論できませんでした。 The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + '{0}' ジェネリック テスト メソッドに引数がないため、ジェネリック パラメーターを推論できません。 Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + ジェネリック パラメーター '{0}' に 2 つの競合する型が見つかりました。競合する型は '{1}' で '{2}'。 diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf index 68c71d989c..ba9e50cf45 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf @@ -78,17 +78,17 @@ but received {4} argument(s), with types '{5}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + 제네릭 매개 변수 '{0}' 형식을 유추할 수 없습니다. The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + 제네릭 테스트 메서드 '{0}' 인수가 없으므로 제네릭 매개 변수를 유추할 수 없습니다. Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + 제네릭 매개 변수 '{0}' 충돌하는 두 가지 형식을 찾았습니다. 충돌하는 형식은 '{1}' '{2}'. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf index 18c3034507..696cc2e048 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf @@ -78,17 +78,17 @@ ale liczba odebranych argumentów to {4} z typami „{5}”. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Nie można wywnioskować typu '{0}' parametru ogólnego. The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + Ogólna metoda testowa '{0}' nie ma argumentów, więc nie można wywnioskować parametru ogólnego. Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Znaleziono dwa typy powodujące konflikt dla parametru ogólnego '{0}'. Typy powodujące konflikty są '{1}' i '{2}'. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf index cb3c269ffe..03c45b6449 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf @@ -78,17 +78,17 @@ mas {4} argumentos recebidos, com tipos '{5}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Não foi possível inferir o tipo '{0}' parâmetro genérico. The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + O método de teste genérico '{0}' não tem argumentos, portanto, o parâmetro genérico não pode ser inferido. Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Foram encontrados dois tipos conflitativos para parâmetro genérico '{0}'. Os tipos conflitativos são '{1}' e '{2}'. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf index 2e1a3dbf58..86afbe8fe8 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf @@ -78,17 +78,17 @@ but received {4} argument(s), with types '{5}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Не удалось определить тип универсального '{0}' параметра. The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + Универсальный метод '{0}' не имеет аргументов, поэтому невозможно вывести универсальный параметр. Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Обнаружены два конфликтующих типа для универсального параметра '{0}'. Конфликтуют типы '{1}' и '{2}'. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf index c440ff0b10..22a786a1bb 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf @@ -78,17 +78,17 @@ ancak, '{5}' türüyle {4} argüman aldı. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Genel parametre türü '{0}' çıkarsanamadı. The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + Genel test '{0}' bağımsız değişkene sahip olmadığından genel parametre çıkarsanamıyor. Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Genel parametre türü için iki çakışan tür '{0}'. Çakışan türler '{1}' '{2}'. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf index 05fec29a05..47986a4c29 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf @@ -78,17 +78,17 @@ but received {4} argument(s), with types '{5}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + 无法推断 '{0}' 泛型参数的类型。 The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + 泛型测试方法 '{0}' 没有参数,因此无法推断泛型参数。 Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + 发现泛型参数 '{0}' 的两个冲突类型。冲突类型 '{1}' 和 '{2}'。 diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf index 43ac773225..ae416802fd 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf @@ -78,17 +78,17 @@ but received {4} argument(s), with types '{5}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + 無法推斷泛型參數 '{0}' 的類型。 The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. - The generic test method '{0}' doesn't have arguments, so the generic parameter cannot be inferred. + 泛型測試方法 '{0}' 沒有自變數,因此無法推斷泛型參數。 Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + 發現兩個衝突的泛型參數類型 '{0}'。衝突的類型 '{1}' 且 '{2}'。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index 7c908215c1..b9e084dc25 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -253,12 +253,12 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Byly nalezeny dva konfliktní typy pro obecný parametr '{0}'. Konfliktní typy jsou '{1}' a '{2}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Typ obecného parametru '{0}' nelze odvodit. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 47965f258f..0a813b0b72 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -255,12 +255,12 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Es wurden zwei in Konflikt stehende Typen für den generischen Parameter '{0}' gefunden. Die in Konflikt stehenden Typen sind '{1}' und '{2}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Der Typ des generischen Parameters '{0}' konnte nicht abgeleitet werden. @@ -646,14 +646,14 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + Testmethoden, Methoden, die mit dem Attribut „[TestMethod]“ gekennzeichnet sind, sollten das folgende Layout berücksichtigen, um von MSTest als gültig angesehen zu werden: +– es darf „public“ (oder „internal“ sein, wenn das Attribut „[assembly: DiscoverInternals]“ festgelegt ist) +– es darf nicht „static“ sein +– es kann generisch sein, solange Typparameter abgeleitet werden können und Argumenttypen kompatibel sind +– es darf nicht „abstract“ sein +– der Rückgabetyp muss „void“, „Task“ oder „ValueTask“ sein +– es darf nicht „async void“ sein +– es darf keine spezielle Methode (Finalizer, Operator...) sein. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index a20c8f195b..9ce8af5290 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -253,12 +253,12 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Se encontraron dos tipos en conflicto para el parámetro genérico '{0}'. Los tipos en conflicto son '{1}' y '{2}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + No se pudo inferir el tipo del parámetro genérico '{0}'. @@ -644,14 +644,14 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + Los métodos de prueba, los métodos marcados con el atributo '[TestMethod]', deben respetar el siguiente diseño para que MSTest lo considere válido: +- debe ser 'public' (o 'internal' si se establece el atributo '[assembly: DiscoverInternals]') +- no debe ser 'static' +- puede ser genérico siempre y cuando se puedan inferir parámetros de tipo y los tipos de argumento sean compatibles +- no debe ser 'abstract' +- el tipo de valor devuelto debe ser 'void', 'Task' o 'ValueTask' +- no debe ser 'async void' +- no debe ser un método especial (finalizador, operador...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 24d8c001b9..f55a879b13 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -253,12 +253,12 @@ Le type doit être une classe Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Deux types en conflit ont été trouvés pour le paramètre générique '{0}'. Les types en conflit sont '{1}' et '{2}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Impossible de déduire le type du paramètre générique '{0}'. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index 2c2296c26c..10154aa439 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -253,12 +253,12 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Sono stati trovati due tipi in conflitto per il parametro generico '{0}'. I tipi in conflitto sono '{1}' e '{2}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Impossibile dedurre il tipo del parametro generico '{0}'. @@ -644,14 +644,14 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + I metodi di test, metodi contrassegnati con l'attributo '[TestMethod]', devono rispettare il layout seguente per essere considerati validi da MSTest: +- devono essere “public” (o “internal” se l'attributo “[assembly: DiscoverInternals]” è impostato) +- non devono essere “static” +- possono essere generici purché i parametri di tipo possano essere dedotti e i tipi di argomento siano compatibili +- non devono essere “abstract” +- il tipo restituito deve essere “void”, “Task” o “ValueTask” +- non devono essere “async void” +- non devono essere un metodo speciale (finalizzatore, operatore...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 2461cd224f..d0527a3d77 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -253,12 +253,12 @@ The type declaring these methods should also respect the following rules: Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + ジェネリック パラメーター '{0}' に 2 つの競合する型が見つかりました。競合する型は '{1}' で '{2}'。 The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + ジェネリック パラメーター '{0}' の型を推論できませんでした。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 05d9b5d338..d164b31731 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -253,12 +253,12 @@ The type declaring these methods should also respect the following rules: Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + 제네릭 매개 변수 '{0}' 충돌하는 두 가지 형식을 찾았습니다. 충돌하는 형식은 '{1}' '{2}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + 제네릭 매개 변수 '{0}' 형식을 유추할 수 없습니다. @@ -644,14 +644,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + '[TestMethod]' 특성으로 표시된 메서드인 테스트 메서드는 MSTest에서 유효한 것으로 간주되도록 다음 레이아웃을 준수해야 합니다. +- 'public'(혹은 '[assembly: DiscoverInternals]' 특성이 설정된 경우 'internal')이어야 합니다. +- 'static'이 아니어야 합니다. +- 형식 매개 변수를 유추할 수 있고 인수 형식이 호환되는 경우 제네릭이 될 수 있습니다. +- 'abstract'가 아니어야 합니다. +- 반환 형식은 'void', 'Task' 또는 'ValueTask'여야 합니다. +- 'async void'가 아니어야 합니다. +- 특수 메서드(종료자, 연산자...)가 아니어야 합니다. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index d2c7472faf..be6c03b429 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -253,12 +253,12 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Znaleziono dwa typy powodujące konflikt dla parametru ogólnego '{0}'. Typy powodujące konflikty są '{1}' i '{2}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Nie można wywnioskować typu '{0}' parametru ogólnego. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index ac74336007..44803079cb 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -253,12 +253,12 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Foram encontrados dois tipos conflitativos para parâmetro genérico '{0}'. Os tipos conflitativos são '{1}' e '{2}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Não foi possível inferir o tipo '{0}' parâmetro genérico. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index 94ed043887..d2f619f344 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -257,12 +257,12 @@ The type declaring these methods should also respect the following rules: Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Обнаружены два конфликтующих типа для универсального параметра '{0}'. Конфликтуют типы '{1}' и '{2}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Не удалось определить тип универсального '{0}' параметра. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index e4ab404253..db0be22ae7 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -253,12 +253,12 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + Genel parametre türü için iki çakışan tür '{0}'. Çakışan türler '{1}' '{2}'. The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + Genel parametre türü '{0}' çıkarsanamadı. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 0a0749e344..9fb03859ef 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -253,12 +253,12 @@ The type declaring these methods should also respect the following rules: Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + 发现泛型参数 '{0}' 的两个冲突类型。冲突类型 '{1}' 和 '{2}'。 The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + 无法推断 '{0}' 泛型参数的类型。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index ef642a95d8..4f38c142a7 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -253,12 +253,12 @@ The type declaring these methods should also respect the following rules: Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. - Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + 發現兩個衝突的泛型參數類型 '{0}'。衝突的類型 '{1}' 且 '{2}'。 The type of the generic parameter '{0}' could not be inferred. - The type of the generic parameter '{0}' could not be inferred. + 無法推斷泛型參數 '{0}' 的類型。 @@ -644,14 +644,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + 測試方法 (標示為 '[TestMethod]' 屬性的方法) 應該遵循下列配置,讓 MSTest 視為有效: +- 它應該是 'public' (如果設定 '[assembly: DiscoverInternals]' 屬性,則為 'internal') +- 它應該是 'static' +- 只要可以推斷類型參數且引數類型相容,則其應為一般 +- 它不能是 'abstract' +- 傳回型別應為 'void'、'Task' 或 'ValueTask' +- 它不能是 'async void' +- 它不應該是特殊方法 (完成項、運算子...)。 From 8ef716f486084cd0ee13457addd3b9ca50f9eb14 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 17 Dec 2024 23:21:03 -0800 Subject: [PATCH 130/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2603905 --- .../Resources/xlf/ExtensionResources.cs.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.de.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.es.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.fr.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.it.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.ja.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.ko.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.pl.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.pt-BR.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.ru.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.tr.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.zh-Hans.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.zh-Hant.xlf | 6 +++--- 13 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf index bf24eb49fe..3353514f11 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Opětovné načítání za provozu se podporuje pouze v rozhraní .NET 6.0 nebo novějším. + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - Testovací relace opětovného načítání za provozu byla dokončena. + Hot reload test session completed Hot reload test session started - Testovací relace opětovného načítání za provozu byla spuštěna. + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf index 426d75c690..6c746dfbf0 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot Reload wird nur unter .NET 6.0 oder höher unterstützt. + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - Hot Reload-Testsitzung abgeschlossen + Hot reload test session completed Hot reload test session started - Hot Reload-Testsitzung gestartet + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf index e014452c97..c1f4fe7325 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - La recarga activa solo se admite en .NET 6.0 o posterior + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - Sesión de prueba de recarga activa completada + Hot reload test session completed Hot reload test session started - Se inició la sesión de prueba de recarga activa + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf index 311d81deac..3ae87ff772 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Le rechargement à chaud est uniquement pris en charge sur .NET 6.0 ou version ultérieure + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - Session de test de rechargement à chaud terminée + Hot reload test session completed Hot reload test session started - Session de test de rechargement à chaud démarrée + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf index f8c8801628..7f4825357d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Il ricaricamento rapido è supportato solo in .NET 6.0 o versione successiva + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - Sessione di test di ricaricamento rapido completata + Hot reload test session completed Hot reload test session started - Sessione di test di ricaricamento rapido avviata + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf index 73be365a65..7d4742beed 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - ホット リロードは .NET 6.0 以降でのみサポートされています + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - ホット リロード テスト セッションが完了しました + Hot reload test session completed Hot reload test session started - ホット リロード テスト セッションが開始されました + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf index 6dbdebaba2..d34213e843 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - 핫 다시 로드는 .NET 6.0 이상에서만 지원됩니다. + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - 핫 다시 로드 테스트 세션 완료 + Hot reload test session completed Hot reload test session started - 핫 다시 로드 테스트 세션 시작됨 + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf index 5b74462a80..b549ab6708 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Ponowne ładowanie na gorąco jest obsługiwane tylko na platformie .NET 6.0 lub nowszej + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - Sesja testu ponownego ładowania na gorąco została ukończona + Hot reload test session completed Hot reload test session started - Rozpoczęto sesję testu ponownego ładowania na gorąco + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf index 743f052c79..ec4eb5d6cf 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Só há suporte para a recarga dinâmica no .NET 6.0 ou superior + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - Sessão de teste de recarga dinâmica concluída + Hot reload test session completed Hot reload test session started - Sessão de teste de recarga dinâmica iniciada + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf index 1f26adfb86..6291815367 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Горячая перезагрузка поддерживается только в версии .NET 6.0 или более поздних версиях + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - Тестовый сеанс горячей перезагрузки завершен + Hot reload test session completed Hot reload test session started - Запущен тестовый сеанс горячей перезагрузки + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf index 70125a0e05..4a493df8a0 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Çalışırken yeniden yükleme yalnızca .NET 6.0 veya üzeri sürümlerde desteklenir + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - Çalışırken yeniden yükleme test oturumu tamamlandı + Hot reload test session completed Hot reload test session started - Çalışırken yeniden yükleme test oturumu başlatıldı + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf index af518ebd73..65bea4a4fd 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - 仅 .NET 6.0 或更高版本支持热重载 + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - 热重载测试会话已完成 + Hot reload test session completed Hot reload test session started - 热重载测试会话已启动 + Hot reload test session started diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf index 0fd9224ca7..265c54fa97 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - 只有 .NET 6.0 或更新版本才支援熱重新載入 + Hot reload is only supported on .NET 6.0 or greater Hot reload test session completed - 熱重新載入測試工作階段已完成 + Hot reload test session completed Hot reload test session started - 熱重新載入測試工作階段已開始 + Hot reload test session started From ea8fee7a00ad8db4031a3b357a5ed573e155c714 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Tue, 17 Dec 2024 23:22:26 -0800 Subject: [PATCH 131/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2603905 --- .../Resources/xlf/ExtensionResources.cs.xlf | 54 +++++++-------- .../Resources/xlf/ExtensionResources.de.xlf | 54 +++++++-------- .../Resources/xlf/ExtensionResources.es.xlf | 67 +++++++++---------- .../Resources/xlf/ExtensionResources.fr.xlf | 54 +++++++-------- .../Resources/xlf/ExtensionResources.it.xlf | 54 +++++++-------- .../Resources/xlf/ExtensionResources.ja.xlf | 54 +++++++-------- .../Resources/xlf/ExtensionResources.ko.xlf | 54 +++++++-------- .../Resources/xlf/ExtensionResources.pl.xlf | 54 +++++++-------- .../xlf/ExtensionResources.pt-BR.xlf | 54 +++++++-------- .../Resources/xlf/ExtensionResources.ru.xlf | 54 +++++++-------- .../Resources/xlf/ExtensionResources.tr.xlf | 54 +++++++-------- .../xlf/ExtensionResources.zh-Hans.xlf | 54 +++++++-------- .../xlf/ExtensionResources.zh-Hant.xlf | 54 +++++++-------- 13 files changed, 357 insertions(+), 358 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf index fa82dcccef..576477cd56 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Nepovedlo se vytvořit adresář opakovaných pokusů kvůli kolizím v adresáři {0}, a to ani přes opakované pokusy. + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Je povolena zásada prahové hodnoty selhání, neúspěšné testy se nerestartují. + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - Prahová hodnota maximálního počtu neúspěšných testů je {0} a tento počet testů selhal: {1}. + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Procentuální prahová hodnota selhání je {0} % a toto procento testů selhalo: {1} % ({2}/{3}). + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Přesouvání souborů prostředků posledního pokusu do výchozího adresáře výsledků +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - Soubor {0} se přesouvá do umístění {1}. + Moving file '{0}' to '{1}' Failed to start process '{0}' - Nepovedlo se spustit proces {0}. + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - Funkce opakování neúspěšných testů umožňuje po selhání znovu spustit test. + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - Opakovat neúspěšné testy + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Opakování neúspěšných testů funguje pouze s tvůrci typu Microsoft.Testing.Platform.Builder.TestApplicationBuilder. + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - Zakázat mechanismus opakování, pokud je procento neúspěšných testů větší než zadaná hodnota + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - Zakázat mechanismus opakování, pokud je počet neúspěšných testů větší než zadaná hodnota + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - Funkce opakování neúspěšných testů není v režimu opětovného načítání za provozu podporovaná. + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - Funkce opakování neúspěšných testů není v režimu serveru podporovaná. + Retry failed tests feature is not supported in server mode Enable retry failed tests - Povolit opakování neúspěšných testů + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - Možnost {0} vyžaduje, aby byla zadaná možnost {1}. + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - Možnost {0} očekává jeden celočíselný argument. + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - Možnost {0} nelze používat společně s možností {1}. + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - Hostitelský proces testu byl ukončen dříve, než se k němu mohla služba opakování připojit. Ukončovací kód: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Přesouvání souborů prostředků posledního pokusu do výchozího adresáře ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Sada testů byla úspěšně dokončena při {0} pokusech +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ Sada testů byla úspěšně dokončena při {0} pokusech Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Sada testů selhala, celkový počet neúspěšných testů: {0}, ukončovací kód: {1}, pokus: {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Sada testů selhala, celkový počet neúspěšných testů: {0}, ukončovací k ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Sada testů selhala při všech {0} pokusech +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Sada testů neproběhla úspěšně a ukončovací kód je jiný než 2 (neúspěšné testy). Selhání související s neočekávanou podmínkou. Ukončovací kód: {0} + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf index c7e44a2b31..a523163bae 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Fehler beim Erstellen des Wiederholungsverzeichnisses aufgrund von Konflikten in „{0}“ trotz erneuter Versuche. + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Wenn die Richtlinie für fehlgeschlagene Tests aktiviert ist, werden fehlgeschlagene Tests nicht neu gestartet. + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - Der Schwellenwert für die maximale Anzahl fehlerhafter Tests ist {0} und {1} Tests mit Fehlern + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Der Schwellenwert für den Prozentsatz fehlgeschlagener Tests ist {0} %, und {1} % Tests mit Fehlern ({2}/{3}) + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Medienobjektdateien des letzten Versuchs werden in das Standardergebnisverzeichnis verschoben. +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - Die Datei "{0}" wird nach "{1}" verschoben + Moving file '{0}' to '{1}' Failed to start process '{0}' - Fehler beim Starten von Prozess "{0}". + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - Das Feature zum Wiederholen fehlerhafter Tests ermöglicht es, die Testausführung bei einem Fehler neu zu starten. + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - Tests mit Wiederholungsfehlern + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Das Wiederholen fehlerhafter Tests funktioniert nur mit Generatoren vom Typ "Microsoft.Testing.Platform.Builder.TestApplicationBuilder". + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - Wiederholungsmechanismus deaktivieren, wenn der Prozentsatz fehlerhafter Tests größer als der angegebene Wert ist + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - Wiederholungsmechanismus deaktivieren, wenn die Anzahl fehlerhafter Tests größer als der angegebene Wert ist + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - Das Feature zum Wiederholen fehlerhafter Tests wird im Hot Reload-Modus nicht unterstützt + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - Das Feature zum Wiederholen fehlerhafter Tests wird im Servermodus nicht unterstützt + Retry failed tests feature is not supported in server mode Enable retry failed tests - Tests mit Wiederholungsfehlern aktivieren + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - Die "{0}"-Option erfordert, dass "{1}" angegeben ist + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - Option "{0}" erwartet ein einzelnes ganzzahliges Argument + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - Optionen "{0}" und "{1}" können nicht zusammen verwendet werden + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - Der Testhostprozess wurde beendet, bevor der Wiederholungsdienst eine Verbindung herstellen konnte. Exitcode: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Medienobjektdateien des letzten Versuchs werden in das Standardergebnisverzeichn ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Die Testsammlung wurde in {0} Versuchen erfolgreich abgeschlossen. +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ Die Testsammlung wurde in {0} Versuchen erfolgreich abgeschlossen. Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Fehler bei der Testsammlung. Fehlerhafte Tests gesamt: {0}, Exitcode: {1}, Versuch: {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Fehler bei der Testsammlung. Fehlerhafte Tests gesamt: {0}, Exitcode: {1}, Versu ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Fehler bei der Testsammlung bei allen {0} Versuchen. +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Bei der Testsammlung ist ein Fehler aufgetreten, und der Exitcode unterscheidet sich von 2 (fehlgeschlagene Tests). Fehler im Zusammenhang mit einer unerwarteten Bedingung. Exitcode "{0}" + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf index 5e008904ad..fa994d33b1 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - No se pudo crear el directorio de reintentos debido a colisiones en '{0}' a pesar de volver a intentarlo. + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - La directiva de umbral de errores está habilitada; no se reiniciarán las pruebas con errores. + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - El umbral máximo de pruebas con errores es {0} y {1} pruebas erróneas + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - El umbral de porcentaje de errores es {0}% y {1}% de pruebas no superadas ({2}/{3}) + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - -======================== -Moviendo los archivos de recursos del último intento al directorio de resultados predeterminado -======================== + +===================== +Moving last attempt asset files to the default result directory +===================== Moving file '{0}' to '{1}' - Moviendo el archivo '{0}' a '{1}' + Moving file '{0}' to '{1}' Failed to start process '{0}' - No se pudo iniciar el proceso '{0}' + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - La característica Reintentar pruebas con errores permite reiniciar la ejecución de pruebas en caso de error. + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - Reintentar pruebas con errores + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Reintentar pruebas con errores solo funciona con generadores de tipo "Microsoft.Testing.Platform.Builder.TestApplicationBuilder" + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - Deshabilitar el mecanismo de reintento si el porcentaje de pruebas con errores es mayor que el valor especificado + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - Deshabilitar el mecanismo de reintento si el número de pruebas con errores es mayor que el valor especificado + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - La característica Reintentar pruebas con errores no se admite en el modo de recarga activa + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - La característica reintentar pruebas con errores no se admite en el modo de servidor + Retry failed tests feature is not supported in server mode Enable retry failed tests - Habilitar pruebas con errores de reintento + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - La opción '{0}' requiere que se especifique la opción '{1}' + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - La opción '{0}' espera un único argumento entero + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - Las opciones '{0}' y '{1}' no se pueden usar juntas + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - El proceso de host de prueba se cerró antes de que el servicio de reintento pudiera conectarse a él. Código de salida: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Moviendo los archivos de recursos del último intento al directorio de resultado ===================== Tests suite completed successfully in {0} attempts ===================== - -======================== -El conjunto de pruebas se completó correctamente en {0} intentos + +===================== +Tests suite completed successfully in {0} attempts ===================== @@ -122,10 +122,10 @@ El conjunto de pruebas se completó correctamente en {0} intentos Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - -======================== -Error del conjunto de pruebas, total de pruebas erróneas: {0}, código de salida: {1}, intento: {2}/{3} -======================== + +===================== +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +===================== @@ -134,16 +134,15 @@ Error del conjunto de pruebas, total de pruebas erróneas: {0}, código de salid ===================== Tests suite failed in all {0} attempts ===================== - -======================== -Error del conjunto de pruebas en todos los - intentos{0} + +===================== +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Error del conjunto de pruebas con el código de salida distinto de 2 (pruebas con error). Error relacionado con una condición inesperada. Código de salida ''{0}'' + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf index debdb1c84f..4bce56d0c7 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Échec de la création du répertoire des nouvelles tentatives en raison de collisions dans « {0} » malgré une nouvelle tentative. + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - La stratégie de seuil d’échec est activée, les tests ayant échoué ne seront pas redémarrés. + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - Le seuil maximal des tests ayant échoué est {0} et {1} tests ont échoué + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Le seuil de pourcentage d’échec est {0}% et {1}% de tests ont échoué ({2}/{3}) + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Déplacement des fichiers de ressources de la dernière tentative vers le répertoire de résultats par défaut +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - Déplacement du fichier '{0}' vers '{1}' + Moving file '{0}' to '{1}' Failed to start process '{0}' - Échec de démarrage du processus « {0} » + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - La fonctionnalité de nouvelles tentatives de tests ayant échoué permet de redémarrer l’exécution des tests en cas d’échec. + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - Nouvelle tentative de tests ayant échoué + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Les nouvelles tentatives de tests ayant échoué fonctionnent uniquement avec les générateurs de type « Microsoft.Testing.Platform.Builder.TestApplicationBuilder » + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - Désactiver le mécanisme de nouvelle tentative si le pourcentage de tests ayant échoué est supérieur à la valeur spécifiée + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - Désactiver le mécanisme de nouvelle tentative si le nombre de tests ayant échoué est supérieur à la valeur spécifiée + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - La fonctionnalité de nouvelles tentatives de tests ayant échoué n’est pas prise en charge en mode rechargement à chaud + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - La fonctionnalité de nouvelles tentatives de tests ayant échoué n’est pas prise en charge en mode serveur + Retry failed tests feature is not supported in server mode Enable retry failed tests - Activer les nouvelles tentatives de tests ayant échoué + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - L’option '{0}' nécessite la spécification de l’option '{1}' + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - L’option '{0}' attend un seul argument entier + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - Les options «{0}» et «{1}» ne peuvent pas être utilisées ensemble + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - Le processus hôte de test s’est arrêté avant que le service de nouvelle tentative puisse s’y connecter. Code de sortie : {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Déplacement des fichiers de ressources de la dernière tentative vers le réper ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -La suite de tests s’est terminée correctement dans les {0} tentatives +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ La suite de tests s’est terminée correctement dans les {0} tentatives Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Échec de la suite de tests, nombre total de tests ayant échoué : {0}, code de sortie : {1}, tentative : {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Échec de la suite de tests dans toutes les {0} tentatives +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - La suite de tests a échoué avec un code de sortie différent de 2 (tests échoués). Défaillance liée à une condition inattendue. Code de sortie « {0} » + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf index 18d2389948..5ea2087640 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Non è possibile creare la directory dei tentativi a causa di collisioni in “{0}” nonostante i tentativi ripetuti. + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Se il criterio della soglia di errore è abilitato, i test non riusciti non verranno riavviati. + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - La soglia massima dei test non superati è {0} e i test {1} non sono riusciti + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - La soglia percentuale di operazioni non riuscite è del {0}% e del {1}% di test non riusciti ({2}/{3}) + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Spostamento dei file di asset dell'ultimo tentativo nella directory dei risultati predefinita +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - Spostamento del file '{0}' in '{1}' + Moving file '{0}' to '{1}' Failed to start process '{0}' - Impossibile avviare il processo '{0}' + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - La funzionalità di ripetizione dei test non riusciti consente di riavviare l'esecuzione dei test in caso di errore. + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - Ripeti i test non riusciti + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - La ripetizione dei test non riusciti funziona solo con i generatori di tipo 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder'. + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disabilita il meccanismo di ripetizione dei tentativi se la percentuale di test non riusciti è maggiore del valore specificato. + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - Disabilita il meccanismo di ripetizione dei tentativi se il numero di test non riusciti è maggiore del valore specificato. + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - La funzionalità di ripetizione dei test non riusciti non è supportata nella modalità di ricaricamento rapido. + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - La funzionalità di ripetizione dei test non riusciti non è supportata in modalità server + Retry failed tests feature is not supported in server mode Enable retry failed tests - Abilita la ripetizione dei test non riusciti + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - L'opzione '{0}' richiede l'opzione '{1}' da specificare + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - L'opzione '{0}' prevede un singolo argomento integer + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - Le opzioni '{0}' e '{1}' non possono essere usate insieme + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - Il processo host di test è stato chiuso prima che il servizio di ripetizione potesse connettersi ad esso. Codice di uscita: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Spostamento dei file di asset dell'ultimo tentativo nella directory dei risultat ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Il gruppo di test è stato completato correttamente in {0} tentativi +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ Il gruppo di test è stato completato correttamente in {0} tentativi Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Gruppo di test non riuscito, totale test non superati: {0}, codice di uscita: {1}, tentativo: {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Gruppo di test non riuscito, totale test non superati: {0}, codice di uscita: {1 ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Gruppo di test non riuscito in tutti i {0} tentativi +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Il gruppo di test non è riuscito e il codice di uscita è diverso da 2 (test non superati). Errore correlato a una condizione imprevista. Codice di uscita "{0}" + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf index 1e003faeed..2f065b6bef 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - 再試行中に '{0}' で競合が発生したため、再試行ディレクトリを作成できませんでした。 + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - 失敗しきい値ポリシーが有効になっているため、失敗したテストは再開されません。 + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - 失敗したテストの最大しきい値は {0} で、{1} のテストが失敗しました + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - 失敗率のしきい値は {0} % で、失敗したテストは {1} % です ({2}/{3}) + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -最後の試行資産ファイルを既定の結果ディレクトリに移動しています +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - ファイル '{0}' を '{1}' に移動しています + Moving file '{0}' to '{1}' Failed to start process '{0}' - 処理 '{0}' を開始できませんでした + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - 失敗したテストの再試行機能を使用すると、失敗時にテストの実行を再開できます。 + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - 失敗したテストの再試行 + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - 失敗したテストの再試行は、'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' 型のビルダーでのみ機能します + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - 失敗したテストの割合が指定した値を超える場合は再試行メカニズムを無効にする + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - 失敗したテストの数が指定した値を超える場合は再試行メカニズムを無効にする + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - 失敗したテストの再試行機能は、ホット リロード モードではサポートされていません + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - 失敗したテストの再試行機能は、サーバー モードではサポートされていません + Retry failed tests feature is not supported in server mode Enable retry failed tests - 失敗したテストの再試行を有効にする + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - オプション '{0}' では、オプション '{1}' を指定する必要があります + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - オプション '{0}' には 1 つの整数引数が必要です + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - オプション '{0}' と '{1}' を一緒に使用することはできません + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - 再試行サービスが接続する前に、テスト ホスト プロセスが終了しました。終了コード: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -テスト スイートが {0} 回の試行で正常に完了しました +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -テスト スイートが失敗しました。失敗したテストの合計数: {0}、終了コード: {1}、試行: {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -{0} 回の試行すべてでテスト スイートが失敗しました +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - テスト スイートが失敗し、終了コードが 2 (失敗したテスト) と異なりました。予期しない状態に関連するエラーです。終了コード '{0}' + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf index d521ae9495..eab60aa795 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - 다시 시도에도 불구하고 '{0}'의 충돌로 인해 재시도 디렉터리를 만들지 못했습니다. + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - 실패 임계값 정책을 사용하도록 설정했습니다. 실패한 테스트는 다시 시작되지 않습니다. + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - 실패한 최대 테스트 임계값이 {0}이고 {1} 테스트가 실패했습니다. + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - 실패한 임계값 백분율은 {0}%이며 {1}% 테스트에 실패했습니다({2}/{3}). + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -마지막 시도 자산 파일을 기본 결과 디렉터리로 이동 +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - 파일 {0}을(를) {1}(으)로 이동 + Moving file '{0}' to '{1}' Failed to start process '{0}' - 프로세스 '{0}'을(를) 시작하지 못했습니다. + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - 실패한 테스트 다시 시도 기능을 사용하면 실패 시 테스트 실행을 다시 시작할 수 있습니다. + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - 실패한 테스트 다시 시도 + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - 실패한 테스트 다시 시도는 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' 유형의 작성기에서만 작동합니다. + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - 실패한 테스트의 비율이 지정된 값보다 큰 경우 다시 시도 메커니즘을 사용하지 않도록 설정 + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - 실패한 테스트 수가 지정된 값보다 큰 경우 다시 시도 메커니즘을 사용하지 않도록 설정 + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - 실패한 테스트 다시 시도 기능은 핫 다시 로드 모드에서 지원되지 않습니다. + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - 실패한 테스트 다시 시도 기능은 서버 모드에서 지원되지 않습니다. + Retry failed tests feature is not supported in server mode Enable retry failed tests - 실패한 테스트 다시 시도 사용 + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - '{0}' 옵션을(를) 사용하려면 '{1}' 옵션을 지정해야 합니다. + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - '{0}' 옵션에는 단일 정수 인수가 필요합니다. + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - '{0}' 및 '{1}' 옵션은 함께 사용할 수 없습니다. + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - 다시 시도 서비스가 연결되기 전에 테스트 호스트 프로세스가 종료되었습니다. 종료 코드: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -테스트 도구 모음이 {0} 시도에서 완료되었습니다. +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -테스트 도구 모음이 실패했습니다. 실패한 총 테스트: {0}, 종료 코드: {1}, 시도: {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -테스트 도구 모음이 모든 {0} 시도에 실패했습니다 +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - 테스트 도구 모음이 2와 다른 종료 코드를 사용하여 실패했습니다(테스트 실패). 예기치 않은 조건과 관련된 오류입니다. 종료 코드 '{0}' + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf index a9d22ccaa5..49774ebf39 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Nie można utworzyć katalogu ponownych prób z powodu kolizji w katalogu „{0}” mimo ponownej próby. + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Zasady progu błędów są włączone, a testy zakończone niepowodzeniem nie zostaną ponownie uruchomione. + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - Próg maksymalnej liczby testów zakończonych niepowodzeniem to {0} i liczba testów zakończonych niepowodzeniem wyniosła {1} + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Wartość procentowa progu niepowodzenia wynosi {0}% i {1}% testów nie powiodło się ({2}/{3}) + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Przeniesienie plików zasobów ostatniej próby do domyślnego katalogu wyników +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - Przenoszenie pliku „{0}” do {1} + Moving file '{0}' to '{1}' Failed to start process '{0}' - Nie można uruchomić procesu „{0}” + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - Funkcja ponawiania testów zakończonych niepowodzeniem umożliwia ponowne uruchomienie wykonywania testu po niepowodzeniu. + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - Ponów próbę testów zakończonych niepowodzeniem + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Ponawianie testów zakończonych niepowodzeniem działa tylko z konstruktorami typu „Microsoft.Testing.Platform.Builder.TestApplicationBuilder” + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - Wyłącz mechanizm ponawiania prób, jeśli procent testów zakończonych niepowodzeniem jest większy niż określona wartość + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - Wyłącz mechanizm ponawiania prób, jeśli liczba testów zakończonych niepowodzeniem jest większa niż określona wartość + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - Funkcja ponownych testów zakończonych niepowodzeniem nie jest obsługiwana w trybie ponownego ładowania na gorąco + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - Funkcja ponawiania testów zakończonych niepowodzeniem nie jest obsługiwana w trybie serwera + Retry failed tests feature is not supported in server mode Enable retry failed tests - Włącz testy zakończone niepowodzeniem ponowień + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - Opcja „{0}” wymaga określenia opcji „{1}” + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - Opcja „{0}” oczekuje argumentu pojedynczej liczby całkowitej + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - Opcji „{0}” i „{1}” nie można używać razem + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - Proces hosta testowego zakończył się, zanim usługa ponawiania próby mogła nawiązać z nim połączenie. Kod zakończenia: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Przeniesienie plików zasobów ostatniej próby do domyślnego katalogu wyników ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Pomyślnie ukończono zestaw testów w {0} próbach +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ Pomyślnie ukończono zestaw testów w {0} próbach Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Zestaw testów nie powiódł się, łączna liczba testów zakończonych niepowodzeniem: {0}, kod zakończenia: {1}, próba: {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Zestaw testów nie powiódł się, łączna liczba testów zakończonych niepowo ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Zestaw testów nie powiódł się we wszystkich {0} próbach +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Zestaw testów nie powiódł się. Kod zakończenia jest inny niż 2 (testy zakończone niepowodzeniem). Błąd związany z nieoczekiwanym warunkiem. Kod zakończenia „{0}” + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf index 48006921c3..904a8aef49 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Falha ao criar o diretório de novas tentativas devido a colisões em '{0}', apesar das novas tentativas. + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - A política de limite de falha está habilitada, os testes com falha não serão reiniciados. + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - O limite máximo de testes com falha é {0} e {1} testes falharam + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - O limite de porcentagem com falha é {0}% e {1}% dos testes falharam ({2}/{3}) + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Movendo arquivos de ativo da última tentativa para o diretório de resultados padrão +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - Movendo o arquivo ''{0}'' para ''{1}'' + Moving file '{0}' to '{1}' Failed to start process '{0}' - Falha ao iniciar o processo '{0}' + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - O recurso repetir testes com falha permite reiniciar a execução de teste após falha. + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - Repetir testes com falha + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - A repetição de testes com falha funciona somente com construtores do tipo ''Microsoft.Testing.Platform.Builder.TestApplicationBuilder'' + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - Desabilitar o mecanismo de repetição se a porcentagem de testes com falha for maior que o valor especificado + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - Desabilitar o mecanismo de repetição se o número de testes com falha for maior que o valor especificado + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - Não há suporte para o recurso de repetição de testes com falha no modo de recarga dinâmica + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - Não há suporte para o recurso de repetição de testes com falha no modo de servidor + Retry failed tests feature is not supported in server mode Enable retry failed tests - Habilitar repetição de testes com falha + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - A opção ''{0}'' requer que a opção ''{1}'' seja especificada + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - A opção ''{0}'' espera um único argumento inteiro + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - As opções ''{0}'' e ''{1}'' não podem ser usadas juntas + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - O processo de host de teste foi encerrado antes que o serviço de repetição pudesse se conectar a ele. Código de saída: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Movendo arquivos de ativo da última tentativa para o diretório de resultados p ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Pacote de testes concluído com êxito em {0} tentativas +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ Pacote de testes concluído com êxito em {0} tentativas Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Falha no pacote de testes, total de testes com falha: {0}, código de saída: {1}, tentativa: {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Falha no pacote de testes, total de testes com falha: {0}, código de saída: {1 ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Falha no pacote de testes em todas as {0} tentativas +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Falha no conjunto de testes e código de saída diferente de 2 (testes com falha). Falha relacionada a uma condição inesperada. Código de saída "{0}" + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf index 31fb110066..5ec33b94b0 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Не удалось создать каталог повторов из-за конфликтов в {0}, несмотря на повторную попытку. + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Политика порога отказа включена, неудачные тесты не будут перезапущены. + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - Максимальное пороговое значение для неудачных тестов — {0}, и неудачных тестов — {1} + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Пороговое значение доли неудачных тестов — {0}%, и доля неудачных тестов — {1}% ({2}/{3}) + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Перемещение файлов ресурсов последней попытки в каталог результатов по умолчанию +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - Перемещение файла "{0}" в "{1}" + Moving file '{0}' to '{1}' Failed to start process '{0}' - Не удалось запустить процесс "{0}". + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - Функция повтора неудачных тестов позволяет перезапустить выполнение теста после сбоя. + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - Включить повтор неудачных тестов + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Повтор неудачных тестов работает только с построителями типа "Microsoft.Testing.Platform.Builder.TestApplicationBuilder" + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - Отключить механизм повторных попыток, если процент неудачных тестов превышает указанное значение + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - Отключить механизм повторных попыток, если число неудачных тестов превышает указанное значение + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - Функция повтора неудачных тестов не поддерживается в режиме горячей перезагрузки + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - Функция повтора неудачных тестов не поддерживается в режиме сервера + Retry failed tests feature is not supported in server mode Enable retry failed tests - Включить повтор неудачных тестов + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - Параметр "{0}" требует указания параметра "{1}" + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - Параметр "{0}" ожидает один целочисленный аргумент + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - Параметры "{0}" и "{1}" не могут использоваться вместе + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - Тестовый хост-процесс завершился прежде, чем к нему смогла подключиться служба повторной попытки. Код выхода: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Набор тестов успешно завершен за несколько ({0}) попыток +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Сбой набора тестов. Всего неудачных тестов: {0}, код завершения: {1}, попытка: {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Сбой набора тестов во всех попытках ({0}) +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Сбой набора тестов с кодом завершения, который отличается от 2 (неудачные тесты). Сбой, связанный с неожиданным условием. Код завершения "{0}" + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf index 74dd39e0dd..f5cce9f379 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Yeniden denemeye rağmen '{0} ' içindeki çakışmalar nedeniyle yeniden deneme dizini oluşturulamadı. + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Hata eşiği ilkesi etkinleştirildi, başarısız testler yeniden başlatılmaz. + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - Maksimum başarısız test eşiği {0} ve {1} test başarısız oldu + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Başarısız olan yüzde eşiği %{0} ve başarısız %{1} ({2}/{3}) + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Son deneme varlık dosyaları, varsayılan sonuç dizinine taşınıyor +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - '{0}' dosyasını '{1}'e taşıma + Moving file '{0}' to '{1}' Failed to start process '{0}' - '{0}' işlemi başlatılamadı + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - Başarısız testleri yeniden dene özelliği, başarısızlık durumunda test yürütmenin yeniden başlatılmasına olanak tanır. + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - Başarısız testleri yeniden deneyin + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Başarısız testleri yeniden deneme yalnızca 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' türündeki oluşturucularla çalışır + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - Başarısız testlerin yüzdesi belirtilen değerden büyükse yeniden deneme mekanizmasını devre dışı bırak + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - Başarısız testlerin yüzdesi belirtilen değerden büyükse yeniden deneme mekanizmasını devre dışı bırak + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - Başarısız testleri yeniden deneme özelliği, çalışırken yeniden yükleme modunda desteklenmez + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - Başarısız testleri yeniden deneme özelliği sunucu modunda desteklenmiyor + Retry failed tests feature is not supported in server mode Enable retry failed tests - Başarısız testleri yeniden denemeyi etkinleştir + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - '{0}' seçeneği, '{1}' seçeneğinin belirtilmesini gerektirir + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - Seçenek '{0}' tek bir tamsayı argümanı bekliyor + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - '{0}' ve '{1}' seçenekleri birlikte kullanılamaz + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - Yeniden deneme hizmeti ona bağlanamadan test ana makinesi işleminden çıkıldı. Çıkış kodu: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Son deneme varlık dosyaları, varsayılan sonuç dizinine taşınıyor ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Test paketi {0}denemede başarıyla tamamlandı +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ Test paketi {0}denemede başarıyla tamamlandı Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Test paketi başarısız oldu, toplam başarısız test: {0}, çıkış kodu: {1}, deneme: {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Test paketi başarısız oldu, toplam başarısız test: {0}, çıkış kodu: {1 ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Test paketi tüm {0} denemede başarısız oldu +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test paketi 2 (başarısız testler) kodundan farklı bir çıkış koduyla başarısız oldu. Beklenmeyen bir koşulla ilgili hata. Çıkış kodu '{0}' + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf index 9b66baf8c6..7ea7359fc1 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - 未能创建重试目录,因为尽管重试,但“{0}”中存在冲突。 + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - 已启用失败阈值策略,将不会重新启动失败的测试。 + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - 最大失败测试阈值为 {0},有 {1} 测试失败 + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - 失败的阈值百分比为 {0}%,有 {1}% 测试失败({2}/{3}) + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -正在将上次尝试资产文件移动到默认结果目录 +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - 正在将文件“{0}”移动到“{1}” + Moving file '{0}' to '{1}' Failed to start process '{0}' - 无法启动进程“{0}” + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - 重试失败的测试功能允许在失败时重新启动测试执行。 + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - 重试失败的测试 + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - 重试失败的测试仅适用于“Microsoft.Testing.Platform.Builder.TestApplicationBuilder”类型的生成器 + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - 如果失败的测试百分比大于指定值,则禁用重试机制 + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - 如果失败的测试数大于指定值,则禁用重试机制 + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - 热重载模式下不支持重试失败的测试功能 + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - 服务器模式不支持重试失败的测试功能 + Retry failed tests feature is not supported in server mode Enable retry failed tests - 启用重试失败的测试 + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - 选项“{0}”需要指定选项“{1}” + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - 选项“{0}”需要单一整数参数 + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - 选项“{0}”和“{1}”不能一起使用 + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - 测试主机进程已在重试服务可以连接到它之前退出。退出代码: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -测试套件在“{0}”次尝试中成功完成 +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -测试套件失败,失败的测试总数: {0},退出代码: {1},尝试次数: {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -测试套件在所有“{0}”尝试中均失败 +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - 测试套件失败,且退出代码不是 2 (测试失败)。与意外情况相关的失败。退出代码“{0}” + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf index 3113a1b002..5cc8cd74fb 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - 無法建立重試目錄,因為 '{0}' 中發生衝突,但仍在重試。 + Failed to create retries directory due to collisions in '{0}' despite re-trying. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - 已啟用失敗節流原則,將不會重新啟動失敗的測試。 + Failure threshold policy is enabled, failed tests will not be restarted. Maximum failed tests threshold is {0} and {1} tests failed - 失敗的測試閾值上限是 {0},有 {1} 個測試失敗 + Maximum failed tests threshold is {0} and {1} tests failed Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - 失敗的百分比閾值為 {0}%,有 {1}% 個測試失敗 ({2}/{3}) + Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -將上次嘗試的資產檔案移至預設結果目錄 +Moving last attempt asset files to the default result directory ===================== Moving file '{0}' to '{1}' - 正在將檔案 '{0}' 移至 '{1}' + Moving file '{0}' to '{1}' Failed to start process '{0}' - 無法啟動處理程序 '{0}' + Failed to start process '{0}' Retry failed tests feature allows to restart test execution upon failure. - 重試失敗的測試功能允許在失敗時重新啟動測試執行。 + Retry failed tests feature allows to restart test execution upon failure. Retry failed tests - 重試失敗的測試 + Retry failed tests Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - 重試失敗的測試僅適用於類型為 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' 的建立器 + Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' Disable retry mechanism if the percentage of failed tests is greater than the specified value - 如果失敗的測試百分比大於指定的值,則停用重試機制 + Disable retry mechanism if the percentage of failed tests is greater than the specified value Disable retry mechanism if the number of failed tests is greater than the specified value - 如果失敗的測試數目大於指定的值,則停用重試機制 + Disable retry mechanism if the number of failed tests is greater than the specified value Retry failed tests feature is not supported in hot reload mode - 熱重新載入模式不支援重試失敗的測試功能 + Retry failed tests feature is not supported in hot reload mode Retry failed tests feature is not supported in server mode - 伺服器模式不支援重試失敗的測試功能 + Retry failed tests feature is not supported in server mode Enable retry failed tests - 啟用重試失敗的測試 + Enable retry failed tests Option '{0}' requires option '{1}' to be specified - 使用 '{0}' 選項時必須指定選項 '{1}'。 + Option '{0}' requires option '{1}' to be specified Option '{0}' expects a single integer argument - 選項 '{0}' 需要單一整數引數 + Option '{0}' expects a single integer argument Options '{0}' and '{1}' cannot be used together - 選項 '{0}' 和 '{1}' 不能同時使用 + Options '{0}' and '{1}' cannot be used together Test host process exited before the retry service could connect to it. Exit code: {0} - 測試主機處理序在重試服務連線到它之前已結束。結束代碼: {0} + Test host process exited before the retry service could connect to it. Exit code: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -測試套件已順利在 {0} 次嘗試中完成 +Tests suite completed successfully in {0} attempts ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -測試套件失敗,失敗的測試總數: {0},結束代碼: {1},嘗試: {2}/{3} +Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -測試套件在所有 {0} 次嘗試中都失敗 +Tests suite failed in all {0} attempts ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - 測試套件失敗,結束代碼與 2 不同 (測試失敗)。與未預期情况有關的失敗。結束代碼 '{0}' + Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' From 18e39e9fe0ff621a973f77f90a297dcca014b487 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 18 Dec 2024 10:03:09 +0100 Subject: [PATCH 132/273] Use test display name instead of UID for slowest tests (#4377) --- .../SlowestTestsConsumer.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/SlowestTestsConsumer.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/SlowestTestsConsumer.cs index 15a0fec88d..cbf0399e57 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/SlowestTestsConsumer.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/SlowestTestsConsumer.cs @@ -9,7 +9,7 @@ namespace Microsoft.Testing.TestInfrastructure; public sealed class SlowestTestsConsumer : IDataConsumer, ITestSessionLifetimeHandler { - private readonly List<(string TestId, double Milliseconds)> _testPerf = []; + private readonly List<(string TestId, string DisplayName, double Milliseconds)> _testPerf = []; public Type[] DataTypesConsumed => [typeof(TestNodeUpdateMessage)]; @@ -32,7 +32,7 @@ public Task ConsumeAsync(IDataProducer dataProducer, IData value, CancellationTo } double milliseconds = testNodeUpdatedMessage.TestNode.Properties.Single().GlobalTiming.Duration.TotalMilliseconds; - _testPerf.Add((testNodeUpdatedMessage.TestNode.Uid, milliseconds)); + _testPerf.Add((testNodeUpdatedMessage.TestNode.Uid, testNodeUpdatedMessage.TestNode.DisplayName, milliseconds)); return Task.CompletedTask; } @@ -40,9 +40,9 @@ public Task ConsumeAsync(IDataProducer dataProducer, IData value, CancellationTo public Task OnTestSessionFinishingAsync(SessionUid sessionUid, CancellationToken cancellationToken) { Console.WriteLine("Slowest 10 tests"); - foreach ((string testId, double milliseconds) in _testPerf.OrderByDescending(x => x.Milliseconds).Take(10)) + foreach ((_, string displayName, double milliseconds) in _testPerf.OrderByDescending(x => x.Milliseconds).Take(10)) { - Console.WriteLine($"{testId} {TimeSpan.FromMilliseconds(milliseconds).TotalSeconds:F5}s"); + Console.WriteLine($"{displayName} {TimeSpan.FromMilliseconds(milliseconds).TotalSeconds:F5}s"); } return Task.CompletedTask; From 367b922da7f2172e0f935ae06dbec7d875770966 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 18 Dec 2024 11:01:43 +0100 Subject: [PATCH 133/273] Fix false positive for PreferTestCleanupOverDispose on non-test classes (#4378) --- .../PreferTestCleanupOverDisposeAnalyzer.cs | 16 +++++++++++----- ...referTestCleanupOverDisposeAnalyzerTests.cs | 18 ++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/PreferTestCleanupOverDisposeAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/PreferTestCleanupOverDisposeAnalyzer.cs index 1e22fec61a..b63e66970d 100644 --- a/src/Analyzers/MSTest.Analyzers/PreferTestCleanupOverDisposeAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/PreferTestCleanupOverDisposeAnalyzer.cs @@ -40,22 +40,28 @@ public override void Initialize(AnalysisContext context) context.RegisterCompilationStartAction(context => { - if (context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIDisposable, out INamedTypeSymbol? idisposableSymbol)) + if (context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIDisposable, out INamedTypeSymbol? idisposableSymbol) && + context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTestClassAttribute, out INamedTypeSymbol? testClassAttributeSymbol)) { INamedTypeSymbol? iasyncDisposableSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemIAsyncDisposable); INamedTypeSymbol? valueTaskSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingTasksValueTask); - context.RegisterSymbolAction(context => AnalyzeSymbol(context, idisposableSymbol, iasyncDisposableSymbol, valueTaskSymbol), SymbolKind.Method); + context.RegisterSymbolAction(context => AnalyzeSymbol(context, testClassAttributeSymbol, idisposableSymbol, iasyncDisposableSymbol, valueTaskSymbol), SymbolKind.Method); } }); } - private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol idisposableSymbol, INamedTypeSymbol? iasyncDisposableSymbol, + private static void AnalyzeSymbol( + SymbolAnalysisContext context, + INamedTypeSymbol testClassAttributeSymbol, + INamedTypeSymbol idisposableSymbol, + INamedTypeSymbol? iasyncDisposableSymbol, INamedTypeSymbol? valueTaskSymbol) { var methodSymbol = (IMethodSymbol)context.Symbol; - if (methodSymbol.IsAsyncDisposeImplementation(iasyncDisposableSymbol, valueTaskSymbol) - || methodSymbol.IsDisposeImplementation(idisposableSymbol)) + if (methodSymbol.ContainingType.GetAttributes().Any(x => x.AttributeClass.Inherits(testClassAttributeSymbol)) && + (methodSymbol.IsAsyncDisposeImplementation(iasyncDisposableSymbol, valueTaskSymbol) + || methodSymbol.IsDisposeImplementation(idisposableSymbol))) { context.ReportDiagnostic(methodSymbol.CreateDiagnostic(Rule)); } diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestCleanupOverDisposeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestCleanupOverDisposeAnalyzerTests.cs index 6681623645..fcee06522e 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestCleanupOverDisposeAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/PreferTestCleanupOverDisposeAnalyzerTests.cs @@ -10,6 +10,24 @@ namespace MSTest.Analyzers.Test; [TestClass] public sealed class PreferTestCleanupOverDisposeAnalyzerTests { + [TestMethod] + public async Task WhenNonTestClassHasDispose_NoDiagnostic() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + public class MyNonTestClass : IDisposable + { + public void Dispose() + { + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [TestMethod] public async Task WhenTestClassHasDispose_Diagnostic() { From 8cf945ba740034e37e0a16efddad85f6b0fb67bc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Dec 2024 11:11:07 +0100 Subject: [PATCH 134/273] [main] Bump Polly from 8.4.2 to 8.5.0 (#4375) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 6ddbf71dfa..310b6620af 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -76,7 +76,7 @@ - + From 85ce7595c252beacacec3ca13118d83a5f20a18e Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 18 Dec 2024 12:40:47 +0100 Subject: [PATCH 135/273] Remove unused resources in TestAdapter (#4379) --- .../Resources/Resource.Designer.cs | 27 ------------------- .../Resources/Resource.resx | 9 ------- .../Resources/xlf/Resource.cs.xlf | 15 ----------- .../Resources/xlf/Resource.de.xlf | 15 ----------- .../Resources/xlf/Resource.es.xlf | 15 ----------- .../Resources/xlf/Resource.fr.xlf | 15 ----------- .../Resources/xlf/Resource.it.xlf | 15 ----------- .../Resources/xlf/Resource.ja.xlf | 15 ----------- .../Resources/xlf/Resource.ko.xlf | 15 ----------- .../Resources/xlf/Resource.pl.xlf | 15 ----------- .../Resources/xlf/Resource.pt-BR.xlf | 15 ----------- .../Resources/xlf/Resource.ru.xlf | 15 ----------- .../Resources/xlf/Resource.tr.xlf | 15 ----------- .../Resources/xlf/Resource.zh-Hans.xlf | 15 ----------- .../Resources/xlf/Resource.zh-Hant.xlf | 15 ----------- 15 files changed, 231 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs b/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs index 5a7d1aa400..1614764330 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs +++ b/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs @@ -242,15 +242,6 @@ internal static string DuplicateConfigurationError { } } - /// - /// Looks up a localized string similar to '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>'. - /// - internal static string DynamicDataShouldBeValidMessageFormat_MemberType { - get { - return ResourceManager.GetString("DynamicDataShouldBeValidMessageFormat_MemberType", resourceCulture); - } - } - /// /// Looks up a localized string similar to The dynamic data source '{0}' in type '{1}' should exist and be a property or a method.. /// @@ -305,15 +296,6 @@ internal static string Execution_Test_Timeout { } } - /// - /// Looks up a localized string similar to Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data.. - /// - internal static string FailedFetchAttributeCache { - get { - return ResourceManager.GetString("FailedFetchAttributeCache", resourceCulture); - } - } - /// /// Looks up a localized string similar to Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1}. /// @@ -422,15 +404,6 @@ internal static string OlderTFMVersionFound { } } - /// - /// Looks up a localized string similar to An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8.. - /// - internal static string OlderTFMVersionFoundClassCleanup { - get { - return ResourceManager.GetString("OlderTFMVersionFoundClassCleanup", resourceCulture); - } - } - /// /// Looks up a localized string similar to Running tests in any of the provided sources is not supported for the selected platform. /// diff --git a/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx b/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx index 8ed6ddde11..4a476afa7d 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx +++ b/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx @@ -325,9 +325,6 @@ Error: {1} Exceptions thrown: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} {0}: Attribute full type name. @@ -339,9 +336,6 @@ Error: {1} The called code threw an exception that was caught, but the exception value was null - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} {0}: TypeName with namespace, @@ -408,9 +402,6 @@ but received {4} argument(s), with types '{5}'. Invalid value '{0}' for runsettings entry '{1}', setting will be ignored. - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - Both '.runsettings' and '.testconfig.json' files have been detected. Please select only one of these test configuration files. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf index 8d859f07e9..bb36585c60 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf @@ -61,11 +61,6 @@ byl však přijat tento počet argumentů: {4} s typy {5}. Byly zjištěny soubory .runsettings i .testconfig.json. Vyberte prosím jenom jeden z těchto souborů konfigurace testu. - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - Odkazovaný člen [DynamicData] {0}.{1} by měl vracet IEnumerable<object[]>, IEnumerable<Tuple> nebo IEnumerable<ValueTuple>. - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Chyba: {1} Vyvolané výjimky: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - Nepodařilo se získat mezipaměť atributů. Ignoruje se dědičnost atributů a spadání do „type defines Attribute model“, abychom získali určitá data. - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} Získání vlastních atributů pro typ {0} vyvolalo výjimku (bude ignorovat a používat způsob reflexe): {1} @@ -471,11 +461,6 @@ Chyba: {1} Volaný kód vyvolal výjimku, která byla zachycena, ale její hodnota byla null. - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - V sestavení je načtena starší verze balíčku MSTestV2. Metody čištění testů se nemusí spustit očekávaným způsobem. Ujistěte se prosím, že všechny vaše testovací projekty odkazují na balíčky MSTest novější než verze 2.2.8. - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} Došlo k výjimce při rozbalování řádků IDataSource z atributu na „{0}.{1}“: {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf index 5829dd95ff..ac1b95cffd 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf @@ -61,11 +61,6 @@ aber empfing {4} Argument(e) mit den Typen „{5}“. Es wurden sowohl die Dateien „.runsettings“ als auch „.testconfig.json“ erkannt. Wählen Sie nur eine dieser Testkonfigurationsdateien aus. - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - "[DynamicData]"-Element "{0}.{1}" muss "IEnumerable"<"object[]>", "IEnumerable<Tuple>" oder "IEnumerable<ValueTuple>" zurückgeben. - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Fehler: {1} Ausgelöste Ausnahmen: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - Fehler beim Abrufen des Attributcaches. Die Attributvererbung wird ignoriert und fällt in "type defines Attribute model", sodass einige Daten vorhanden sind. - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} Beim Abrufen von benutzerdefinierten Attributen für den Typ {0} wurde Ausnahme ausgelöst (wird ignoriert und die Reflektionsart verwendet): {1} @@ -471,11 +461,6 @@ Fehler: {1} Der aufgerufene Code hat eine Ausnahme ausgelöst, die abgefangen wurde, aber der Ausnahmewert war NULL. - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - Eine ältere Version des MSTestV2-Pakets wird in die Assembly geladen. Testbereinigungsmethoden werden möglicherweise nicht wie erwartet ausgeführt. Stellen Sie sicher, dass alle Testprojekte auf MSTest-Pakete verweisen, die neuer als Version 2.2.8 sind. - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} Ausnahme beim Erweitern von IDataSource-Zeilen aus dem Attribut auf "{0}.{1}": {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf index 915345816f..fb7c182bca 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf @@ -61,11 +61,6 @@ pero recibió {4} argumento(s), con los tipos "{5}". Se han detectado los archivos ".runsettings" y ".testconfig.json". Seleccione solo uno de estos archivos de configuración de prueba. - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - El miembro ''{0}.{1}'' de '[DynamicData]' al que se hace referencia debe devolver ''IEnumerable<object[]>', 'IEnumerable<Tuple>'' o ''IEnumerable<ValueTuple>'' - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Error: {1} Excepciones devueltas: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - No se pudo obtener la memoria caché de atributos. Se omitirá la herencia del atributo y se entrará en "type define Attribute model", de modo que tengamos algunos datos. - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} Al obtener atributos personalizados para el tipo {0} se produjo una excepción (se omitirá y se usará la forma de reflexión): {1} @@ -471,11 +461,6 @@ Error: {1} El código llamado produjo una excepción que se detectó, pero el valor de la excepción era null - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - Hay una versión anterior del paquete MSTestV2 cargada en el ensamblado. Es posible que los métodos de limpieza de pruebas no se ejecuten según lo esperado. Asegúrese de que todos los proyectos de prueba hacen referencia a paquetes MSTest más recientes que la versión 2.2.8. - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} Se produjo una excepción al expandir las filas de IDataSource del atributo en "{0}.{1}": {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf index 60bfc69ee9..e12d6a019a 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf @@ -61,11 +61,6 @@ mais a reçu {4} argument(s), avec les types « {5} ». Les fichiers « .runsettings » et « .testconfig.json » ont été détectés. Veuillez sélectionner un seul de ces fichiers de configuration de test. - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - Le membre référencé « [DynamicData] '{0}.{1}' doit renvoyer « IEnumerable<object[]> », « IEnumerable<Tuple> » ou « IEnumerable<ValueTuple> » - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Erreur : {1} Exceptions levées/s : This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - Échec de l’obtention du cache d’attributs. Héritage d’attribut ignoré et retour à 'type defines Attribute model' pour que nous ayons des données. - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} L’obtention d’attributs personnalisés pour le type {0} a levé une exception (ignorera et utilisera la méthode de réflexion) : {1} @@ -471,11 +461,6 @@ Erreur : {1} Le code appelé a levé une exception qui a été interceptée, mais la valeur de l’exception était nul - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - Une version antérieure du package MSTestV2 est chargée dans l’assembly. Les méthodes de nettoyage de test risquent de ne pas s’exécuter comme prévu. Vérifiez que tous vos projets de test référencent des packages MSTest plus récent que la version 2.2.8. - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} Une exception s’est produite lors du développement des lignes IDataSource à partir de l’attribut sur « {0}.{1} » : {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf index 74bb819f4e..5269afce00 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf @@ -61,11 +61,6 @@ ma ha ricevuto {4} argomenti, con tipi "{5}". Sono stati rilevati sia i file '.runsettings' sia '.testconfig.json'. Selezionare solo uno di questi file di configurazione di test. - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - '[DynamicData]' membro di riferimento '{0}.{1}' deve restituire 'IEnumerable<object[]>', 'IEnumerable<Tuple>' o 'IEnumerable<ValueTuple>' - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Errore: {1} Eccezioni generate: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - Non è stato possibile ottenere la cache degli attributi. L'ereditarietà dell'attributo verrà ignorata e verrà considerato 'il tipo definisce il modello di attributo', in modo che siano disponibili alcuni dati. - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} Il recupero degli attributi personalizzati per il tipo {0} ha generato un'eccezione (verrà ignorata e verrà usata la modalità reflection): {1} @@ -471,11 +461,6 @@ Errore: {1} Il codice chiamato ha generato un'eccezione che è stata rilevata, ma il valore dell'eccezione è Null - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - Nell'assembly è caricata una versione precedente del pacchetto MSTestV2. I metodi di pulizia dei test potrebbero non essere eseguiti come previsto. Assicurarsi che tutti i progetti di test facciano riferimento a pacchetti MSTest più recenti della versione 2.2.8. - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} Si è verificata un'eccezione durante l'espansione delle righe IDataSource dall'attributo in "{0}.{1}": {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf index 6b7c27488b..561c093562 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf @@ -62,11 +62,6 @@ but received {4} argument(s), with types '{5}'. '.runsettings' ファイルと '.testconfig.json' ファイルの両方が検出されました。これらのテスト構成ファイルのいずれか 1 つだけを選択してください。 - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - '[DynamicData]' の参照されるメンバー '{0}.{1}' は、'IEnumerable<object[]>'、'IEnumerable<Tuple>`、'IEnumerable<ValueTuple>' のいずれかを返す必要があります - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -451,11 +446,6 @@ Error: {1} スローされた例外: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - 属性キャッシュを取得できませんでした。属性の継承を無視すると、'type defines Attribute model' に分類されるため、いくつかのデータがあるようになります。 - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} 型 {0} のカスタム属性を取得中に例外がスローされました (無視してリフレクションの方法を使用します): {1} @@ -472,11 +462,6 @@ Error: {1} 呼び出されたコードはキャッチされた例外をスローしましたが、例外値が null でした - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - 古いバージョンの MSTestV2 パッケージがアセンブリに読み込まれています。テスト クリーンアップ メソッドが正しく実行されない可能性があります。すべてのテスト プロジェクトが、バージョン 2.2.8 より新しい MSTest パッケージを参照していることを確認してください。 - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} "{0}.{1}" の属性から IDataSource 行を展開中に例外が発生しました: {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf index ba9e50cf45..062afab0ae 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf @@ -61,11 +61,6 @@ but received {4} argument(s), with types '{5}'. '.runsettings' 및 '.testconfig.json' 파일이 모두 검색되었습니다. 이러한 테스트 구성 파일 중 하나만 선택하세요. - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - '[DynamicData]'이(가) '{0} 멤버를 참조했습니다.{1}'은(는) 'IEnumerable<object[]>', 'IEnumerable<Tuple>' 또는 'IEnumerable<ValueTuple>'을 반환해야 합니다. - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Error: {1} 예외 발생: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - 특성 캐시를 가져오지 못했습니다. 일부 데이터가 있도록 특성 상속을 무시하고 'type defines Attribute model'로 바꿉니다. - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} {0} 형식에 대한 사용자 지정 특성을 가져오는 데 예외가 발생했습니다(무시하고 리플렉션 방법 사용). {1} @@ -471,11 +461,6 @@ Error: {1} 호출된 코드에서 확인된 예외가 발생했지만 예외 값이 null입니다. - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - 이전 버전 MSTestV2 패키지가 어셈블리에 로드되어 테스트 정리 메서드가 예상대로 실행되지 않을 수 있습니다. 모든 테스트 프로젝트가 2.2.8 이후 버전 MSTest 패키지를 참조하는지 확인하세요. - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} "{0}.{1}"의 특성에서 IDataSource 행을 확장하는 동안 예외가 발생했습니다. {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf index 696cc2e048..f50f03f8ef 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf @@ -61,11 +61,6 @@ ale liczba odebranych argumentów to {4} z typami „{5}”. Wykryto zarówno pliki „.runsettings”, jak i „.testconfig.json”. Wybierz tylko jeden z tych plików konfiguracji testu. - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - Przywołany element członkowski „{0}.{1}” „[DynamicData]” powinien zwrócić „IEnumerable<object[]>”, „IEnumerable<Tuple>” lub „IEnumerable<ValueTuple>” - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Błąd: {1} Zgłoszone wyjątki: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - Nie można pobrać pamięci podręcznej atrybutów. Ignorowanie dziedziczenia atrybutów i wpadnięcie do elementu „typ definiuje model atrybutu”, dzięki czemu mamy pewne dane. - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} Pobieranie atrybutów niestandardowych dla typu {0} zgłosiło wyjątek (zignoruje i użyje sposobu odbicia): {1} @@ -471,11 +461,6 @@ Błąd: {1} Wywołany kod zgłosił wyjątek, który został przechwycony, ale wartość wyjątku miała wartość null - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - Starsza wersja pakietu MSTestV2 jest załadowana do zestawu. Metody czyszczenia testów mogą nie działać zgodnie z oczekiwaniami. Upewnij się, że wszystkie projekty testowe odwołują się do pakietów MSTest nowszych niż wersja 2.2.8. - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} Wystąpił wyjątek podczas rozwijania wierszy IDataSource z atrybutu w przestrzeni nazw „{0}.{1}”: {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf index 03c45b6449..51e1317f57 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf @@ -61,11 +61,6 @@ mas {4} argumentos recebidos, com tipos '{5}'. Ambos os arquivos '.runsettings' e '.testconfig.json' foram detectados. Selecione apenas um desses arquivos de configuração de teste. - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - O membro referenciado "{0}.{1}" de "[DynamicData]" deve retornar "IEnumerable<object[]>", "IEnumerable<Tuple>" ou "IEnumerable<ValueTuple>" - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Erro: {1} Exceções lançadas: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - Falha ao obter cache de atributos. Ignorando a herança de atributos e caindo em 'tipo define modelo de atributo', para que tenhamos alguns dados. - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} A obtenção de atributos personalizados para o tipo {0} gerou uma exceção (irá ignorar e usar o modo de reflexão): {1} @@ -471,11 +461,6 @@ Erro: {1} O código chamado lançou uma exceção que foi capturada, mas o valor da exceção era nulo - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - Uma versão mais antiga do pacote MSTestV2 é carregada no assembly, os métodos de limpeza de teste podem não ser executados conforme o esperado. Certifique-se de que todos os seus projetos de teste façam referência a pacotes MSTest mais recentes que a versão 2.2.8. - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} Ocorreu uma exceção ao expandir as linhas IDataSource do atributo em "{0}.{1}": {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf index 86afbe8fe8..a9c4bf409b 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf @@ -61,11 +61,6 @@ but received {4} argument(s), with types '{5}'. Обнаружены файлы ".runsettings" и ".testconfig.json". Выберите только один из этих файлов тестовой конфигурации. - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - Указанный элемент "[DynamicData]" "{0}.{1}" должен возвращать "IEnumerable<object[]>", "IEnumerable<Tuple>" или "IEnumerable<ValueTuple>" - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Error: {1} Выданные исключения: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - Не удалось получить кэш атрибутов. Наследование атрибутов игнорируется и выполняется переход к схеме "тип определяет модель атрибута", чтобы получить некоторые данные. - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} При получении настраиваемых атрибутов для типа {0} возникло исключение (оно будет проигнорировано и будет использовано отражение): {1} @@ -471,11 +461,6 @@ Error: {1} Вызванный код вызвал исключение, которое было перехвачено, но значение исключения было равно NULL - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - В сборку загружена старая версия пакета MSTestV2. Методы очистки тестов могут выполняться неправильно. Убедитесь, что все тестовые проекты ссылаются на пакеты MSTest с версией выше 2.2.8. - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} Возникло исключение при развертывании строк IDataSource из атрибута "{0}.{1}": {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf index 22a786a1bb..39bb0c917c 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf @@ -61,11 +61,6 @@ ancak, '{5}' türüyle {4} argüman aldı. Hem '.runsettings' hem de '.testconfig.json' dosyaları algılandı. Lütfen bu test yapılandırma dosyalarından yalnızca birini seçin. - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - '[DynamicData]' başvurulan üyesi '{0}.{1}' şu değerleri döndürmelidir: 'IEnumerable<object[]>', 'IEnumerable<Tuple>` veya 'IEnumerable<ValueTuple>' - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Hata: {1} Oluşturulan özel durumlar: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - Öznitelik önbelleği alınamadı. Öznitelik devralmayı yok saymak ve 'tür, Öznitelik modelini tanımlar' içine düşmek, böylece bazı verilerimiz olur. - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} {0} tipi için özel niteliklerin alınması özel durum oluşturdu (yok sayar ve yansıma yolunu kullanır): {1} @@ -471,11 +461,6 @@ Hata: {1} Çağrılan kod, yakalanan bir özel durum yarattı, ancak özel durum değeri boştu - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - Montaja MSTestV2 paketinin daha eski bir sürümü yüklendi, test temizleme yöntemleri beklendiği gibi çalışmayabilir. Lütfen tüm test projelerinizin 2.2.8 sürümünden daha yeni olan MSTest paketlerine başvurduğundan emin olun. - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} "{0}. {1}" üzerindeki öznitelikten IDataSource satırları genişletilirken özel durum oluştu: {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf index 47986a4c29..347c203c37 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf @@ -61,11 +61,6 @@ but received {4} argument(s), with types '{5}'. 检测到 ".runsettings" 和 ".testconfig.json" 文件。请仅选择其中一个测试配置文件。 - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - “[DynamicData]”引用的成员“{0}.{1}”应返回“IEnumerable<object[]>”、“IEnumerable<Tuple>”或“IEnumerable<ValueTuple>” - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Error: {1} 引发的异常: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - 无法获取属性缓存。忽略属性继承并进入“type 定义属性模型”,以便我们拥有一些数据。 - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} 获取类型 {0} 自定义属性引发异常(将忽略并使用反射方式): {1} @@ -471,11 +461,6 @@ Error: {1} 调用的代码引发了捕获的异常,但异常值为 null - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - 较旧版本的 MSTestV2 包已加载到程序集中,测试清理方法可能不会按预期运行。请确保所有测试项目都引用更高版本 2.2.8 的 MSTest 包。 - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} 从“{0}.{1}”上的属性扩展 IDataSource 行时出现异常: {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf index ae416802fd..cb94ea042b 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf @@ -61,11 +61,6 @@ but received {4} argument(s), with types '{5}'. 偵測到 '.runsettings' 和 '.testconfig.json' 檔案。請只選取其中一個測試設定檔。 - - '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - '[DynamicData]' 參考成員 '{0}.{1}' 應傳回 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. @@ -450,11 +445,6 @@ Error: {1} 擲回的例外狀況數: This is usually precedes by TestAssembly_AssemblyDiscoveryFailure message, and preceded by list of exceptions thrown in a test discovery session. - - Failed to get attribute cache. Ignoring attribute inheritance and falling into 'type defines Attribute model', so that we have some data. - 無法取得屬性快取。略過屬性繼承並落在 'type defines Attribute model' 中,因此我們有一些資料。 - - Getting custom attributes for type {0} threw exception (will ignore and use the reflection way): {1} 取得類型 {0} 擲回例外狀況的自訂屬性 (將會略過並使用反映方式): {1} @@ -471,11 +461,6 @@ Error: {1} 被呼叫的程式碼擲回攔截到的例外狀況,但例外狀況值為 Null - - An older version of MSTestV2 package is loaded in assembly, test cleanup methods might not run as expected. Please make sure all your test projects references MSTest packages newer then version 2.2.8. - 元件中已載入舊版的 MSTestV2 套件,測試清理方法可能無法如預期方式執行。請確定您的所有測試專案都參考了新版的 MSTest 套件 2.2.8 版。 - - Exception occurred while expanding IDataSource rows from attribute on "{0}.{1}": {2} 從「{0}.{1}」上的屬性展開 IDataSource 資料列時發生例外狀況: {2} From 68fd5bdfd7aa340378dfe40da69a5bec256c40ef Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 18 Dec 2024 12:41:48 +0100 Subject: [PATCH 136/273] Add DisplayMessage to TestContext (#4345) --- .../Execution/TestExecutionManager.cs | 16 ++++++++++- .../Execution/UnitTestRunner.cs | 5 ++-- .../IPlatformServiceProvider.cs | 3 +- .../PlatformServiceProvider.cs | 5 ++-- .../Interfaces/ITestContext.cs | 2 ++ .../PublicAPI/PublicAPI.Unshipped.txt | 2 ++ .../Services/MessageLevel.cs | 19 +++++++++++++ .../Services/TestContextImplementation.cs | 15 ++++++++++ .../TestFramework.Extensions/MessageLevel.cs | 25 +++++++++++++++++ .../PublicAPI/PublicAPI.Unshipped.txt | 5 ++++ .../TestFramework.Extensions/TestContext.cs | 2 ++ .../TestContextImplementationTests.cs | 19 +++++++++++++ .../Execution/UnitTestRunnerTests.cs | 28 +++++++++---------- .../PlatformServiceProviderTests.cs | 2 +- .../TestablePlatformServiceProvider.cs | 3 +- 15 files changed, 129 insertions(+), 22 deletions(-) create mode 100644 src/Adapter/MSTestAdapter.PlatformServices/Services/MessageLevel.cs create mode 100644 src/TestFramework/TestFramework.Extensions/MessageLevel.cs diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs index e05a6e1b02..6393868783 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs @@ -28,6 +28,17 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; #endif public class TestExecutionManager { + private sealed class RemotingMessageLogger : MarshalByRefObject, IMessageLogger + { + private readonly IMessageLogger _realMessageLogger; + + public RemotingMessageLogger(IMessageLogger messageLogger) + => _realMessageLogger = messageLogger; + + public void SendMessage(TestMessageLevel testMessageLevel, string message) + => _realMessageLogger.SendMessage(testMessageLevel, message); + } + /// /// Dictionary for test run parameters. /// @@ -451,7 +462,10 @@ private void ExecuteTestsWithTestRunner( // Run single test passing test context properties to it. IDictionary tcmProperties = TcmTestPropertiesProvider.GetTcmProperties(currentTest); Dictionary testContextProperties = GetTestContextProperties(tcmProperties, sourceLevelParameters); - UnitTestResult[] unitTestResult = testRunner.RunSingleTest(unitTestElement.TestMethod, testContextProperties); + + // testRunner could be in a different AppDomain. We cannot pass the testExecutionRecorder directly. + // Instead, we pass a proxy (remoting object) that is marshallable by ref. + UnitTestResult[] unitTestResult = testRunner.RunSingleTest(unitTestElement.TestMethod, testContextProperties, new RemotingMessageLogger(testExecutionRecorder)); PlatformServiceProvider.Instance.AdapterTraceLogger.LogInfo("Executed test {0}", unitTestElement.TestMethod.Name); diff --git a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs index 6d6e854add..8f706dd7a8 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs @@ -11,6 +11,7 @@ using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; using UnitTestOutcome = Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestOutcome; @@ -130,7 +131,7 @@ internal FixtureTestResult GetFixtureTestResult(TestMethod testMethod, string fi /// The test Method. /// The test context properties. /// The . - internal UnitTestResult[] RunSingleTest(TestMethod testMethod, IDictionary testContextProperties) + internal UnitTestResult[] RunSingleTest(TestMethod testMethod, IDictionary testContextProperties, IMessageLogger messageLogger) { Guard.NotNull(testMethod); @@ -138,7 +139,7 @@ internal UnitTestResult[] RunSingleTest(TestMethod testMethod, IDictionary(testContextProperties); - ITestContext testContext = PlatformServiceProvider.Instance.GetTestContext(testMethod, writer, properties); + ITestContext testContext = PlatformServiceProvider.Instance.GetTestContext(testMethod, writer, properties, messageLogger); testContext.SetOutcome(UTF.UnitTestOutcome.InProgress); // Get the testMethod diff --git a/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs b/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs index 8bf09bab56..db5390a5b9 100644 --- a/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs @@ -3,6 +3,7 @@ using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; @@ -121,5 +122,5 @@ ITestSourceHost CreateTestSourceHost( /// /// This was required for compatibility reasons since the TestContext object that the V1 adapter had for desktop is not .Net Core compliant. /// - ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties); + ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties, IMessageLogger messageLogger); } diff --git a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs index 94bcdc3e8d..38d8259a8e 100644 --- a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs @@ -9,6 +9,7 @@ using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; @@ -222,9 +223,9 @@ public ITestSourceHost CreateTestSourceHost( /// /// This was required for compatibility reasons since the TestContext object that the V1 adapter had for desktop is not .Net Core compliant. /// - public ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties) + public ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties, IMessageLogger messageLogger) { - var testContextImplementation = new TestContextImplementation(testMethod, writer, properties); + var testContextImplementation = new TestContextImplementation(testMethod, writer, properties, messageLogger); TestRunCancellationToken?.Register(CancelDelegate, testContextImplementation); return testContextImplementation; } diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestContext.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestContext.cs index ade967e97a..c57763b367 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestContext.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestContext.cs @@ -85,4 +85,6 @@ public interface ITestContext /// /// The display name. void SetDisplayName(string? displayName); + + void DisplayMessage(MessageLevel messageLevel, string message); } diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt index 7dc5c58110..6569d196f2 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt @@ -1 +1,3 @@ #nullable enable +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.DisplayMessage(Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel messageLevel, string! message) -> void +override Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.DisplayMessage(Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel messageLevel, string! message) -> void diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/MessageLevel.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/MessageLevel.cs new file mode 100644 index 0000000000..455c39aaf8 --- /dev/null +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/MessageLevel.cs @@ -0,0 +1,19 @@ +// 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.VisualStudio.TestPlatform.ObjectModel.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; + +internal static class MessageLevelExtensions +{ + public static TestMessageLevel ToTestMessageLevel(this MessageLevel messageLevel) + => messageLevel switch + { + MessageLevel.Informational => TestMessageLevel.Informational, + MessageLevel.Warning => TestMessageLevel.Warning, + MessageLevel.Error => TestMessageLevel.Error, + _ => throw new ArgumentOutOfRangeException(nameof(messageLevel)), + }; +} diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs index 5685895cd2..010994cdc4 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs @@ -9,6 +9,7 @@ using System.Globalization; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; using ITestMethod = Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel.ITestMethod; @@ -49,6 +50,7 @@ public class TestContextImplementation : TestContext, ITestContext /// Properties. /// private readonly Dictionary _properties; + private readonly IMessageLogger? _messageLogger; /// /// Specifies whether the writer is disposed or not. @@ -72,6 +74,17 @@ public class TestContextImplementation : TestContext, ITestContext private DataRow? _dataRow; #endif + /// + /// Initializes a new instance of the class. + /// + /// The test method. + /// The writer where diagnostic messages are written to. + /// Properties/configuration passed in. + /// The message logger to use. + internal TestContextImplementation(ITestMethod testMethod, StringWriter stringWriter, IDictionary properties, IMessageLogger messageLogger) + : this(testMethod, stringWriter, properties) + => _messageLogger = messageLogger; + /// /// Initializes a new instance of the class. /// @@ -357,5 +370,7 @@ public void ClearDiagnosticMessages() public void SetDisplayName(string? displayName) => TestDisplayName = displayName; + public override void DisplayMessage(MessageLevel messageLevel, string message) + => _messageLogger?.SendMessage(messageLevel.ToTestMessageLevel(), message); #endregion } diff --git a/src/TestFramework/TestFramework.Extensions/MessageLevel.cs b/src/TestFramework/TestFramework.Extensions/MessageLevel.cs new file mode 100644 index 0000000000..064b617131 --- /dev/null +++ b/src/TestFramework/TestFramework.Extensions/MessageLevel.cs @@ -0,0 +1,25 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestTools.UnitTesting; + +/// +/// Specifies the severity level of messages displayed using the API. +/// +public enum MessageLevel +{ + /// + /// The message will be displayed as informational, typically used for general updates or non-critical messages. + /// + Informational, + + /// + /// The message will be displayed as a warning, indicating a potential issue or something requiring attention. + /// + Warning, + + /// + /// The message will be displayed as an error, representing a significant issue or failure. + /// + Error, +} diff --git a/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt index 7dc5c58110..5b7e887699 100644 --- a/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework.Extensions/PublicAPI/PublicAPI.Unshipped.txt @@ -1 +1,6 @@ #nullable enable +abstract Microsoft.VisualStudio.TestTools.UnitTesting.TestContext.DisplayMessage(Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel messageLevel, string! message) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel +Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel.Error = 2 -> Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel +Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel.Informational = 0 -> Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel +Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel.Warning = 1 -> Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel diff --git a/src/TestFramework/TestFramework.Extensions/TestContext.cs b/src/TestFramework/TestFramework.Extensions/TestContext.cs index 83082db374..1d559cccd2 100644 --- a/src/TestFramework/TestFramework.Extensions/TestContext.cs +++ b/src/TestFramework/TestFramework.Extensions/TestContext.cs @@ -201,6 +201,8 @@ public abstract class TestContext /// the arguments. public abstract void WriteLine(string format, params object?[] args); + public abstract void DisplayMessage(MessageLevel messageLevel, string message); + private T? GetProperty(string name) where T : class { diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestContextImplementationTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestContextImplementationTests.cs index b2a1ec1e32..fdac028df8 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestContextImplementationTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestContextImplementationTests.cs @@ -7,6 +7,8 @@ #endif using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; +using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; @@ -389,4 +391,21 @@ public void GetResultFilesShouldReturnListOfAddedResultFiles() Verify(resultFiles.Contains("C:\\files\\myfile2.txt")); } #endif + + public void DisplayMessageShouldForwardToIMessageLogger() + { + var messageLoggerMock = new Mock(MockBehavior.Strict); + + messageLoggerMock + .Setup(l => l.SendMessage(It.IsAny(), It.IsAny())); + + _testContextImplementation = new TestContextImplementation(_testMethod.Object, new ThreadSafeStringWriter(null, "test"), _properties, messageLoggerMock.Object); + _testContextImplementation.DisplayMessage(MessageLevel.Informational, "InfoMessage"); + _testContextImplementation.DisplayMessage(MessageLevel.Warning, "WarningMessage"); + _testContextImplementation.DisplayMessage(MessageLevel.Error, "ErrorMessage"); + + messageLoggerMock.Verify(x => x.SendMessage(TestMessageLevel.Informational, "InfoMessage"), Times.Once); + messageLoggerMock.Verify(x => x.SendMessage(TestMessageLevel.Warning, "WarningMessage"), Times.Once); + messageLoggerMock.Verify(x => x.SendMessage(TestMessageLevel.Error, "ErrorMessage"), Times.Once); + } } diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestRunnerTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestRunnerTests.cs index 186ecb58de..d5d08b00ee 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestRunnerTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestRunnerTests.cs @@ -85,12 +85,12 @@ public void ConstructorShouldPopulateSettings() #region RunSingleTest tests public void RunSingleTestShouldThrowIfTestMethodIsNull() => - VerifyThrows(() => _unitTestRunner.RunSingleTest(null, null)); + VerifyThrows(() => _unitTestRunner.RunSingleTest(null, null, null)); public void RunSingleTestShouldThrowIfTestRunParametersIsNull() { var testMethod = new TestMethod("M", "C", "A", isAsync: false); - VerifyThrows(() => _unitTestRunner.RunSingleTest(testMethod, null)); + VerifyThrows(() => _unitTestRunner.RunSingleTest(testMethod, null, null)); } public void RunSingleTestShouldReturnTestResultIndicateATestNotFoundIfTestMethodCannotBeFound() @@ -100,7 +100,7 @@ public void RunSingleTestShouldReturnTestResultIndicateATestNotFoundIfTestMethod _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("A", It.IsAny())) .Returns(Assembly.GetExecutingAssembly()); - UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); Verify(results is not null); Verify(results.Length == 1); @@ -117,7 +117,7 @@ public void RunSingleTestShouldReturnTestResultIndicatingNotRunnableTestIfTestMe _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("A", It.IsAny())) .Returns(Assembly.GetExecutingAssembly()); - UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); string expectedMessage = string.Format( CultureInfo.InvariantCulture, @@ -140,7 +140,7 @@ public void ExecuteShouldSkipTestAndFillInClassIgnoreMessageIfIgnoreAttributeIsP _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("A", It.IsAny())) .Returns(Assembly.GetExecutingAssembly()); - UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); Verify(results is not null); Verify(results.Length == 1); @@ -157,7 +157,7 @@ public void ExecuteShouldSkipTestAndSkipFillingIgnoreMessageIfIgnoreAttributeIsP _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("A", It.IsAny())) .Returns(Assembly.GetExecutingAssembly()); - UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); Verify(results is not null); Verify(results.Length == 1); @@ -174,7 +174,7 @@ public void ExecuteShouldSkipTestAndFillInMethodIgnoreMessageIfIgnoreAttributeIs _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("A", It.IsAny())) .Returns(Assembly.GetExecutingAssembly()); - UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); Verify(results is not null); Verify(results.Length == 1); @@ -191,7 +191,7 @@ public void ExecuteShouldSkipTestAndSkipFillingIgnoreMessageIfIgnoreAttributeIsP _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("A", It.IsAny())) .Returns(Assembly.GetExecutingAssembly()); - UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); Verify(results is not null); Verify(results.Length == 1); @@ -208,7 +208,7 @@ public void ExecuteShouldSkipTestAndFillInClassIgnoreMessageIfIgnoreAttributeIsP _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("A", It.IsAny())) .Returns(Assembly.GetExecutingAssembly()); - UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); Verify(results is not null); Verify(results.Length == 1); @@ -225,7 +225,7 @@ public void ExecuteShouldSkipTestAndFillInMethodIgnoreMessageIfIgnoreAttributeIs _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("A", It.IsAny())) .Returns(Assembly.GetExecutingAssembly()); - UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); Verify(results is not null); Verify(results.Length == 1); @@ -241,7 +241,7 @@ public void RunSingleTestShouldReturnTestResultIndicatingFailureIfThereIsAnyType _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("A", It.IsAny())) .Returns(Assembly.GetExecutingAssembly()); - UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); string expectedMessage = string.Format( CultureInfo.InvariantCulture, @@ -264,7 +264,7 @@ public void RunSingleTestShouldReturnTestResultsForAPassingTestMethod() _testablePlatformServiceProvider.MockFileOperations.Setup(fo => fo.LoadAssembly("A", It.IsAny())) .Returns(Assembly.GetExecutingAssembly()); - UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); Verify(results is not null); Verify(results.Length == 1); @@ -282,7 +282,7 @@ public void RunSingleTestShouldSetTestsAsInProgressInTestContext() .Returns(Assembly.GetExecutingAssembly()); // Asserting in the test method execution flow itself. - UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + UnitTestResult[] results = _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); Verify(results is not null); Verify(results.Length == 1); @@ -308,7 +308,7 @@ public void RunSingleTestShouldCallAssemblyInitializeAndClassInitializeMethodsIn DummyTestClassWithInitializeMethods.AssemblyInitializeMethodBody = () => validator <<= 2; DummyTestClassWithInitializeMethods.ClassInitializeMethodBody = () => validator >>= 2; - _unitTestRunner.RunSingleTest(testMethod, _testRunParameters); + _unitTestRunner.RunSingleTest(testMethod, _testRunParameters, null); Verify(validator == 1); } diff --git a/test/UnitTests/MSTestAdapter.UnitTests/PlatformServiceProviderTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/PlatformServiceProviderTests.cs index 4aa2b30fce..7109a8a7bf 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/PlatformServiceProviderTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/PlatformServiceProviderTests.cs @@ -64,7 +64,7 @@ public void GetTestContextShouldReturnAValidTestContext() testMethod.Setup(tm => tm.Name).Returns("M"); // Act. - PlatformServices.Interface.ITestContext testContext = PlatformServiceProvider.Instance.GetTestContext(testMethod.Object, writer, properties); + PlatformServices.Interface.ITestContext testContext = PlatformServiceProvider.Instance.GetTestContext(testMethod.Object, writer, properties, null); // Assert. Verify(testContext.Context.FullyQualifiedTestClassName == "A.C.M"); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs b/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs index afec0277f4..96627190a9 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs @@ -7,6 +7,7 @@ using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Moq; @@ -125,7 +126,7 @@ public IReflectionOperations2 ReflectionOperations public TestRunCancellationToken TestRunCancellationToken { get; set; } - public ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties) => new TestContextImplementation(testMethod, writer, properties); + public ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties, IMessageLogger messageLogger) => new TestContextImplementation(testMethod, writer, properties, messageLogger); public ITestSourceHost CreateTestSourceHost(string source, TestPlatform.ObjectModel.Adapter.IRunSettings runSettings, TestPlatform.ObjectModel.Adapter.IFrameworkHandle frameworkHandle) => MockTestSourceHost.Object; From 2dd2f37ce139bf2c5149fdbaf0ad128c6a5b714c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 18 Dec 2024 12:42:08 +0100 Subject: [PATCH 137/273] Improve some flaky tests (#4381) --- .../RunsettingsTests.cs | 8 +------- .../RetryFailedTestsTests.cs | 14 ++++++++++++-- .../Logging/FileLoggerTests.cs | 9 +++++++-- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs index 9bdbb88338..09bcd2b58a 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Globalization; -using System.Runtime.InteropServices; using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; @@ -38,11 +37,6 @@ public sealed class RunSettingsTests : AcceptanceTestBase await RetryHelper.RetryAsync( + { + // TODO: Crash dump is not working properly on macos, so we skip the test for now + if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + return; + } + + await RetryHelper.RetryAsync( async () => { var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, AssetName, tfm); @@ -171,6 +180,7 @@ public async Task RetryFailedTests_MoveFiles_Succeeds(string tfm) Assert.Fail($"Expected 1 or 2 dump files, but found {dumpFilesCount}"); } }, 3, TimeSpan.FromSeconds(5)); + } public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs index e5d53c93e6..2b88b549d2 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs @@ -176,12 +176,17 @@ public async Task Log_WhenSyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsIt if (LogTestHelpers.IsLogEnabled(defaultLogLevel, currentLogLevel)) { - if (_memoryStream.Length == 0) + await _memoryStream.FlushAsync(); + int iteration = 0; + while (_memoryStream.Length == 0 && iteration < 10) { - await Task.Delay(1000); + iteration++; + await Task.Delay(200); } await _memoryStream.FlushAsync(); + + _mockConsole.Verify(x => x.WriteLine(It.IsAny()), Times.Never); Assert.AreEqual($"[00:00:00.000 Test - {currentLogLevel}] Message{Environment.NewLine}", Encoding.Default.GetString(_memoryStream.ToArray())); } else From 352bd40257de3036ac55c41918484afd4ec41c53 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 18 Dec 2024 03:53:20 -0800 Subject: [PATCH 138/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2604024 --- .../MSTest.Analyzers/xlf/Resources.fr.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.ja.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.ru.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.tr.xlf | 17 +++++++++-------- .../MSTest.Analyzers/xlf/Resources.zh-Hans.xlf | 16 ++++++++-------- 6 files changed, 49 insertions(+), 48 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index f55a879b13..bf8ddfce3b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -644,14 +644,14 @@ Le type doit être une classe - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + Les méthodes de test, c’est-à-dire les méthodes marquées de l’attribut « [TestMethod] », doivent respecter la disposition suivante pour être considérées comme valides par MSTest : +– elle doit être « publique » (ou « interne » si l’attribut « [assembly : DiscoverInternals] » est défini) +– elle ne doit pas être « statique » +– elle peut être générique tant que les paramètres de type peuvent être déduits et que les types d’arguments sont compatibles +– il ne doit pas être « abstract » +– le type de retour doit être « void », « Task » ou « ValueTask » +– elle ne doit pas être « async void » +– elle ne doit pas être une méthode spéciale (finaliseur, opérateur...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index d0527a3d77..584950f364 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -644,14 +644,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + '[TestMethod]' 属性でマークされたテスト メソッドは、MSTest によって有効と見なされるように、次のレイアウトを考慮する必要があります: +- 'public' である必要があります ('[assembly: DiscoverInternals]' 属性が設定されている場合は 'internal' である必要があります) +- 'static' にすることはできません +- 型パラメーターを推論でき、引数の型が互換性がある限り、ジェネリックである必要があります +- 'abstract' にすることはできません +- 戻り値の型は 'void'、'Task'、または 'ValueTask' である必要があります +- 'async void' にすることはできません +- 特殊なメソッド (ファイナライザー、演算子...) にすることはできません。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 44803079cb..a8bb4a42b4 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -644,14 +644,14 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + Os métodos de teste, métodos marcados com o atributo '[TestMethod]', devem respeitar o seguinte layout para que sejam considerados válidos pelo MSTest: +- deve ser "público" (ou "interno" se o atributo "[assembly: DiscoverInternals]" estiver definido) +- não pode ser ''estático'' +- ele deve ser genérico, desde que os parâmetros de tipo possam ser inferidos e os tipos de argumentos sejam compatíveis +- não pode ser ''abstrato'' +- o tipo de retorno deve ser 'nulo', 'Tarefa' ou 'ValueTask' +- não pode ser ''nulo assíncrono'' +— não deve ser um método especial (finalizador, operador...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index d2f619f344..0413a925b7 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -654,14 +654,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + Методы теста (методы, помеченные атрибутом "[TestMethod]") должны соблюдать следующую структуру, чтобы считаться допустимыми в MSTest: +– должно быть присвоено значение "public" (или "internal", если задан атрибут "[assembly: DiscoverInternals]") +– не следует присваивать значение "static" +– могут быть универсальными, если можно вывести параметры типа, а типы аргументов являются совместимыми +– не следует присваивать значение "abstract" +– возвращаемый тип должен быть "void", "Task" или "ValueTask" +– не следует присваивать значение "async void" +– это должен быть специальный метод (метод завершения, оператор...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index db0be22ae7..eb8dbfb988 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -645,14 +645,15 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + '[TestMethod]' özniteliğiyle işaretlenen test yöntemleri, MSTest: + tarafından geçerli kabul edilebilmesi için aşağıdaki düzene uygun olacak şekilde düzenlenmelidir +- 'public' (veya '[assembly: DiscoverInternals]' özniteliği ayarlanmışsa 'internal') olmalıdır +- 'static' olmamalıdır +- Tür parametreleri çıkarsandıkça ve bağımsız değişken türleri uyumlu olduğu sürece genel olmalıdır +- 'abstract' olmamalıdır +- dönüş türü 'void', 'Task' veya 'ValueTask' olmalıdır +- 'async void' olmamalıdır +- özel bir yöntem (sonlandırıcı, işleç...) olmamalıdır. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 9fb03859ef..960cd5eb87 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -644,14 +644,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + 测试方法(标记有 "[TestMethod]" 属性的方法)应遵循以下布局,以便 MSTest 将其视为有效: +- 它应该是 "public" (如果设置了 "[assembly: DiscoverInternals]" 属性,则应该是 "internal") +- 它不应为 "static" +- 只要可以推断类型参数并且参数类型兼容,它就应该是泛型 +- 它不应为 "abstract" +- 返回类型应为 "void”、"Task" 或 "ValueTask" +- 它不应为 "async void" +- 它不应是特殊方法(终结器、运算符...)。 From 6cbfc9f31c8b5fb16405d3db32ceef2f571b3f23 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 18 Dec 2024 03:58:10 -0800 Subject: [PATCH 139/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2604027 --- .../MSTest.Analyzers/xlf/Resources.fr.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.ja.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.ru.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.tr.xlf | 17 +++++++++-------- .../MSTest.Analyzers/xlf/Resources.zh-Hans.xlf | 16 ++++++++-------- 6 files changed, 49 insertions(+), 48 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index f55a879b13..bf8ddfce3b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -644,14 +644,14 @@ Le type doit être une classe - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + Les méthodes de test, c’est-à-dire les méthodes marquées de l’attribut « [TestMethod] », doivent respecter la disposition suivante pour être considérées comme valides par MSTest : +– elle doit être « publique » (ou « interne » si l’attribut « [assembly : DiscoverInternals] » est défini) +– elle ne doit pas être « statique » +– elle peut être générique tant que les paramètres de type peuvent être déduits et que les types d’arguments sont compatibles +– il ne doit pas être « abstract » +– le type de retour doit être « void », « Task » ou « ValueTask » +– elle ne doit pas être « async void » +– elle ne doit pas être une méthode spéciale (finaliseur, opérateur...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index d0527a3d77..584950f364 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -644,14 +644,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + '[TestMethod]' 属性でマークされたテスト メソッドは、MSTest によって有効と見なされるように、次のレイアウトを考慮する必要があります: +- 'public' である必要があります ('[assembly: DiscoverInternals]' 属性が設定されている場合は 'internal' である必要があります) +- 'static' にすることはできません +- 型パラメーターを推論でき、引数の型が互換性がある限り、ジェネリックである必要があります +- 'abstract' にすることはできません +- 戻り値の型は 'void'、'Task'、または 'ValueTask' である必要があります +- 'async void' にすることはできません +- 特殊なメソッド (ファイナライザー、演算子...) にすることはできません。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 44803079cb..a8bb4a42b4 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -644,14 +644,14 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + Os métodos de teste, métodos marcados com o atributo '[TestMethod]', devem respeitar o seguinte layout para que sejam considerados válidos pelo MSTest: +- deve ser "público" (ou "interno" se o atributo "[assembly: DiscoverInternals]" estiver definido) +- não pode ser ''estático'' +- ele deve ser genérico, desde que os parâmetros de tipo possam ser inferidos e os tipos de argumentos sejam compatíveis +- não pode ser ''abstrato'' +- o tipo de retorno deve ser 'nulo', 'Tarefa' ou 'ValueTask' +- não pode ser ''nulo assíncrono'' +— não deve ser um método especial (finalizador, operador...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index d2f619f344..0413a925b7 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -654,14 +654,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + Методы теста (методы, помеченные атрибутом "[TestMethod]") должны соблюдать следующую структуру, чтобы считаться допустимыми в MSTest: +– должно быть присвоено значение "public" (или "internal", если задан атрибут "[assembly: DiscoverInternals]") +– не следует присваивать значение "static" +– могут быть универсальными, если можно вывести параметры типа, а типы аргументов являются совместимыми +– не следует присваивать значение "abstract" +– возвращаемый тип должен быть "void", "Task" или "ValueTask" +– не следует присваивать значение "async void" +– это должен быть специальный метод (метод завершения, оператор...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index db0be22ae7..eb8dbfb988 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -645,14 +645,15 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + '[TestMethod]' özniteliğiyle işaretlenen test yöntemleri, MSTest: + tarafından geçerli kabul edilebilmesi için aşağıdaki düzene uygun olacak şekilde düzenlenmelidir +- 'public' (veya '[assembly: DiscoverInternals]' özniteliği ayarlanmışsa 'internal') olmalıdır +- 'static' olmamalıdır +- Tür parametreleri çıkarsandıkça ve bağımsız değişken türleri uyumlu olduğu sürece genel olmalıdır +- 'abstract' olmamalıdır +- dönüş türü 'void', 'Task' veya 'ValueTask' olmalıdır +- 'async void' olmamalıdır +- özel bir yöntem (sonlandırıcı, işleç...) olmamalıdır. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 9fb03859ef..960cd5eb87 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -644,14 +644,14 @@ The type declaring these methods should also respect the following rules: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + 测试方法(标记有 "[TestMethod]" 属性的方法)应遵循以下布局,以便 MSTest 将其视为有效: +- 它应该是 "public" (如果设置了 "[assembly: DiscoverInternals]" 属性,则应该是 "internal") +- 它不应为 "static" +- 只要可以推断类型参数并且参数类型兼容,它就应该是泛型 +- 它不应为 "abstract" +- 返回类型应为 "void”、"Task" 或 "ValueTask" +- 它不应为 "async void" +- 它不应是特殊方法(终结器、运算符...)。 From b9c836305b18a9030d972d60cf58f744a8ad37ec Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 18 Dec 2024 13:52:56 +0100 Subject: [PATCH 140/273] Report diagnostic if DynamicData is referencing a member that's not method/property (e.g, field) (and some cleanup) (#4383) --- .../DynamicDataShouldBeValidAnalyzer.cs | 70 +++++++++++-------- .../MSTest.Analyzers/Resources.Designer.cs | 13 +++- src/Analyzers/MSTest.Analyzers/Resources.resx | 7 +- .../MSTest.Analyzers/xlf/Resources.cs.xlf | 13 ++-- .../MSTest.Analyzers/xlf/Resources.de.xlf | 13 ++-- .../MSTest.Analyzers/xlf/Resources.es.xlf | 13 ++-- .../MSTest.Analyzers/xlf/Resources.fr.xlf | 13 ++-- .../MSTest.Analyzers/xlf/Resources.it.xlf | 13 ++-- .../MSTest.Analyzers/xlf/Resources.ja.xlf | 13 ++-- .../MSTest.Analyzers/xlf/Resources.ko.xlf | 13 ++-- .../MSTest.Analyzers/xlf/Resources.pl.xlf | 13 ++-- .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 13 ++-- .../MSTest.Analyzers/xlf/Resources.ru.xlf | 13 ++-- .../MSTest.Analyzers/xlf/Resources.tr.xlf | 13 ++-- .../xlf/Resources.zh-Hans.xlf | 13 ++-- .../xlf/Resources.zh-Hant.xlf | 13 ++-- .../DynamicDataShouldBeValidAnalyzerTests.cs | 59 +++++++++++++--- 17 files changed, 224 insertions(+), 94 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs index d21e8335d2..4c400817e6 100644 --- a/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs @@ -47,6 +47,9 @@ public sealed class DynamicDataShouldBeValidAnalyzer : DiagnosticAnalyzer internal static readonly DiagnosticDescriptor SourceTypeMethodRule = NotTestMethodRule .WithMessage(new(nameof(Resources.DynamicDataShouldBeValidMessageFormat_SourceTypeMethod), Resources.ResourceManager, typeof(Resources))); + internal static readonly DiagnosticDescriptor SourceTypeNotPropertyOrMethodRule = NotTestMethodRule + .WithMessage(new(nameof(Resources.DynamicDataShouldBeValidMessageFormat_SourceTypeNotPropertyOrMethod), Resources.ResourceManager, typeof(Resources))); + internal static readonly DiagnosticDescriptor MemberMethodRule = NotTestMethodRule .WithMessage(new(nameof(Resources.DynamicDataShouldBeValidMessageFormat_MemberMethod), Resources.ResourceManager, typeof(Resources))); @@ -59,8 +62,17 @@ public sealed class DynamicDataShouldBeValidAnalyzer : DiagnosticAnalyzer internal static readonly DiagnosticDescriptor DisplayMethodSignatureRule = NotTestMethodRule .WithMessage(new(nameof(Resources.DynamicDataShouldBeValidMessageFormat_DisplayMethodSignature), Resources.ResourceManager, typeof(Resources))); - public override ImmutableArray SupportedDiagnostics { get; } - = ImmutableArray.Create(NotTestMethodRule); + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create( + NotTestMethodRule, + MemberNotFoundRule, + FoundTooManyMembersRule, + SourceTypePropertyRule, + SourceTypeMethodRule, + SourceTypeNotPropertyOrMethodRule, + MemberMethodRule, + MemberTypeRule, + DataMemberSignatureRule, + DisplayMethodSignatureRule); public override void Initialize(AnalysisContext context) { @@ -91,7 +103,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo var methodSymbol = (IMethodSymbol)context.Symbol; bool isTestMethod = false; - List dynamicDataAttributes = new(); + bool hasDynamicDataAttribute = false; foreach (AttributeData methodAttribute in methodSymbol.GetAttributes()) { // Current method should be a test method or should inherit from the TestMethod attribute. @@ -103,26 +115,15 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo if (SymbolEqualityComparer.Default.Equals(methodAttribute.AttributeClass, dynamicDataAttributeSymbol)) { - dynamicDataAttributes.Add(methodAttribute); + hasDynamicDataAttribute = true; + AnalyzeAttribute(context, methodAttribute, methodSymbol, dynamicDataSourceTypeSymbol, ienumerableTypeSymbol, itupleTypeSymbol, methodInfoTypeSymbol); } } // Check if attribute is set on a test method. - if (!isTestMethod) - { - if (dynamicDataAttributes.Count > 0) - { - context.ReportDiagnostic(methodSymbol.CreateDiagnostic(NotTestMethodRule)); - } - - return; - } - - // Check each data row attribute. - foreach (AttributeData attribute in dynamicDataAttributes) + if (!isTestMethod && hasDynamicDataAttribute) { - AnalyzeAttribute(context, attribute, methodSymbol, dynamicDataSourceTypeSymbol, ienumerableTypeSymbol, itupleTypeSymbol, - methodInfoTypeSymbol); + context.ReportDiagnostic(methodSymbol.CreateDiagnostic(NotTestMethodRule)); } } @@ -192,18 +193,29 @@ private static void AnalyzeDataSource(SymbolAnalysisContext context, AttributeDa ISymbol member = potentialMembers[0]; - // If the member is a property and the data source type is not set to property, report a diagnostic. - if (member.Kind == SymbolKind.Property && dataSourceType is not (DynamicDataSourceTypeProperty or DynamicDataSourceTypeAutoDetect)) + switch (member.Kind) { - context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(SourceTypePropertyRule, declaringType.Name, memberName)); - return; - } - - // If the member is a method and the data source type is not set to method, report a diagnostic. - if (member.Kind == SymbolKind.Method && dataSourceType is not (DynamicDataSourceTypeMethod or DynamicDataSourceTypeAutoDetect)) - { - context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(SourceTypeMethodRule, declaringType.Name, memberName)); - return; + case SymbolKind.Property: + // If the member is a property and the data source type is not set to property or auto detect, report a diagnostic. + if (dataSourceType is not (DynamicDataSourceTypeProperty or DynamicDataSourceTypeAutoDetect)) + { + context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(SourceTypePropertyRule, declaringType.Name, memberName)); + return; + } + + break; + case SymbolKind.Method: + // If the member is a method and the data source type is not set to method or auto detect, report a diagnostic. + if (dataSourceType is not (DynamicDataSourceTypeMethod or DynamicDataSourceTypeAutoDetect)) + { + context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(SourceTypeMethodRule, declaringType.Name, memberName)); + return; + } + + break; + default: + context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(SourceTypeNotPropertyOrMethodRule, declaringType.Name, memberName)); + return; } if (!member.IsStatic) diff --git a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs index c79c68d575..ff6155302f 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs @@ -504,7 +504,7 @@ internal static string DynamicDataShouldBeValidMessageFormat_OnTestMethod { } /// - /// Looks up a localized string similar to '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method'. + /// Looks up a localized string similar to '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended). /// internal static string DynamicDataShouldBeValidMessageFormat_SourceTypeMethod { get { @@ -513,7 +513,16 @@ internal static string DynamicDataShouldBeValidMessageFormat_SourceTypeMethod { } /// - /// Looks up a localized string similar to '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property'. + /// Looks up a localized string similar to '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported.. + /// + internal static string DynamicDataShouldBeValidMessageFormat_SourceTypeNotPropertyOrMethod { + get { + return ResourceManager.GetString("DynamicDataShouldBeValidMessageFormat_SourceTypeNotPropertyOrMethod", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended). /// internal static string DynamicDataShouldBeValidMessageFormat_SourceTypeProperty { get { diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx index ca9399fdab..41cf404fa7 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.resx +++ b/src/Analyzers/MSTest.Analyzers/Resources.resx @@ -493,7 +493,7 @@ The type declaring these methods should also respect the following rules: '[DynamicDta]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) '[DynamicData]' member '{0}.{1}' should be a method @@ -502,7 +502,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' referenced member '{0}.{1}' should return 'IEnumerable<object[]>', 'IEnumerable<Tuple>` or 'IEnumerable<ValueTuple>' - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) '[DynamicData]' display name method '{0}.{1}' signature is invalid @@ -540,4 +540,7 @@ The type declaring these methods should also respect the following rules: Found two conflicting types for generic parameter '{0}'. The conflicting types are '{1}' and '{2}'. + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index b9e084dc25..9034506a08 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -363,13 +363,18 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - Člen [DynamicData] {0}.{1} je metoda, takže byste měli nastavit DynamicDataSourceType.Method. + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + Člen [DynamicData] {0}.{1} je metoda, takže byste měli nastavit DynamicDataSourceType.Method. + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - Člen [DynamicData] {0}.{1} je vlastnost, takže byste měli nastavit DynamicDataSourceType.Property. + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + Člen [DynamicData] {0}.{1} je vlastnost, takže byste měli nastavit DynamicDataSourceType.Property. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 0a813b0b72..f620681c5a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -365,13 +365,18 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - "[DynamicData]"-Element "{0}.{1}" ist eine Methode, daher sollten Sie "DynamicDataSourceType.Method" festlegen. + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + "[DynamicData]"-Element "{0}.{1}" ist eine Methode, daher sollten Sie "DynamicDataSourceType.Method" festlegen. + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - "[DynamicData]"-Element "{0}.{1}" ist eine Eigenschaft, daher sollten Sie "DynamicDataSourceType.Property" festlegen. + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + "[DynamicData]"-Element "{0}.{1}" ist eine Eigenschaft, daher sollten Sie "DynamicDataSourceType.Property" festlegen. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 9ce8af5290..58bc1a1c76 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -363,13 +363,18 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - El miembro de '{0}.{1}' de '[DynamicData]' es un método, por lo que debe establecert 'DynamicDataSourceType.Method' + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + El miembro de '{0}.{1}' de '[DynamicData]' es un método, por lo que debe establecert 'DynamicDataSourceType.Method' + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - El miembro de '{0}.{1}' de '[DynamicData]' es una propiedad, por lo que debe establecer 'DynamicDataSourceType.Property' + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + El miembro de '{0}.{1}' de '[DynamicData]' es una propiedad, por lo que debe establecer 'DynamicDataSourceType.Property' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index bf8ddfce3b..9659b2b9a3 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -363,13 +363,18 @@ Le type doit être une classe - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - Membre '[DynamicData]' '{0}.{1}' est une méthode, vous devez donc définir 'DynamicDataSourceType.Method' + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + Membre '[DynamicData]' '{0}.{1}' est une méthode, vous devez donc définir 'DynamicDataSourceType.Method' + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - Membre '[DynamicData]' '{0}.{1}' est une propriété, vous devez donc définir 'DynamicDataSourceType.Property' + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + Membre '[DynamicData]' '{0}.{1}' est une propriété, vous devez donc définir 'DynamicDataSourceType.Property' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index 10154aa439..73fd28a209 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -363,13 +363,18 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - Il membro '[DynamicData]' '{0}.{1}' è un metodo, quindi impostare 'DynamicDataSourceType.Method' + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + Il membro '[DynamicData]' '{0}.{1}' è un metodo, quindi impostare 'DynamicDataSourceType.Method' + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - Il membro '[DynamicData]' '{0}.{1}' è una proprietà, quindi impostare 'DynamicDataSourceType.Property' + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + Il membro '[DynamicData]' '{0}.{1}' è una proprietà, quindi impostare 'DynamicDataSourceType.Property' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 584950f364..147e6f5f26 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -363,13 +363,18 @@ The type declaring these methods should also respect the following rules: - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - '[DynamicData]' メンバー '{0}.{1}' はメソッドであるため、'DynamicDataSourceType.Method' を設定する必要があります + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' メンバー '{0}.{1}' はメソッドであるため、'DynamicDataSourceType.Method' を設定する必要があります + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - '[DynamicData]' メンバー '{0}.{1}' はプロパティであるため、'DynamicDataSourceType.Property' を設定する必要があります + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' メンバー '{0}.{1}' はプロパティであるため、'DynamicDataSourceType.Property' を設定する必要があります diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index d164b31731..54f68d8f04 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -363,13 +363,18 @@ The type declaring these methods should also respect the following rules: - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - '[DynamicData]' 멤버 '{0}.{1}'은(는) 메서드이므로 'DynamicDataSourceType.Method'를 설정해야 합니다. + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' 멤버 '{0}.{1}'은(는) 메서드이므로 'DynamicDataSourceType.Method'를 설정해야 합니다. + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - '[DynamicData]' 멤버 '{0}.{1}'은(는) 속성이므로 'DynamicDataSourceType.Property'를 설정해야 합니다. + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' 멤버 '{0}.{1}'은(는) 속성이므로 'DynamicDataSourceType.Property'를 설정해야 합니다. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index be6c03b429..aa965e181f 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -363,13 +363,18 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - Element członkowski „{0}.{1}” „[DynamicData]” jest metodą, dlatego należy ustawić „DynamicDataSourceType.Method” + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + Element członkowski „{0}.{1}” „[DynamicData]” jest metodą, dlatego należy ustawić „DynamicDataSourceType.Method” + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - Element członkowski „{0}.{1}” „[DynamicData]” jest właściwością, dlatego należy ustawić „DynamicDataSourceType.Property” + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + Element członkowski „{0}.{1}” „[DynamicData]” jest właściwością, dlatego należy ustawić „DynamicDataSourceType.Property” diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index a8bb4a42b4..5b0259459d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -363,13 +363,18 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - O membro "{0}.{1}" de "[DynamicData]" é um método; portanto, você deve definir "DynamicDataSourceType.Method" + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + O membro "{0}.{1}" de "[DynamicData]" é um método; portanto, você deve definir "DynamicDataSourceType.Method" + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - O membro "{0}.{1}" de "[DynamicData]" é uma propriedade; portanto, você deve definir "DynamicDataSourceType.Property" + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + O membro "{0}.{1}" de "[DynamicData]" é uma propriedade; portanto, você deve definir "DynamicDataSourceType.Property" diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index 0413a925b7..ce81847425 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -367,13 +367,18 @@ The type declaring these methods should also respect the following rules: - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - Элемент "[DynamicData]" "{0}.{1}" является методом, поэтому следует задать "DynamicDataSourceType.Method" + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + Элемент "[DynamicData]" "{0}.{1}" является методом, поэтому следует задать "DynamicDataSourceType.Method" + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - Элемент "[DynamicData]" "{0}.{1}" является свойством, поэтому следует задать "DynamicDataSourceType.Property" + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + Элемент "[DynamicData]" "{0}.{1}" является свойством, поэтому следует задать "DynamicDataSourceType.Property" diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index eb8dbfb988..a0dfd107c7 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -363,13 +363,18 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - '[DynamicData]' üyesi '{0}.{1}' bir yöntem olduğundan 'DynamicDataSourceType.Method' öğesini ayarlamalısınız + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' üyesi '{0}.{1}' bir yöntem olduğundan 'DynamicDataSourceType.Method' öğesini ayarlamalısınız + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - '[DynamicData]' üyesi '{0}.{1}' bir özellik olduğundan 'DynamicDataSourceType.Property' öğesini ayarlamalısınız + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' üyesi '{0}.{1}' bir özellik olduğundan 'DynamicDataSourceType.Property' öğesini ayarlamalısınız diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 960cd5eb87..8bf35ffe8a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -363,13 +363,18 @@ The type declaring these methods should also respect the following rules: - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - "[DynamicData]" 成员 "{0}.{1}" 是一个方法,因此应设置 "DynamicDataSourceType.Method" + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + "[DynamicData]" 成员 "{0}.{1}" 是一个方法,因此应设置 "DynamicDataSourceType.Method" + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - "[DynamicData]" 成员 "{0}.{1}" 是一个属性,因此应设置 "DynamicDataSourceType.Property" + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + "[DynamicData]" 成员 "{0}.{1}" 是一个属性,因此应设置 "DynamicDataSourceType.Property" diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 4f38c142a7..65013f9dc0 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -363,13 +363,18 @@ The type declaring these methods should also respect the following rules: - '[DynamicData]' member '{0}.{1}' is a method so you should set 'DynamicDataSourceType.Method' - '[DynamicData]' 成員 '{0}.{1}' 是方法,因此您應該設定 'DynamicDataSourceType.Method' + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' 成員 '{0}.{1}' 是方法,因此您應該設定 'DynamicDataSourceType.Method' + + + + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is a property so you should set 'DynamicDataSourceType.Property' - '[DynamicData]' 成員 '{0}.{1}' 是屬性,因此您應該設定 'DynamicDataSourceType.Property' + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' 成員 '{0}.{1}' 是屬性,因此您應該設定 'DynamicDataSourceType.Property' diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs index baf83013c6..79d5212059 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs @@ -423,22 +423,22 @@ public async Task WhenAppliedToNonTestMethod_Diagnostic() [TestClass] public class MyTestClass { - [DynamicData("SomeProperty")] + [{|#4:DynamicData("SomeProperty")|}] public void {|#0:TestMethod1|}(object[] o) { } - [DynamicData("SomeProperty", typeof(SomeClass))] + [{|#5:DynamicData("SomeProperty", typeof(SomeClass))|}] public void {|#1:TestMethod2|}(object[] o) { } - [DynamicData(dynamicDataSourceName: "SomeProperty")] + [{|#6:DynamicData(dynamicDataSourceName: "SomeProperty")|}] public void {|#2:TestMethod3|}(object[] o) { } - [DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "SomeProperty")] + [{|#7:DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "SomeProperty")|}] public void {|#3:TestMethod4|}(object[] o) { } @@ -451,10 +451,22 @@ public class SomeClass await VerifyCS.VerifyAnalyzerAsync( code, - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.NotTestMethodRule).WithLocation(0), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.NotTestMethodRule).WithLocation(1), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.NotTestMethodRule).WithLocation(2), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.NotTestMethodRule).WithLocation(3)); + // /0/Test0.cs(6,6): warning MSTEST0018: '[DynamicData]' member 'MyTestClass.SomeProperty' cannot be found + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberNotFoundRule).WithSpan(6, 6, 6, 33).WithArguments("MyTestClass", "SomeProperty"), + // /0/Test0.cs(7,17): warning MSTEST0018: '[DynamicData]' should only be set on a test method + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.NotTestMethodRule).WithSpan(7, 17, 7, 28), + // /0/Test0.cs(11,6): warning MSTEST0018: '[DynamicData]' member 'SomeClass.SomeProperty' cannot be found + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberNotFoundRule).WithSpan(11, 6, 11, 52).WithArguments("SomeClass", "SomeProperty"), + // /0/Test0.cs(12,17): warning MSTEST0018: '[DynamicData]' should only be set on a test method + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.NotTestMethodRule).WithSpan(12, 17, 12, 28), + // /0/Test0.cs(16,6): warning MSTEST0018: '[DynamicData]' member 'MyTestClass.SomeProperty' cannot be found + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberNotFoundRule).WithSpan(16, 6, 16, 56).WithArguments("MyTestClass", "SomeProperty"), + // /0/Test0.cs(17,17): warning MSTEST0018: '[DynamicData]' should only be set on a test method + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.NotTestMethodRule).WithSpan(17, 17, 17, 28), + // /0/Test0.cs(21,6): warning MSTEST0018: '[DynamicData]' member 'SomeClass.SomeProperty' cannot be found + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberNotFoundRule).WithSpan(21, 6, 21, 101).WithArguments("SomeClass", "SomeProperty"), + // /0/Test0.cs(22,17): warning MSTEST0018: '[DynamicData]' should only be set on a test method + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.NotTestMethodRule).WithSpan(22, 17, 22, 28)); } [TestMethod] @@ -582,8 +594,33 @@ public void TestMethod14(object[] o) { } + [{|#8:DynamicData(nameof(DataField), DynamicDataSourceType.Method)|}] + [TestMethod] + public void TestMethod15(object[] o) + { + } + + [{|#9:DynamicData(nameof(DataField), DynamicDataSourceType.Property)|}] + [TestMethod] + public void TestMethod16(object[] o) + { + } + + [{|#10:DynamicData(nameof(DataField), DynamicDataSourceType.AutoDetect)|}] + [TestMethod] + public void TestMethod17(object[] o) + { + } + + [{|#11:DynamicData(nameof(DataField))|}] + [TestMethod] + public void TestMethod18(object[] o) + { + } + public static IEnumerable Data => new List(); public static IEnumerable GetData() => new List(); + public static IEnumerable DataField = new List(); } public class SomeClass @@ -602,7 +639,11 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.SourceTypePropertyRule).WithLocation(4).WithArguments("MyTestClass", "Data"), VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.SourceTypePropertyRule).WithLocation(5).WithArguments("SomeClass", "SomeData"), VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.SourceTypePropertyRule).WithLocation(6).WithArguments("MyTestClass", "Data"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.SourceTypePropertyRule).WithLocation(7).WithArguments("SomeClass", "SomeData")); + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.SourceTypePropertyRule).WithLocation(7).WithArguments("SomeClass", "SomeData"), + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.SourceTypeNotPropertyOrMethodRule).WithLocation(8).WithArguments("MyTestClass", "DataField"), + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.SourceTypeNotPropertyOrMethodRule).WithLocation(9).WithArguments("MyTestClass", "DataField"), + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.SourceTypeNotPropertyOrMethodRule).WithLocation(10).WithArguments("MyTestClass", "DataField"), + VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.SourceTypeNotPropertyOrMethodRule).WithLocation(11).WithArguments("MyTestClass", "DataField")); } [TestMethod] From 61b558f9d0ffc8979d62d9e1c9229afab0bca984 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 18 Dec 2024 05:07:30 -0800 Subject: [PATCH 141/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2604061 --- src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index 9034506a08..2b8096f967 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -364,7 +364,7 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - Člen [DynamicData] {0}.{1} je metoda, takže byste měli nastavit DynamicDataSourceType.Method. + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -374,7 +374,7 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - Člen [DynamicData] {0}.{1} je vlastnost, takže byste měli nastavit DynamicDataSourceType.Property. + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index f620681c5a..37d70ae6af 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -366,7 +366,7 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - "[DynamicData]"-Element "{0}.{1}" ist eine Methode, daher sollten Sie "DynamicDataSourceType.Method" festlegen. + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -376,7 +376,7 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - "[DynamicData]"-Element "{0}.{1}" ist eine Eigenschaft, daher sollten Sie "DynamicDataSourceType.Property" festlegen. + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 58bc1a1c76..3b9dedcf56 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -364,7 +364,7 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - El miembro de '{0}.{1}' de '[DynamicData]' es un método, por lo que debe establecert 'DynamicDataSourceType.Method' + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -374,7 +374,7 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - El miembro de '{0}.{1}' de '[DynamicData]' es una propiedad, por lo que debe establecer 'DynamicDataSourceType.Property' + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 9659b2b9a3..9c798da092 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -364,7 +364,7 @@ Le type doit être une classe '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - Membre '[DynamicData]' '{0}.{1}' est une méthode, vous devez donc définir 'DynamicDataSourceType.Method' + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -374,7 +374,7 @@ Le type doit être une classe '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - Membre '[DynamicData]' '{0}.{1}' est une propriété, vous devez donc définir 'DynamicDataSourceType.Property' + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index 73fd28a209..6fe19f3fd9 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -364,7 +364,7 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - Il membro '[DynamicData]' '{0}.{1}' è un metodo, quindi impostare 'DynamicDataSourceType.Method' + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -374,7 +374,7 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - Il membro '[DynamicData]' '{0}.{1}' è una proprietà, quindi impostare 'DynamicDataSourceType.Property' + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 147e6f5f26..e7e4b11bb7 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -364,7 +364,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' メンバー '{0}.{1}' はメソッドであるため、'DynamicDataSourceType.Method' を設定する必要があります + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -374,7 +374,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' メンバー '{0}.{1}' はプロパティであるため、'DynamicDataSourceType.Property' を設定する必要があります + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 54f68d8f04..50810c8346 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -364,7 +364,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' 멤버 '{0}.{1}'은(는) 메서드이므로 'DynamicDataSourceType.Method'를 설정해야 합니다. + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -374,7 +374,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' 멤버 '{0}.{1}'은(는) 속성이므로 'DynamicDataSourceType.Property'를 설정해야 합니다. + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index aa965e181f..3b5d911698 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -364,7 +364,7 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - Element członkowski „{0}.{1}” „[DynamicData]” jest metodą, dlatego należy ustawić „DynamicDataSourceType.Method” + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -374,7 +374,7 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - Element członkowski „{0}.{1}” „[DynamicData]” jest właściwością, dlatego należy ustawić „DynamicDataSourceType.Property” + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 5b0259459d..4a1bbdc5d4 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -364,7 +364,7 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - O membro "{0}.{1}" de "[DynamicData]" é um método; portanto, você deve definir "DynamicDataSourceType.Method" + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -374,7 +374,7 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - O membro "{0}.{1}" de "[DynamicData]" é uma propriedade; portanto, você deve definir "DynamicDataSourceType.Property" + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index ce81847425..d7b35bb2f2 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -368,7 +368,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - Элемент "[DynamicData]" "{0}.{1}" является методом, поэтому следует задать "DynamicDataSourceType.Method" + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -378,7 +378,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - Элемент "[DynamicData]" "{0}.{1}" является свойством, поэтому следует задать "DynamicDataSourceType.Property" + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index a0dfd107c7..fe0feb4cd0 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -364,7 +364,7 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' üyesi '{0}.{1}' bir yöntem olduğundan 'DynamicDataSourceType.Method' öğesini ayarlamalısınız + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -374,7 +374,7 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' üyesi '{0}.{1}' bir özellik olduğundan 'DynamicDataSourceType.Property' öğesini ayarlamalısınız + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 8bf35ffe8a..fde4a6b1f6 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -364,7 +364,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - "[DynamicData]" 成员 "{0}.{1}" 是一个方法,因此应设置 "DynamicDataSourceType.Method" + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -374,7 +374,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - "[DynamicData]" 成员 "{0}.{1}" 是一个属性,因此应设置 "DynamicDataSourceType.Property" + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 65013f9dc0..5e4f919fa6 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -364,7 +364,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' 成員 '{0}.{1}' 是方法,因此您應該設定 'DynamicDataSourceType.Method' + '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) @@ -374,7 +374,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' 成員 '{0}.{1}' 是屬性,因此您應該設定 'DynamicDataSourceType.Property' + '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) From abc7029b7a948ca213f176713c09ace9553e7880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Wed, 18 Dec 2024 14:57:47 +0100 Subject: [PATCH 142/273] Simplify test dependencies (#4382) --- test/Directory.Build.targets | 5 +++-- test/Performance/MSTest.Performance.Runner/Program.cs | 6 +----- .../MSTest.Analyzers.UnitTests.csproj | 6 +++++- .../Microsoft.Testing.TestInfrastructure/Constants.cs | 3 --- .../Microsoft.Testing.TestInfrastructure.csproj | 3 --- 5 files changed, 9 insertions(+), 14 deletions(-) diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 463df410cc..2cdd2f3e1a 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -27,10 +27,11 @@ - + + + - diff --git a/test/Performance/MSTest.Performance.Runner/Program.cs b/test/Performance/MSTest.Performance.Runner/Program.cs index 11775c0650..b615f7baf5 100644 --- a/test/Performance/MSTest.Performance.Runner/Program.cs +++ b/test/Performance/MSTest.Performance.Runner/Program.cs @@ -5,16 +5,12 @@ using System.Runtime.InteropServices; using Microsoft.Testing.TestInfrastructure; -using Microsoft.VisualStudio.TestTools.UnitTesting; using MSTest.Performance.Runner.Steps; using DotnetMuxer = MSTest.Performance.Runner.Steps.DotnetMuxer; using ExecutionScope = MSTest.Performance.Runner.Steps.ExecutionScope; -// TODO: this should not be required -[assembly: Parallelize(Scope = Microsoft.VisualStudio.TestTools.UnitTesting.ExecutionScope.MethodLevel, Workers = 0)] - namespace MSTest.Performance.Runner; internal class EntryPoint @@ -27,7 +23,7 @@ public static Task Main(string[] args) Console.WriteLine("Microsoft (R) MSTest Performance Profiler Command Line Tool"); var rootCommand = new RootCommand("MSTest Performance Profiler Command Line Tool"); - var pipelineNameFilter = new Option(name: "--pipelineNameFilter", description: "Globbing filter for the pipeline name to execute.", getDefaultValue: () => string.Empty); + var pipelineNameFilter = new Option(name: "--pipelineNameFilter", description: "Globing filter for the pipeline name to execute.", getDefaultValue: () => string.Empty); var executeTests = new Command("execute", "Execute the performance scenarios.") { pipelineNameFilter, diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj b/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj index 40ef00ed4b..d525f44713 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/MSTest.Analyzers.UnitTests.csproj @@ -22,6 +22,10 @@ + + + + @@ -29,8 +33,8 @@ - + diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs index 65c5414243..a4489f8b11 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs @@ -3,9 +3,6 @@ using System.Runtime.InteropServices; -// TODO: this should not be required -[assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] - namespace Microsoft.Testing.TestInfrastructure; public static class Constants diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/Microsoft.Testing.TestInfrastructure.csproj b/test/Utilities/Microsoft.Testing.TestInfrastructure/Microsoft.Testing.TestInfrastructure.csproj index ebff01df15..5557b9cd96 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/Microsoft.Testing.TestInfrastructure.csproj +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/Microsoft.Testing.TestInfrastructure.csproj @@ -7,8 +7,6 @@ - - @@ -18,7 +16,6 @@ - From 7b7ec1d3ed04750acbbd094e45ffc767b1cacd2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 19 Dec 2024 10:41:58 +0100 Subject: [PATCH 143/273] Cleanup retry and hot reload versions and refs (#4393) --- Directory.Packages.props | 1 - eng/Version.Details.xml | 4 ---- eng/Versions.props | 1 - src/Package/MSTest.Sdk/MSTest.Sdk.csproj | 2 +- .../MSTest.Sdk/Sdk/Runner/ClassicEngine.targets | 4 ++-- src/Package/MSTest.Sdk/Sdk/Sdk.props.template | 1 - test/Directory.Build.targets | 1 + ...sting.Platform.Acceptance.IntegrationTests.csproj | 12 ------------ 8 files changed, 4 insertions(+), 22 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 310b6620af..2e0673f29b 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -43,7 +43,6 @@ - diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c41acf13b5..5a85febd43 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -17,10 +17,6 @@ https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage eb105201ff904a7d5c6fac39de838a4bb6966a93 - - https://github.com/microsoft/testanywhere - 33cb71263430f0dbe8f9ffd4edd76d837cb05259 - https://github.com/microsoft/testanywhere 2346f405dcb5150b567970995dc978feb26b2db0 diff --git a/eng/Versions.props b/eng/Versions.props index d7804ec652..0e7161ac55 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,7 +10,6 @@ 10.0.0-beta.24604.4 17.13.2-preview.24606.2 - 1.5.0-preview.24608.1 1.0.0-alpha.24473.2 diff --git a/src/Package/MSTest.Sdk/MSTest.Sdk.csproj b/src/Package/MSTest.Sdk/MSTest.Sdk.csproj index ed9f10179d..21f72c2b41 100644 --- a/src/Package/MSTest.Sdk/MSTest.Sdk.csproj +++ b/src/Package/MSTest.Sdk/MSTest.Sdk.csproj @@ -35,7 +35,7 @@ - <_TemplateProperties>MSTestEngineVersion=$(MSTestEngineVersion);MSTestVersion=$(Version);MicrosoftTestingPlatformVersion=$(Version.Replace('$(VersionPrefix)', '$(TestingPlatformVersionPrefix)'));MicrosoftTestingEntrepriseExtensionsVersion=$(MicrosoftTestingExtensionsRetryVersion);MicrosoftNETTestSdkVersion=$(MicrosoftNETTestSdkVersion);MicrosoftTestingExtensionsCodeCoverageVersion=$(MicrosoftTestingExtensionsCodeCoverageVersion);MicrosoftPlaywrightVersion=$(MicrosoftPlaywrightVersion);AspireHostingTestingVersion=$(AspireHostingTestingVersion);MicrosoftTestingExtensionsFakesVersion=$(MicrosoftTestingExtensionsFakesVersion) + <_TemplateProperties>MSTestEngineVersion=$(MSTestEngineVersion);MSTestVersion=$(Version);MicrosoftTestingPlatformVersion=$(Version.Replace('$(VersionPrefix)', '$(TestingPlatformVersionPrefix)'));MicrosoftNETTestSdkVersion=$(MicrosoftNETTestSdkVersion);MicrosoftTestingExtensionsCodeCoverageVersion=$(MicrosoftTestingExtensionsCodeCoverageVersion);MicrosoftPlaywrightVersion=$(MicrosoftPlaywrightVersion);AspireHostingTestingVersion=$(AspireHostingTestingVersion);MicrosoftTestingExtensionsFakesVersion=$(MicrosoftTestingExtensionsFakesVersion) true - $(MicrosoftTestingEntrepriseExtensionsVersion) + $(MicrosoftTestingExtensionsCommonVersion) true - $(MicrosoftTestingEntrepriseExtensionsVersion) + $(MicrosoftTestingExtensionsCommonVersion) true diff --git a/src/Package/MSTest.Sdk/Sdk/Sdk.props.template b/src/Package/MSTest.Sdk/Sdk/Sdk.props.template index 1da4144322..cf6c6f5242 100644 --- a/src/Package/MSTest.Sdk/Sdk/Sdk.props.template +++ b/src/Package/MSTest.Sdk/Sdk/Sdk.props.template @@ -16,7 +16,6 @@ ${AspireHostingTestingVersion} ${MicrosoftNETTestSdkVersion} ${MicrosoftPlaywrightVersion} - ${MicrosoftTestingEntrepriseExtensionsVersion} ${MicrosoftTestingExtensionsCodeCoverageVersion} ${MicrosoftTestingExtensionsFakesVersion} ${MicrosoftTestingPlatformVersion} diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets index 2cdd2f3e1a..5697bbf9cd 100644 --- a/test/Directory.Build.targets +++ b/test/Directory.Build.targets @@ -25,6 +25,7 @@ + diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj index 8e13bcf2f9..747774663a 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests.csproj @@ -12,17 +12,10 @@ - - - - - - - @@ -32,9 +25,4 @@ - - - - - From 3fc020b640718c5a8c455be1c9443d1ff796177a Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 19 Dec 2024 10:42:26 +0100 Subject: [PATCH 144/273] Fix DiagnosticExtensions class name (#4390) --- .../RoslynAnalyzerHelpers/DiagnosticExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/DiagnosticExtensions.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/DiagnosticExtensions.cs index a83e870acc..d5e5134011 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/DiagnosticExtensions.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/DiagnosticExtensions.cs @@ -8,7 +8,7 @@ namespace Analyzer.Utilities.Extensions; -internal static class FixtureUtils +internal static class DiagnosticExtensions { public static Diagnostic CreateDiagnostic( this SyntaxNode node, From 5bdcacdbc2d2b0d08f8fa18a027ff4098b1ac5c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 19 Dec 2024 10:42:56 +0100 Subject: [PATCH 145/273] Allow any IEnumerable as return type to DynamicData source member (#4389) --- .../DynamicDataOperations.cs | 62 +++-- .../DynamicDataShouldBeValidAnalyzer.cs | 42 +-- .../Helpers/WellKnownTypeNames.cs | 1 - .../DataSource/DynamicDataAttribute.cs | 89 ++----- .../Resources/FrameworkMessages.Designer.cs | 2 +- .../Resources/FrameworkMessages.resx | 4 +- .../Resources/xlf/FrameworkMessages.cs.xlf | 4 +- .../Resources/xlf/FrameworkMessages.de.xlf | 4 +- .../Resources/xlf/FrameworkMessages.es.xlf | 4 +- .../Resources/xlf/FrameworkMessages.fr.xlf | 4 +- .../Resources/xlf/FrameworkMessages.it.xlf | 4 +- .../Resources/xlf/FrameworkMessages.ja.xlf | 4 +- .../Resources/xlf/FrameworkMessages.ko.xlf | 4 +- .../Resources/xlf/FrameworkMessages.pl.xlf | 4 +- .../Resources/xlf/FrameworkMessages.pt-BR.xlf | 4 +- .../Resources/xlf/FrameworkMessages.ru.xlf | 4 +- .../Resources/xlf/FrameworkMessages.tr.xlf | 4 +- .../xlf/FrameworkMessages.zh-Hans.xlf | 4 +- .../xlf/FrameworkMessages.zh-Hant.xlf | 4 +- .../Parameterized tests/DynamicDataTests.cs | 5 +- .../Parameterized tests/DynamicDataTests.cs | 5 +- .../DynamicDataTests.cs | 15 ++ .../DynamicDataShouldBeValidAnalyzerTests.cs | 245 ++++++++---------- 23 files changed, 229 insertions(+), 293 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs b/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs index 5a2631f7be..c33c1f1b7d 100644 --- a/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs @@ -160,50 +160,62 @@ private static bool TryGetData(object dataSource, [NotNullWhen(true)] out IEnume return true; } - if (dataSource is IEnumerable enumerable) + if (dataSource is IEnumerable enumerable and not string) { List objects = new(); foreach (object? entry in enumerable) { -#if NET471_OR_GREATER || NETCOREAPP - if (entry is not ITuple tuple - || (objects.Count > 0 && objects[^1].Length != tuple.Length)) + if (entry is null) { data = null; return false; } - object[] array = new object[tuple.Length]; - for (int i = 0; i < tuple.Length; i++) + if (!TryHandleTupleDataSource(entry, objects)) { - array[i] = tuple[i]!; + objects.Add(new[] { entry }); } + } - objects.Add(array); -#else - Type type = entry.GetType(); - if (!IsTupleOrValueTuple(entry.GetType(), out int tupleSize) - || (objects.Count > 0 && objects[objects.Count - 1].Length != tupleSize)) - { - data = null; - return false; - } + data = objects; + return true; + } - object[] array = new object[tupleSize]; - for (int i = 0; i < tupleSize; i++) - { - array[i] = type.GetField($"Item{i + 1}")?.GetValue(entry)!; - } + data = null; + return false; + } - objects.Add(array); -#endif + private static bool TryHandleTupleDataSource(object data, List objects) + { +#if NET471_OR_GREATER || NETCOREAPP + if (data is ITuple tuple + && (objects.Count == 0 || objects[^1].Length == tuple.Length)) + { + object[] array = new object[tuple.Length]; + for (int i = 0; i < tuple.Length; i++) + { + array[i] = tuple[i]!; } - data = objects; + objects.Add(array); return true; } +#else + Type type = data.GetType(); + if (IsTupleOrValueTuple(data.GetType(), out int tupleSize) + && (objects.Count == 0 || objects[objects.Count - 1].Length == tupleSize)) + { + object[] array = new object[tupleSize]; + for (int i = 0; i < tupleSize; i++) + { + array[i] = type.GetField($"Item{i + 1}")?.GetValue(data)!; + } + + objects.Add(array); + return true; + } +#endif - data = null; return false; } diff --git a/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs index 4c400817e6..acc5aeab60 100644 --- a/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs @@ -85,12 +85,11 @@ public override void Initialize(AnalysisContext context) && context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingDynamicDataAttribute, out INamedTypeSymbol? dynamicDataAttributeSymbol) && context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingDynamicDataSourceType, out INamedTypeSymbol? dynamicDataSourceTypeSymbol) && context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemCollectionsGenericIEnumerable1, out INamedTypeSymbol? ienumerableTypeSymbol) - && context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemRuntimeCompilerServicesITuple, out INamedTypeSymbol? itupleTypeSymbol) && context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemReflectionMethodInfo, out INamedTypeSymbol? methodInfoTypeSymbol)) { context.RegisterSymbolAction( context => AnalyzeSymbol(context, testMethodAttributeSymbol, dynamicDataAttributeSymbol, dynamicDataSourceTypeSymbol, - ienumerableTypeSymbol, itupleTypeSymbol, methodInfoTypeSymbol), + ienumerableTypeSymbol, methodInfoTypeSymbol), SymbolKind.Method); } }); @@ -98,7 +97,7 @@ public override void Initialize(AnalysisContext context) private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol testMethodAttributeSymbol, INamedTypeSymbol dynamicDataAttributeSymbol, INamedTypeSymbol dynamicDataSourceTypeSymbol, INamedTypeSymbol ienumerableTypeSymbol, - INamedTypeSymbol itupleTypeSymbol, INamedTypeSymbol methodInfoTypeSymbol) + INamedTypeSymbol methodInfoTypeSymbol) { var methodSymbol = (IMethodSymbol)context.Symbol; @@ -116,7 +115,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo if (SymbolEqualityComparer.Default.Equals(methodAttribute.AttributeClass, dynamicDataAttributeSymbol)) { hasDynamicDataAttribute = true; - AnalyzeAttribute(context, methodAttribute, methodSymbol, dynamicDataSourceTypeSymbol, ienumerableTypeSymbol, itupleTypeSymbol, methodInfoTypeSymbol); + AnalyzeAttribute(context, methodAttribute, methodSymbol, dynamicDataSourceTypeSymbol, ienumerableTypeSymbol, methodInfoTypeSymbol); } } @@ -128,22 +127,19 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo } private static void AnalyzeAttribute(SymbolAnalysisContext context, AttributeData attributeData, IMethodSymbol methodSymbol, - INamedTypeSymbol dynamicDataSourceTypeSymbol, INamedTypeSymbol ienumerableTypeSymbol, INamedTypeSymbol itupleTypeSymbol, - INamedTypeSymbol methodInfoTypeSymbol) + INamedTypeSymbol dynamicDataSourceTypeSymbol, INamedTypeSymbol ienumerableTypeSymbol, INamedTypeSymbol methodInfoTypeSymbol) { if (attributeData.ApplicationSyntaxReference?.GetSyntax() is not { } attributeSyntax) { return; } - AnalyzeDataSource(context, attributeData, attributeSyntax, methodSymbol, dynamicDataSourceTypeSymbol, ienumerableTypeSymbol, - itupleTypeSymbol); + AnalyzeDataSource(context, attributeData, attributeSyntax, methodSymbol, dynamicDataSourceTypeSymbol, ienumerableTypeSymbol); AnalyzeDisplayNameSource(context, attributeData, attributeSyntax, methodSymbol, methodInfoTypeSymbol); } private static void AnalyzeDataSource(SymbolAnalysisContext context, AttributeData attributeData, SyntaxNode attributeSyntax, - IMethodSymbol methodSymbol, INamedTypeSymbol dynamicDataSourceTypeSymbol, INamedTypeSymbol ienumerableTypeSymbol, - INamedTypeSymbol itupleTypeSymbol) + IMethodSymbol methodSymbol, INamedTypeSymbol dynamicDataSourceTypeSymbol, INamedTypeSymbol ienumerableTypeSymbol) { string? memberName = null; int dataSourceType = DynamicDataSourceTypeAutoDetect; @@ -234,28 +230,12 @@ private static void AnalyzeDataSource(SymbolAnalysisContext context, AttributeDa // Validate member return type. ITypeSymbol? memberTypeSymbol = member.GetMemberType(); - if (memberTypeSymbol is INamedTypeSymbol memberNamedType) + if (memberTypeSymbol is INamedTypeSymbol memberNamedType + && (!SymbolEqualityComparer.Default.Equals(memberNamedType.ConstructedFrom, ienumerableTypeSymbol) + || memberNamedType.TypeArguments.Length != 1)) { - if (!SymbolEqualityComparer.Default.Equals(memberNamedType.ConstructedFrom, ienumerableTypeSymbol) - || memberNamedType.TypeArguments.Length != 1) - { - context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(MemberTypeRule, declaringType.Name, memberName)); - return; - } - - ITypeSymbol collectionBoundType = memberNamedType.TypeArguments[0]; - if (!collectionBoundType.Inherits(itupleTypeSymbol) - && collectionBoundType is not IArrayTypeSymbol) - { - context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(MemberTypeRule, declaringType.Name, memberName)); - } - } - else if (memberTypeSymbol is IArrayTypeSymbol arrayType) - { - if (arrayType.ElementType is not IArrayTypeSymbol) - { - context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(MemberTypeRule, declaringType.Name, memberName)); - } + context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(MemberTypeRule, declaringType.Name, memberName)); + return; } } diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs b/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs index 92bafef649..dacfbbf53b 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs @@ -45,7 +45,6 @@ internal static class WellKnownTypeNames public const string SystemIAsyncDisposable = "System.IAsyncDisposable"; public const string SystemIDisposable = "System.IDisposable"; public const string SystemReflectionMethodInfo = "System.Reflection.MethodInfo"; - public const string SystemRuntimeCompilerServicesITuple = "System.Runtime.CompilerServices.ITuple"; public const string SystemThreadingTasksTask = "System.Threading.Tasks.Task"; public const string SystemThreadingTasksTask1 = "System.Threading.Tasks.Task`1"; public const string SystemThreadingTasksValueTask = "System.Threading.Tasks.ValueTask"; diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs index a7240468d8..3361ea15d0 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs @@ -1,12 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -#if NETCOREAPP || NET471_OR_GREATER -using System.Collections; -using System.Runtime.CompilerServices; -#endif using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Reflection; @@ -122,75 +117,41 @@ public DynamicDataAttribute(string dynamicDataSourceName, Type dynamicDataDeclar public TestDataSourceUnfoldingStrategy UnfoldingStrategy { get; set; } = TestDataSourceUnfoldingStrategy.Auto; /// - public IEnumerable GetData(MethodInfo methodInfo) => DynamicDataProvider.Instance.GetData(_dynamicDataDeclaringType, _dynamicDataSourceType, _dynamicDataSourceName, methodInfo); + public IEnumerable GetData(MethodInfo methodInfo) + => DynamicDataProvider.Instance.GetData(_dynamicDataDeclaringType, _dynamicDataSourceType, _dynamicDataSourceName, methodInfo); /// public string? GetDisplayName(MethodInfo methodInfo, object?[]? data) { - if (DynamicDataDisplayName != null) + if (DynamicDataDisplayName == null) { - Type? dynamicDisplayNameDeclaringType = DynamicDataDisplayNameDeclaringType ?? methodInfo.DeclaringType; - DebugEx.Assert(dynamicDisplayNameDeclaringType is not null, "Declaring type of test data cannot be null."); - - MethodInfo method = dynamicDisplayNameDeclaringType.GetTypeInfo().GetDeclaredMethod(DynamicDataDisplayName) - ?? throw new ArgumentNullException($"{DynamicDataSourceType.Method} {DynamicDataDisplayName}"); - ParameterInfo[] parameters = method.GetParameters(); - return parameters.Length != 2 || - parameters[0].ParameterType != typeof(MethodInfo) || - parameters[1].ParameterType != typeof(object[]) || - method.ReturnType != typeof(string) || - !method.IsStatic || - !method.IsPublic - ? throw new ArgumentNullException( - string.Format( - CultureInfo.InvariantCulture, - FrameworkMessages.DynamicDataDisplayName, - DynamicDataDisplayName, - nameof(String), - string.Join(", ", nameof(MethodInfo), typeof(object[]).Name))) - : method.Invoke(null, [methodInfo, data]) as string; + return TestDataSourceUtilities.ComputeDefaultDisplayName(methodInfo, data, TestIdGenerationStrategy); } - return TestDataSourceUtilities.ComputeDefaultDisplayName(methodInfo, data, TestIdGenerationStrategy); - } - - private static bool TryGetData(object dataSource, [NotNullWhen(true)] out IEnumerable? data) - { - if (dataSource is IEnumerable enumerableObjectArray) - { - data = enumerableObjectArray; - return true; - } - -#if NETCOREAPP || NET471_OR_GREATER - if (dataSource is IEnumerable enumerable) + Type? dynamicDisplayNameDeclaringType = DynamicDataDisplayNameDeclaringType ?? methodInfo.DeclaringType; + DebugEx.Assert(dynamicDisplayNameDeclaringType is not null, "Declaring type of test data cannot be null."); + + MethodInfo method = dynamicDisplayNameDeclaringType.GetTypeInfo().GetDeclaredMethod(DynamicDataDisplayName) + ?? throw new ArgumentNullException($"{DynamicDataSourceType.Method} {DynamicDataDisplayName}"); + ParameterInfo[] parameters = method.GetParameters(); + if (parameters.Length != 2 + || parameters[0].ParameterType != typeof(MethodInfo) + || parameters[1].ParameterType != typeof(object[]) + || method.ReturnType != typeof(string) + || !method.IsStatic + || !method.IsPublic) { - List objects = new(); - foreach (object? entry in enumerable) - { - if (entry is not ITuple tuple - || (objects.Count > 0 && objects[^1].Length != tuple.Length)) - { - data = null; - return false; - } - - object[] array = new object[tuple.Length]; - for (int i = 0; i < tuple.Length; i++) - { - array[i] = tuple[i]!; - } - - objects.Add(array); - } - - data = objects; - return true; + throw new ArgumentNullException( + string.Format( + CultureInfo.InvariantCulture, + FrameworkMessages.DynamicDataDisplayName, + DynamicDataDisplayName, + nameof(String), + string.Join(", ", nameof(MethodInfo), typeof(object[]).Name))); } -#endif - data = null; - return false; + // Try to get the display name from the method. + return method.Invoke(null, [methodInfo, data]) as string; } string? ITestDataSourceEmptyDataSourceExceptionInfo.GetPropertyOrMethodNameForEmptyDataSourceException() diff --git a/src/TestFramework/TestFramework/Resources/FrameworkMessages.Designer.cs b/src/TestFramework/TestFramework/Resources/FrameworkMessages.Designer.cs index 67efb2d944..9fd4712ea7 100644 --- a/src/TestFramework/TestFramework/Resources/FrameworkMessages.Designer.cs +++ b/src/TestFramework/TestFramework/Resources/FrameworkMessages.Designer.cs @@ -295,7 +295,7 @@ internal static string DynamicDataIEnumerableEmpty { } /// - /// Looks up a localized string similar to Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core).. + /// Looks up a localized string similar to Property or method {0} on {1} return type is not assignable to 'IEnumerable'.. /// internal static string DynamicDataIEnumerableNull { get { diff --git a/src/TestFramework/TestFramework/Resources/FrameworkMessages.resx b/src/TestFramework/TestFramework/Resources/FrameworkMessages.resx index 8a0a86b9df..dd36b5c2f8 100644 --- a/src/TestFramework/TestFramework/Resources/FrameworkMessages.resx +++ b/src/TestFramework/TestFramework/Resources/FrameworkMessages.resx @@ -263,7 +263,7 @@ Actual: {2} UITestMethodAttribute.DispatcherQueue should not be null. To use UITestMethodAttribute within a WinUI Desktop App, remember to set the static UITestMethodAttribute.DispatcherQueue during the test initialization. - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. Value returned by property or method {0} shouldn't be null. @@ -287,4 +287,4 @@ Actual: {2} Dynamic data property '{0}' should be static and have a getter. - \ No newline at end of file + diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf index c5f80ae742..d5f7ef3690 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf @@ -253,8 +253,8 @@ Skutečnost: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - Vlastnost nebo metoda {0} na návratovém typu {1} se nedá přiřadit k „IEnumerable<object[]>“ (ani „IEnumerable<ITuple>“ pro .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + Vlastnost nebo metoda {0} na návratovém typu {1} se nedá přiřadit k „IEnumerable<object[]>“ (ani „IEnumerable<ITuple>“ pro .NET Core). diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf index 28fadee2b5..11674effd2 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf @@ -253,8 +253,8 @@ Tatsächlich: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - Die Eigenschaft oder Methode "{0}" für Rückgabetyp "{1}" kann "IEnumerable<object[]>" nicht zugewiesen werden (auch nicht "IEnumerable<ITuple>" für .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + Die Eigenschaft oder Methode "{0}" für Rückgabetyp "{1}" kann "IEnumerable<object[]>" nicht zugewiesen werden (auch nicht "IEnumerable<ITuple>" für .NET Core). diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf index cd8b47406d..36e0fcaa67 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf @@ -253,8 +253,8 @@ Real: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - La propiedad o el método {0} en {1} tipo de valor devuelto no se puede asignar a "IEnumerable<objecto[]>" (ni a "IEnumerable<ITuple>" para .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + La propiedad o el método {0} en {1} tipo de valor devuelto no se puede asignar a "IEnumerable<objecto[]>" (ni a "IEnumerable<ITuple>" para .NET Core). diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf index 5ed63942ad..11bf22ec30 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf @@ -253,8 +253,8 @@ Réel : {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - La propriété ou la méthode {0} sur le type de retour {1} ne peut pas être attribuée à « IEnumerable<object[]> » (ni à « IEnumerable<ITuple> » pour .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + La propriété ou la méthode {0} sur le type de retour {1} ne peut pas être attribuée à « IEnumerable<object[]> » (ni à « IEnumerable<ITuple> » pour .NET Core). diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf index 71bcd535ff..6a0aff7534 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf @@ -253,8 +253,8 @@ Effettivo: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - La proprietà o il metodo {0} su {1} tipo restituito non è assegnabile a 'IEnumerable<object[]>' (né a 'IEnumerable<ITuple>' per .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + La proprietà o il metodo {0} su {1} tipo restituito non è assegnabile a 'IEnumerable<object[]>' (né a 'IEnumerable<ITuple>' per .NET Core). diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf index b59c9fcec1..0cb38f531a 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf @@ -253,8 +253,8 @@ Actual: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - {1} 戻り値の型のプロパティまたはメソッド {0} は、'IEnumerable<object[]>' (.NET Core の場合は 'IEnumerable<ITuple>' に割り当てできません)。 + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + {1} 戻り値の型のプロパティまたはメソッド {0} は、'IEnumerable<object[]>' (.NET Core の場合は 'IEnumerable<ITuple>' に割り当てできません)。 diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf index 115b45d027..bc0c38c646 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf @@ -253,8 +253,8 @@ Actual: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - {1} 반환 형식의 속성 또는 메서드 {0}은(는) 'IEnumerable<object[]>'(.NET Core의 경우 'IEnumerable<ITuple>')에 할당할 수 없습니다. + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + {1} 반환 형식의 속성 또는 메서드 {0}은(는) 'IEnumerable<object[]>'(.NET Core의 경우 'IEnumerable<ITuple>')에 할당할 수 없습니다. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf index a0679c8cdf..c4b7f133ea 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf @@ -253,8 +253,8 @@ Rzeczywiste: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - Właściwości lub metody {0} w zwracanym typie {1} nie można przypisać do elementu „IEnumerable<object[]>” (ani „IEnumerable<ITuple>” dla platformy .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + Właściwości lub metody {0} w zwracanym typie {1} nie można przypisać do elementu „IEnumerable<object[]>” (ani „IEnumerable<ITuple>” dla platformy .NET Core). diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf index cb285ff60e..85a180e229 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf @@ -253,8 +253,8 @@ Real: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - A propriedade ou método {0} no {1} tipo de retorno não pode ser atribuído a 'IEnumerable<object[]>” (nem 'IEnumerable<ITuple>” para .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + A propriedade ou método {0} no {1} tipo de retorno não pode ser atribuído a 'IEnumerable<object[]>” (nem 'IEnumerable<ITuple>” para .NET Core). diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf index 2daf879f2e..8efd601c62 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf @@ -253,8 +253,8 @@ Actual: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - Свойство или метод {0} возвращаемого типа {1} не могут быть назначены объекту "IEnumerable<[]>" (или "IEnumerable<ITuple>" для .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + Свойство или метод {0} возвращаемого типа {1} не могут быть назначены объекту "IEnumerable<[]>" (или "IEnumerable<ITuple>" для .NET Core). diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf index 870ccfbf3d..d5b60bb38a 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf @@ -253,8 +253,8 @@ Gerçekte olan: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - {1} dönüş türündeki {0} özelliği veya yöntemi 'IEnumerable<object[]>' öğesine (veya .NET Core için 'IEnumerable<ITuple>' öğesine) atanamaz. + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + {1} dönüş türündeki {0} özelliği veya yöntemi 'IEnumerable<object[]>' öğesine (veya .NET Core için 'IEnumerable<ITuple>' öğesine) atanamaz. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf index 8ef99214ca..8216a4f254 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf @@ -253,8 +253,8 @@ Actual: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - {1} 返回类型上的属性或方法 {0} 不能分配给 "IEnumerable<object[]>" (对于 .NET Core,也不能分配给 "IEnumerable<ITuple>")。 + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + {1} 返回类型上的属性或方法 {0} 不能分配给 "IEnumerable<object[]>" (对于 .NET Core,也不能分配给 "IEnumerable<ITuple>")。 diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf index 4fb282577d..3b6b0e03a3 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf @@ -253,8 +253,8 @@ Actual: {2} - Property or method {0} on {1} return type is not assignable to 'IEnumerable<object[]>' (nor 'IEnumerable<ITuple>' for .NET Core). - {1} 傳回類型上的屬性或方法 {0} 無法指派給 'IEnumerable<object[]>' (或 'IEnumerable<ITuple>' 給 .NET Core) + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + {1} 傳回類型上的屬性或方法 {0} 無法指派給 'IEnumerable<object[]>' (或 'IEnumerable<ITuple>' 給 .NET Core) diff --git a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs index bd61e0b916..f88dae7f1b 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs @@ -58,7 +58,10 @@ public void ExecuteDynamicDataTests() "MethodWithOverload (\"1\",1)", "MethodWithOverload (\"2\",1)", "MethodWithOverload (1,\"0\")", - "MethodWithOverload (2,\"2\")"); + "MethodWithOverload (2,\"2\")", + "DynamicDataTest_SimpleCollection(0)", + "DynamicDataTest_SimpleCollection(2)", + "DynamicDataTest_SimpleCollection(4)"); VerifyE2E.FailedTestCount(testResults, 0); } diff --git a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs index 652f65471b..d6686c1f01 100644 --- a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs +++ b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs @@ -52,7 +52,10 @@ public void ExecuteDynamicDataTests() "MethodWithOverload (\"1\",1)", "MethodWithOverload (\"2\",1)", "MethodWithOverload (1,\"0\")", - "MethodWithOverload (2,\"2\")"); + "MethodWithOverload (2,\"2\")", + "DynamicDataTest_SimpleCollection(0)", + "DynamicDataTest_SimpleCollection(2)", + "DynamicDataTest_SimpleCollection(4)"); ValidateFailedTestsCount(0); } diff --git a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs index 6013db1afa..03635ebb52 100644 --- a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs +++ b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs @@ -100,6 +100,11 @@ public void MethodWithOverload(int x, string y) { } + [TestMethod] + [DynamicData(nameof(SimpleCollection))] + public void DynamicDataTest_SimpleCollection(int value) + => Assert.AreEqual(0, value % 2); + private static void ParseAndAssert(string userData, User expectedUser) { // Prepare @@ -212,4 +217,14 @@ private static IEnumerable Int32AndString() yield return new object[] { 1, "0" }; yield return new object[] { 2, "2" }; } + + private static IEnumerable SimpleCollection + { + get + { + yield return 0; + yield return 2; + yield return 4; + } + } } diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs index 79d5212059..d57bf15a77 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs @@ -309,16 +309,116 @@ public void TestMethod414(MyTestClass[] testClasses) { } + [DynamicData("Data")] + [TestMethod] + public void TestMethod501(object[] o) + { + } + + [DynamicData("SomeData", typeof(SomeClass))] + [TestMethod] + public void TestMethod502(object[] o) + { + } + + [DynamicData(dynamicDataSourceName: "Data")] + [TestMethod] + public void TestMethod503(object[] o) + { + } + + [DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "SomeData")] + [TestMethod] + public void TestMethod504(object[] o) + { + } + + [DynamicData("GetData", DynamicDataSourceType.Method)] + [TestMethod] + public void TestMethod511(object[] o) + { + } + + [DynamicData("GetSomeData", typeof(SomeClass), DynamicDataSourceType.Method)] + [TestMethod] + public void TestMethod512(object[] o) + { + } + + [DynamicData(dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetData")] + [TestMethod] + public void TestMethod513(object[] o) + { + } + + [DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetSomeData")] + [TestMethod] + public void TestMethod514(object[] o) + { + } + + [DynamicData("DataArray")] + [TestMethod] + public void TestMethod601(MyTestClass[] o) + { + } + + [DynamicData("SomeDataArray", typeof(SomeClass))] + [TestMethod] + public void TestMethod602(MyTestClass[] o) + { + } + + [DynamicData(dynamicDataSourceName: "DataArray")] + [TestMethod] + public void TestMethod603(MyTestClass[] o) + { + } + + [DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "SomeDataArray")] + [TestMethod] + public void TestMethod604(MyTestClass[] o) + { + } + + [DynamicData("GetDataArray", DynamicDataSourceType.Method)] + [TestMethod] + public void TestMethod611(MyTestClass[] o) + { + } + + [DynamicData("GetSomeDataArray", typeof(SomeClass), DynamicDataSourceType.Method)] + [TestMethod] + public void TestMethod612(MyTestClass[] o) + { + } + + [DynamicData(dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetDataArray")] + [TestMethod] + public void TestMethod613(MyTestClass[] o) + { + } + + [DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetSomeDataArray")] + [TestMethod] + public void TestMethod614(MyTestClass[] o) + { + } + public static IEnumerable Data => new List(); public static IEnumerable> DataTuple => new List>(); public static IEnumerable<(int, string)> DataValueTuple => new List<(int, string)>(); public static MyTestClass[][] DataJaggedArray => System.Array.Empty(); public static IEnumerable DataNonObjectTypeArray => new List(); + public static IEnumerable DataObject => new List(); + public static MyTestClass[] DataArray => System.Array.Empty(); public static IEnumerable GetData() => new List(); public static IEnumerable> GetDataTuple() => new List>(); public static IEnumerable<(int, string)> GetDataValueTuple() => new List<(int, string)>(); public static MyTestClass[][] GetDataJaggedArray() => System.Array.Empty(); public static IEnumerable GetDataNonObjectTypeArray() => new List(); + public static IEnumerable GetDataObject() => new List(); + public static MyTestClass[] GetDataArray() => System.Array.Empty(); } public class SomeClass @@ -328,11 +428,15 @@ public class SomeClass public static IEnumerable<(int, string)> SomeDataValueTuple => new List<(int, string)>(); public static MyTestClass[][] SomeDataJaggedArray => System.Array.Empty(); public static IEnumerable SomeDataNonObjectTypeArray => new List(); + public static IEnumerable SomeDataObject => new List(); + public static MyTestClass[] SomeDataArray => System.Array.Empty(); public static IEnumerable GetSomeData() => new List(); public static IEnumerable> GetSomeDataTuple() => new List>(); public static IEnumerable<(int, string)> GetSomeDataValueTuple() => new List<(int, string)>(); public static MyTestClass[][] GetSomeDataJaggedArray() => System.Array.Empty(); public static IEnumerable GetSomeDataNonObjectTypeArray() => new List(); + public static IEnumerable GetSomeDataObject() => new List(); + public static MyTestClass[] GetSomeDataArray() => System.Array.Empty(); } """; @@ -646,147 +750,6 @@ await VerifyCS.VerifyAnalyzerAsync( VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.SourceTypeNotPropertyOrMethodRule).WithLocation(11).WithArguments("MyTestClass", "DataField")); } - [TestMethod] - public async Task WhenDataSourceReturnTypeIsInvalid_Diagnostic() - { - string code = """ - using System.Collections.Generic; - using Microsoft.VisualStudio.TestTools.UnitTesting; - - [TestClass] - public class MyTestClass - { - [{|#0:DynamicData("Data")|}] - [TestMethod] - public void TestMethod1(object[] o) - { - } - - [{|#1:DynamicData("SomeData", typeof(SomeClass))|}] - [TestMethod] - public void TestMethod2(object[] o) - { - } - - [{|#2:DynamicData(dynamicDataSourceName: "Data")|}] - [TestMethod] - public void TestMethod3(object[] o) - { - } - - [{|#3:DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "SomeData")|}] - [TestMethod] - public void TestMethod4(object[] o) - { - } - - [{|#4:DynamicData("GetData", DynamicDataSourceType.Method)|}] - [TestMethod] - public void TestMethod5(object[] o) - { - } - - [{|#5:DynamicData("GetSomeData", typeof(SomeClass), DynamicDataSourceType.Method)|}] - [TestMethod] - public void TestMethod6(object[] o) - { - } - - [{|#6:DynamicData(dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetData")|}] - [TestMethod] - public void TestMethod7(object[] o) - { - } - - [{|#7:DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetSomeData")|}] - [TestMethod] - public void TestMethod8(object[] o) - { - } - - [{|#8:DynamicData("DataArray")|}] - [TestMethod] - public void TestMethod9(MyTestClass[] o) - { - } - - [{|#9:DynamicData("SomeDataArray", typeof(SomeClass))|}] - [TestMethod] - public void TestMethod10(MyTestClass[] o) - { - } - - [{|#10:DynamicData(dynamicDataSourceName: "DataArray")|}] - [TestMethod] - public void TestMethod11(MyTestClass[] o) - { - } - - [{|#11:DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceName: "SomeDataArray")|}] - [TestMethod] - public void TestMethod12(MyTestClass[] o) - { - } - - [{|#12:DynamicData("GetDataArray", DynamicDataSourceType.Method)|}] - [TestMethod] - public void TestMethod13(MyTestClass[] o) - { - } - - [{|#13:DynamicData("GetSomeDataArray", typeof(SomeClass), DynamicDataSourceType.Method)|}] - [TestMethod] - public void TestMethod14(MyTestClass[] o) - { - } - - [{|#14:DynamicData(dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetDataArray")|}] - [TestMethod] - public void TestMethod15(MyTestClass[] o) - { - } - - [{|#15:DynamicData(dynamicDataDeclaringType: typeof(SomeClass), dynamicDataSourceType: DynamicDataSourceType.Method, dynamicDataSourceName: "GetSomeDataArray")|}] - [TestMethod] - public void TestMethod16(MyTestClass[] o) - { - } - - public static IEnumerable Data => new List(); - public static MyTestClass[] DataArray => System.Array.Empty(); - public static IEnumerable GetData() => new List(); - public static MyTestClass[] GetDataArray() => System.Array.Empty(); - } - - public class SomeClass - { - public static IEnumerable SomeData => new List(); - public static MyTestClass[] SomeDataArray => System.Array.Empty(); - public static IEnumerable GetSomeData() => new List(); - public static MyTestClass[] GetSomeDataArray() => System.Array.Empty(); - } - """; - - await VerifyCS.VerifyAnalyzerAsync( - code, - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(0).WithArguments("MyTestClass", "Data"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(1).WithArguments("SomeClass", "SomeData"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(2).WithArguments("MyTestClass", "Data"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(3).WithArguments("SomeClass", "SomeData"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(4).WithArguments("MyTestClass", "GetData"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(5).WithArguments("SomeClass", "GetSomeData"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(6).WithArguments("MyTestClass", "GetData"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(7).WithArguments("SomeClass", "GetSomeData"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(8).WithArguments("MyTestClass", "DataArray"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(9).WithArguments("SomeClass", "SomeDataArray"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(10).WithArguments("MyTestClass", "DataArray"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(11).WithArguments("SomeClass", "SomeDataArray"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(12).WithArguments("MyTestClass", "GetDataArray"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(13).WithArguments("SomeClass", "GetSomeDataArray"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(14).WithArguments("MyTestClass", "GetDataArray"), - VerifyCS.Diagnostic(DynamicDataShouldBeValidAnalyzer.MemberTypeRule).WithLocation(15).WithArguments("SomeClass", "GetSomeDataArray")); - } - [TestMethod] public async Task MemberIsNotStatic_Diagnostic() { From ddf39b48535169a1b8b47f956fa3c6e28c46e08a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 19 Dec 2024 10:54:09 +0100 Subject: [PATCH 146/273] Fix flakiness on test Log_WhenAsyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsIt (#4394) --- .../Logging/FileLoggerTests.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs index 2b88b549d2..8d313146f8 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs @@ -197,30 +197,28 @@ public async Task Log_WhenSyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsIt [TestMethod] [DynamicData(nameof(LogTestHelpers.GetLogLevelCombinations), typeof(LogTestHelpers), DynamicDataSourceType.Method)] - public async Task Log_WhenAsyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsIt(LogLevel defaultLogLevel, LogLevel currentLogLevel) + public void Log_WhenAsyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsIt(LogLevel defaultLogLevel, LogLevel currentLogLevel) { _mockFileSystem.Setup(x => x.Exists(It.IsAny())).Returns(false); _mockFileStreamFactory .Setup(x => x.Create(It.IsAny(), FileMode.CreateNew, FileAccess.Write, FileShare.Read)) .Returns(_mockStream.Object); - using FileLogger fileLogger = new( + // Ensures that the async flush is completed before the file is read + using (FileLogger fileLogger = new( new(LogFolder, LogPrefix, fileName: FileName, syncFlush: false), defaultLogLevel, _mockClock.Object, new SystemTask(), _mockConsole.Object, _mockFileSystem.Object, - _mockFileStreamFactory.Object); - fileLogger.Log(currentLogLevel, Message, null, Formatter, Category); + _mockFileStreamFactory.Object)) + { + fileLogger.Log(currentLogLevel, Message, null, Formatter, Category); + } if (LogTestHelpers.IsLogEnabled(defaultLogLevel, currentLogLevel)) { - if (_memoryStream.Length == 0) - { - await Task.Delay(1000); - } - Assert.AreEqual($"0001-01-01T00:00:00.0000000+00:00 Test {currentLogLevel.ToString().ToUpperInvariant()} Message{Environment.NewLine}", Encoding.Default.GetString(_memoryStream.ToArray())); } else From 8165be49b43ebd0f7fa3534235722ba9c94d061f Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 19 Dec 2024 03:01:21 -0800 Subject: [PATCH 147/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2604632 (#4395) --- .../MSTest.Analyzers/xlf/Resources.cs.xlf | 16 ++++++++-------- .../MSTest.Analyzers/xlf/Resources.pl.xlf | 16 ++++++++-------- .../Resources/xlf/FrameworkMessages.cs.xlf | 2 +- .../Resources/xlf/FrameworkMessages.de.xlf | 2 +- .../Resources/xlf/FrameworkMessages.es.xlf | 2 +- .../Resources/xlf/FrameworkMessages.fr.xlf | 2 +- .../Resources/xlf/FrameworkMessages.it.xlf | 2 +- .../Resources/xlf/FrameworkMessages.ja.xlf | 2 +- .../Resources/xlf/FrameworkMessages.ko.xlf | 2 +- .../Resources/xlf/FrameworkMessages.pl.xlf | 2 +- .../Resources/xlf/FrameworkMessages.pt-BR.xlf | 2 +- .../Resources/xlf/FrameworkMessages.ru.xlf | 2 +- .../Resources/xlf/FrameworkMessages.tr.xlf | 2 +- .../Resources/xlf/FrameworkMessages.zh-Hans.xlf | 2 +- .../Resources/xlf/FrameworkMessages.zh-Hant.xlf | 2 +- 15 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index 2b8096f967..6982430e5b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -649,14 +649,14 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + Testovací metody (metody označené atributem [TestMethod]) by měly respektovat následující rozložení, které MSTest považuje za platné: +– musí být public (nebo internal, pokud je nastaven atribut [assembly: DiscoverInternals]), +– musí být static, +– můžou být obecné, pokud lze odvodit parametry typu a typy argumentů jsou kompatibilní +– nesmí být abstract, +– návratový typ by měl být void, Task nebo ValueTask, +– nesmí být async void, +– nesmí být speciální metodou (finalizační metoda, operátor...). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 3b5d911698..82fd0f8278 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -649,14 +649,14 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu - return type should be 'void', 'Task' or 'ValueTask' - it should not be 'async void' - it should not be a special method (finalizer, operator...). - Test methods, methods marked with the '[TestMethod]' attribute, should respect the following layout to be considered valid by MSTest: -- it should be 'public' (or 'internal' if '[assembly: DiscoverInternals]' attribute is set) -- it should not be 'static' -- it should may be generic as long as type parameters can be inferred and argument types are compatible -- it should not be 'abstract' -- return type should be 'void', 'Task' or 'ValueTask' -- it should not be 'async void' -- it should not be a special method (finalizer, operator...). + Metody testowe, czyli metody oznaczone atrybutem „[TestMethod]”, powinny uwzględniać następujący układ, aby platforma MSTest uznała je za prawidłowe: +— powinny mieć wartość „public” (lub „internal”, jeśli ustawiono atrybut „[assembly: DiscoverInternals]”) +— nie powinny mieć wartości „static” +— mogą być ogólne, o ile można wywnioskować parametry typu i typy argumentów są zgodne +— nie powinny mieć wartości „abstract” +— zwracany typ powinien mieć wartość „void”, „Task” lub „ValueTask” +— nie powinny mieć wartości „async void” +— nie powinny być metodą specjalną (finalizator, operator...). diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf index d5f7ef3690..088671ad85 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf @@ -254,7 +254,7 @@ Skutečnost: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Vlastnost nebo metoda {0} na návratovém typu {1} se nedá přiřadit k „IEnumerable<object[]>“ (ani „IEnumerable<ITuple>“ pro .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf index 11674effd2..92ad58b0e8 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf @@ -254,7 +254,7 @@ Tatsächlich: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Die Eigenschaft oder Methode "{0}" für Rückgabetyp "{1}" kann "IEnumerable<object[]>" nicht zugewiesen werden (auch nicht "IEnumerable<ITuple>" für .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf index 36e0fcaa67..ab6c3262df 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf @@ -254,7 +254,7 @@ Real: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - La propiedad o el método {0} en {1} tipo de valor devuelto no se puede asignar a "IEnumerable<objecto[]>" (ni a "IEnumerable<ITuple>" para .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf index 11bf22ec30..749ee02e87 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf @@ -254,7 +254,7 @@ Réel : {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - La propriété ou la méthode {0} sur le type de retour {1} ne peut pas être attribuée à « IEnumerable<object[]> » (ni à « IEnumerable<ITuple> » pour .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf index 6a0aff7534..9e7406e31d 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf @@ -254,7 +254,7 @@ Effettivo: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - La proprietà o il metodo {0} su {1} tipo restituito non è assegnabile a 'IEnumerable<object[]>' (né a 'IEnumerable<ITuple>' per .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf index 0cb38f531a..989996682a 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf @@ -254,7 +254,7 @@ Actual: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - {1} 戻り値の型のプロパティまたはメソッド {0} は、'IEnumerable<object[]>' (.NET Core の場合は 'IEnumerable<ITuple>' に割り当てできません)。 + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf index bc0c38c646..fe9b7199cb 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf @@ -254,7 +254,7 @@ Actual: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - {1} 반환 형식의 속성 또는 메서드 {0}은(는) 'IEnumerable<object[]>'(.NET Core의 경우 'IEnumerable<ITuple>')에 할당할 수 없습니다. + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf index c4b7f133ea..ec4aaa9fb6 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf @@ -254,7 +254,7 @@ Rzeczywiste: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Właściwości lub metody {0} w zwracanym typie {1} nie można przypisać do elementu „IEnumerable<object[]>” (ani „IEnumerable<ITuple>” dla platformy .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf index 85a180e229..372e307848 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf @@ -254,7 +254,7 @@ Real: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - A propriedade ou método {0} no {1} tipo de retorno não pode ser atribuído a 'IEnumerable<object[]>” (nem 'IEnumerable<ITuple>” para .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf index 8efd601c62..fe3737cf89 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf @@ -254,7 +254,7 @@ Actual: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Свойство или метод {0} возвращаемого типа {1} не могут быть назначены объекту "IEnumerable<[]>" (или "IEnumerable<ITuple>" для .NET Core). + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf index d5b60bb38a..e8e420d934 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf @@ -254,7 +254,7 @@ Gerçekte olan: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - {1} dönüş türündeki {0} özelliği veya yöntemi 'IEnumerable<object[]>' öğesine (veya .NET Core için 'IEnumerable<ITuple>' öğesine) atanamaz. + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf index 8216a4f254..b4c6af2102 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf @@ -254,7 +254,7 @@ Actual: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - {1} 返回类型上的属性或方法 {0} 不能分配给 "IEnumerable<object[]>" (对于 .NET Core,也不能分配给 "IEnumerable<ITuple>")。 + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf index 3b6b0e03a3..d2e361b7fa 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf @@ -254,7 +254,7 @@ Actual: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - {1} 傳回類型上的屬性或方法 {0} 無法指派給 'IEnumerable<object[]>' (或 'IEnumerable<ITuple>' 給 .NET Core) + Property or method {0} on {1} return type is not assignable to 'IEnumerable'. From 49f9c1ffde41fdfb7ab4cb5eaf66c755afa72ec6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 19 Dec 2024 12:09:31 +0100 Subject: [PATCH 148/273] Fix FileLogger tests --- .../Logging/FileLoggerTests.cs | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs index 8d313146f8..53b2d03ecc 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs @@ -1,6 +1,7 @@ // 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.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text; @@ -31,7 +32,7 @@ public sealed class FileLoggerTests : IDisposable private readonly Mock _mockFileSystem = new(); private readonly Mock _mockStream = new(); private readonly Mock _mockFileStreamFactory = new(); - private readonly MemoryStream _memoryStream; + private readonly CustomMemoryStream _memoryStream; public FileLoggerTests() { @@ -41,7 +42,7 @@ public FileLoggerTests() #endif _mockStream.Setup(x => x.Name).Returns(FileName); - _memoryStream = new MemoryStream(); + _memoryStream = new CustomMemoryStream(); _mockStream.Setup(x => x.Stream).Returns(_memoryStream); } @@ -229,4 +230,23 @@ public void Log_WhenAsyncFlush_StreamWriterIsCalledOnlyWhenLogLevelAllowsIt(LogL void IDisposable.Dispose() => _memoryStream.Dispose(); + + private sealed class CustomMemoryStream : MemoryStream + { + private bool _shouldDispose; + + [SuppressMessage("Usage", "CA2215:Dispose methods should call base class dispose", Justification = "Don't dispose")] + protected override void Dispose(bool disposing) + { + if (_shouldDispose) + { + base.Dispose(disposing); + } + else + { + _shouldDispose = true; + return; + } + } + } } From 1c4e496dabc90f7bdf77e9935147b4b9ca0755c2 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 20 Dec 2024 12:11:01 +0100 Subject: [PATCH 149/273] Fix DynamicDataTests (#4399) --- .../Parameterized tests/DynamicDataTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs index d6686c1f01..d04d431f5a 100644 --- a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs +++ b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs @@ -53,9 +53,9 @@ public void ExecuteDynamicDataTests() "MethodWithOverload (\"2\",1)", "MethodWithOverload (1,\"0\")", "MethodWithOverload (2,\"2\")", - "DynamicDataTest_SimpleCollection(0)", - "DynamicDataTest_SimpleCollection(2)", - "DynamicDataTest_SimpleCollection(4)"); + "DynamicDataTest_SimpleCollection (0)", + "DynamicDataTest_SimpleCollection (2)", + "DynamicDataTest_SimpleCollection (4)"); ValidateFailedTestsCount(0); } From c9ab615fa6d8f2b68c0f51fdb3633c1cbda8caa1 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 20 Dec 2024 12:44:12 +0100 Subject: [PATCH 150/273] Fix one more dynamic data test (#4400) --- .../Parameterized tests/DynamicDataTests.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs index f88dae7f1b..44dc75da83 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// 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; @@ -59,9 +59,9 @@ public void ExecuteDynamicDataTests() "MethodWithOverload (\"2\",1)", "MethodWithOverload (1,\"0\")", "MethodWithOverload (2,\"2\")", - "DynamicDataTest_SimpleCollection(0)", - "DynamicDataTest_SimpleCollection(2)", - "DynamicDataTest_SimpleCollection(4)"); + "DynamicDataTest_SimpleCollection (0)", + "DynamicDataTest_SimpleCollection (2)", + "DynamicDataTest_SimpleCollection (4)"); VerifyE2E.FailedTestCount(testResults, 0); } From 1ec111d6f3f3fc09c7e765b0d7b6d3f720374a8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Fri, 20 Dec 2024 14:00:43 +0100 Subject: [PATCH 151/273] Drop dependency to System.ValueTuple (#4398) --- Directory.Packages.props | 2 -- src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj | 4 +--- src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec | 3 --- .../MSTestAdapter.PlatformServices.UnitTests.csproj | 1 - 4 files changed, 1 insertion(+), 9 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 2e0673f29b..2ab7b2733f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -21,7 +21,6 @@ 4.3.1 4.3.1 4.5.4 - 4.5.0 1.1.3-beta1.24423.1 @@ -53,7 +52,6 @@ - diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj index 0174d645d9..ec2308022d 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj @@ -1,4 +1,4 @@ - + @@ -58,7 +58,6 @@ - @@ -86,7 +85,6 @@ - diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec index 549cd6e8c8..fab41babbc 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec @@ -7,17 +7,14 @@ - - - diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/MSTestAdapter.PlatformServices.UnitTests.csproj b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/MSTestAdapter.PlatformServices.UnitTests.csproj index b6f427823c..fc3cf9fa06 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/MSTestAdapter.PlatformServices.UnitTests.csproj +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/MSTestAdapter.PlatformServices.UnitTests.csproj @@ -39,7 +39,6 @@ - From 7b519c8e428c8dbc059b0854bc01632ad5c950e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Fri, 20 Dec 2024 14:01:29 +0100 Subject: [PATCH 152/273] Simplify adapter props and targets (#4397) --- eng/verify-nupkgs.ps1 | 2 +- .../MSTest.TestAdapter.NonWindows.nuspec | 18 ++-- .../MSTest.TestAdapter.csproj | 2 +- .../MSTest.TestAdapter.nuspec | 22 ++--- .../MSTest.TestAdapter.targets | 0 .../MSTest.TestAdapter.targets | 88 ------------------- .../build/uwp/MSTest.TestAdapter.props | 29 +----- .../build/uwp/MSTest.TestAdapter.targets | 34 +++++-- 8 files changed, 44 insertions(+), 151 deletions(-) rename src/Adapter/MSTest.TestAdapter/build/{net => common}/MSTest.TestAdapter.targets (100%) delete mode 100644 src/Adapter/MSTest.TestAdapter/build/netfx-netcore-netstandard/MSTest.TestAdapter.targets diff --git a/eng/verify-nupkgs.ps1 b/eng/verify-nupkgs.ps1 index f13aa658aa..bef6bb99db 100644 --- a/eng/verify-nupkgs.ps1 +++ b/eng/verify-nupkgs.ps1 @@ -22,7 +22,7 @@ function Confirm-NugetPackages { "MSTest.Sdk" = 15; "MSTest.Internal.TestFx.Documentation" = 10; "MSTest.TestFramework" = 148; - "MSTest.TestAdapter" = 82; + "MSTest.TestAdapter" = 74; "MSTest" = 6; "MSTest.Analyzers" = 10; } diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.NonWindows.nuspec b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.NonWindows.nuspec index 9e6505d523..62d93b1975 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.NonWindows.nuspec +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.NonWindows.nuspec @@ -36,48 +36,42 @@ - - + - - + - - + - - + - - + - - + diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj index ec2308022d..3c92cb4996 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj @@ -101,7 +101,7 @@ PreserveNewest - + PreserveNewest diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec index fab41babbc..845b2f2dee 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec @@ -44,8 +44,7 @@ - - + @@ -53,23 +52,20 @@ - - - + - - + @@ -78,32 +74,28 @@ - - + - - + - - + - - + diff --git a/src/Adapter/MSTest.TestAdapter/build/net/MSTest.TestAdapter.targets b/src/Adapter/MSTest.TestAdapter/build/common/MSTest.TestAdapter.targets similarity index 100% rename from src/Adapter/MSTest.TestAdapter/build/net/MSTest.TestAdapter.targets rename to src/Adapter/MSTest.TestAdapter/build/common/MSTest.TestAdapter.targets diff --git a/src/Adapter/MSTest.TestAdapter/build/netfx-netcore-netstandard/MSTest.TestAdapter.targets b/src/Adapter/MSTest.TestAdapter/build/netfx-netcore-netstandard/MSTest.TestAdapter.targets deleted file mode 100644 index 64fb79bf30..0000000000 --- a/src/Adapter/MSTest.TestAdapter/build/netfx-netcore-netstandard/MSTest.TestAdapter.targets +++ /dev/null @@ -1,88 +0,0 @@ - - - - - $(EnableMSTestRunner) - $(EnableMSTestRunner) - false - true - - - - - Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.dll - PreserveNewest - False - - - Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll - PreserveNewest - False - - - Microsoft.TestPlatform.AdapterUtilities.dll - PreserveNewest - False - - - - - - - - - - - - - - - $(MSBuildThisFileDirectory)Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.dll - - - - - - - - - - - - - - - - - - - - - - - %(CurrentUICultureHierarchy.Identity) - - - - - - - %(MSTestV2Files.UICulture)\%(FileName).dll - PreserveNewest - %(FullPath) - False - - - - - diff --git a/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.props b/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.props index 365706e987..259e47a969 100644 --- a/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.props +++ b/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.props @@ -1,30 +1,7 @@ - - - Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.dll - PreserveNewest - False - - - Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll - PreserveNewest - False - - - Microsoft.TestPlatform.AdapterUtilities.dll - PreserveNewest - False - - - - - - - + + true + diff --git a/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.targets b/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.targets index c33b561416..7fac02bef5 100644 --- a/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.targets +++ b/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.targets @@ -1,13 +1,31 @@ - - true - - $(EnableMSTestRunner) - $(EnableMSTestRunner) - false - true - + + + Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.dll + PreserveNewest + False + + + Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.dll + PreserveNewest + False + + + Microsoft.TestPlatform.AdapterUtilities.dll + PreserveNewest + False + + + + + + + @@ -31,7 +31,8 @@ - + Analyzer false @@ -39,6 +40,7 @@ + From ed891e82caf356e2564b20db8d0dadeaa6ecdbab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Fri, 20 Dec 2024 14:10:55 +0100 Subject: [PATCH 154/273] Fix MSTestV2Files msbuild items (#4405) --- .../MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.targets | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.targets b/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.targets index 7fac02bef5..e8d37601f3 100644 --- a/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.targets +++ b/src/Adapter/MSTest.TestAdapter/build/uwp/MSTest.TestAdapter.targets @@ -52,9 +52,6 @@ %(CurrentUICultureHierarchy.Identity) - - %(CurrentUICultureHierarchy.Identity) - From 5cdcbc5e188c86bd86fbb15b5815f3e868518357 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Fri, 20 Dec 2024 14:30:42 +0100 Subject: [PATCH 155/273] Cleanup MSTest.Sdk now that analyzers are deps of framework (#4407) (#4408) --- src/Package/MSTest.Sdk/Sdk/Runner/ClassicEngine.targets | 3 --- src/Package/MSTest.Sdk/Sdk/VSTest/VSTest.targets | 3 --- 2 files changed, 6 deletions(-) diff --git a/src/Package/MSTest.Sdk/Sdk/Runner/ClassicEngine.targets b/src/Package/MSTest.Sdk/Sdk/Runner/ClassicEngine.targets index 2974864941..0ba5bac6c4 100644 --- a/src/Package/MSTest.Sdk/Sdk/Runner/ClassicEngine.targets +++ b/src/Package/MSTest.Sdk/Sdk/Runner/ClassicEngine.targets @@ -43,9 +43,6 @@ - diff --git a/src/Package/MSTest.Sdk/Sdk/VSTest/VSTest.targets b/src/Package/MSTest.Sdk/Sdk/VSTest/VSTest.targets index 39e814bc83..b8f3011a78 100644 --- a/src/Package/MSTest.Sdk/Sdk/VSTest/VSTest.targets +++ b/src/Package/MSTest.Sdk/Sdk/VSTest/VSTest.targets @@ -16,9 +16,6 @@ - From 378afeba899bce83b6e3296a64261aa17690748e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Fri, 20 Dec 2024 15:47:36 +0100 Subject: [PATCH 156/273] Add changelog for 3.7.0 and 1.5.0 (#4409) --- docs/Changelog-Platform.md | 55 ++++++++++++++++ docs/Changelog.md | 130 +++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+) diff --git a/docs/Changelog-Platform.md b/docs/Changelog-Platform.md index 0a54343ef7..b763e9ac39 100644 --- a/docs/Changelog-Platform.md +++ b/docs/Changelog-Platform.md @@ -4,6 +4,61 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) +## [1.5.0] - 2024-12-20 + +See full log [here](https://github.com/microsoft/testfx/compare/v1.4.3...v1.5.0) + +### Added + +* Expose `ExecuteRequestContext` ctor for testability by @MarcoRossignoli in [#3717](https://github.com/microsoft/testfx/pull/3717) +* Add `StandardOutputProperty` and `StandardErrorProperty` by @MarcoRossignoli in [#3748](https://github.com/microsoft/testfx/pull/3748) +* Optimize the server mode discovery workflow by @MarcoRossignoli in [#3877](https://github.com/microsoft/testfx/pull/3877) +* Add yy/mm to the log filename for better ordering by @MarcoRossignoli in [#3894](https://github.com/microsoft/testfx/pull/3894) +* Add logic to read env var for runsettings path in VSTestBridge by @mariam-abdulla in [#3909](https://github.com/microsoft/testfx/pull/3909) +* Support runsettings environment variables by @MarcoRossignoli in [#3918](https://github.com/microsoft/testfx/pull/3918) +* Write standard output and error, and respect execution id by @nohwnd in [#3934](https://github.com/microsoft/testfx/pull/3934) +* Add key only overload to TestMetadataProperty by @Evangelink in [#4041](https://github.com/microsoft/testfx/pull/4041) +* Pass multiple errors by @nohwnd in [#4054](https://github.com/microsoft/testfx/pull/4054) +* Introduce and use warning and error output messages by @Evangelink in [#4217](https://github.com/microsoft/testfx/pull/4217) +* Show running tests by @drognanar in [#4221](https://github.com/microsoft/testfx/pull/4221) + +### Fixed + +* Ensure correct exit code in case of cancellation and add `OnExit` phase for for `IPushOnlyProtocol` by @MarcoRossignoli in [#3820](https://github.com/microsoft/testfx/pull/3820) +* Fix writing dark colors by @nohwnd in [#3825](https://github.com/microsoft/testfx/pull/3825) +* Fix: do not show telemetry banner if no telemetry provider is registered by @Evangelink in [#3862](https://github.com/microsoft/testfx/pull/3862) +* Fix RunSettings/RunConfiguration/ResultsDirectory by @MarcoRossignoli in [#3902](https://github.com/microsoft/testfx/pull/3902) +* Fix concurrency issue in TerminalTestReporter by @mariam-abdulla in [#4229](https://github.com/microsoft/testfx/pull/4229) +* Only push output device messages to Test Explorer, don't push logs by @Youssef1313 in [#4178](https://github.com/microsoft/testfx/pull/4178) +* Fix missing skip reason by @MarcoRossignoli in [#3754](https://github.com/microsoft/testfx/pull/3754) +* Fix skipped Test isn't shown as skipped/not executed in Trx Report by @engyebrahim in [#3773](https://github.com/microsoft/testfx/pull/3773) +* Fix Timed Out Test isn't shown under timeout counter in Trx Report by @engyebrahim in [#3788](https://github.com/microsoft/testfx/pull/3788) +* Fix trx in case of exit code != 0 by @MarcoRossignoli in [#3887](https://github.com/microsoft/testfx/pull/3887) +* Fix SelfRegisteredExtensions type to be internal by @Evangelink in [#3891](https://github.com/microsoft/testfx/pull/3891) +* Display inner exceptions by @Evangelink in [#3920](https://github.com/microsoft/testfx/pull/3920) +* Fix publishing as docker image via /t:PublishContainer by @nohwnd in [#3929](https://github.com/microsoft/testfx/pull/3929) +* Fix conflict with Microsoft.Win32.Registry by @Evangelink in [#3988](https://github.com/microsoft/testfx/pull/3988) +* Fix live output with HotReload (#3983) by @nohwnd in [#3993](https://github.com/microsoft/testfx/pull/3993) +* Fix hangdump not showing tests in progress (#3992) by @nohwnd in [#3999](https://github.com/microsoft/testfx/pull/3999) +* Fix hangdump space in dump path (#3994) by @nohwnd in [#4001](https://github.com/microsoft/testfx/pull/4001) +* Improve error message for incompatible architecture by @Youssef1313 in [#4144](https://github.com/microsoft/testfx/pull/4144) +* StopUpdate in Finally Block by @thomhurst in [#4147](https://github.com/microsoft/testfx/pull/4147) +* Set IsTestingPlatformApplication to true in ClassicEngine.targets by @mariam-abdulla in [#4151](https://github.com/microsoft/testfx/pull/4151) +* Fix displaying progress in non-ansi terminal by @Evangelink in [#4320](https://github.com/microsoft/testfx/pull/4320) + +### Artifacts + +* Microsoft.Testing.Extensions.CrashDump: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.CrashDump/1.5.0) +* Microsoft.Testing.Extensions.HangDump: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.HangDump/1.5.0) +* Microsoft.Testing.Extensions.HotReload: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.HotReload/1.5.0) +* Microsoft.Testing.Extensions.Retry: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.Retry/1.5.0) +* Microsoft.Testing.Extensions.Telemetry: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.Telemetry/1.5.0) +* Microsoft.Testing.Extensions.TrxReport: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.TrxReport/1.5.0) +* Microsoft.Testing.Extensions.TrxReport.Abstractions: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.TrxReport.Abstractions/1.5.0) +* Microsoft.Testing.Extensions.VSTestBridge: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.VSTestBridge/1.5.0) +* Microsoft.Testing.Platform: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Platform/1.5.0) +* Microsoft.Testing.Platform.MSBuild: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Platform.MSBuild/1.5.0) + ## [1.4.3] - 2024-11-12 See full log [here](https://github.com/microsoft/testanywhere/compare/v1.4.2...v1.4.3) diff --git a/docs/Changelog.md b/docs/Changelog.md index 842ec327f1..afc6aac720 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -4,6 +4,136 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) +## [3.7.0] - 2024-12-20 + +See full log [here](https://github.com/microsoft/testfx/compare/v3.6.4...v3.7.0) + +### Added + +* MSTEST0029 code fix by @engyebrahim in [#3747](https://github.com/microsoft/testfx/pull/3747) +* Add codefix for MSTEST0025 by @engyebrahim in [#3756](https://github.com/microsoft/testfx/pull/3756) +* Add codefix for MSTEST0022 by @engyebrahim in [#3770](https://github.com/microsoft/testfx/pull/3770) +* Add codefix for MSTEST0020 by @engyebrahim in [#3798](https://github.com/microsoft/testfx/pull/3798) +* Add code fix for MSTEST0019 by @engyebrahim in [#3812](https://github.com/microsoft/testfx/pull/3812) +* Add support for testconfig.json entries in MSTest by @engyebrahim in [#3872](https://github.com/microsoft/testfx/pull/3872) +* Implement method lookup for dynamic data by @nohwnd in [#3892](https://github.com/microsoft/testfx/pull/3892) +* Add TestData property to the TestContext by @Evangelink in [#4015](https://github.com/microsoft/testfx/pull/4015) +* Add TestException property to the TestContext by @Evangelink in [#4018](https://github.com/microsoft/testfx/pull/4018) +* Add code fix for MSTEST0021 by @engyebrahim in [#3827](https://github.com/microsoft/testfx/pull/3827) +* Add TestDisplayName property to the TestContext by @Evangelink in [#4037](https://github.com/microsoft/testfx/pull/4037) +* Implement codefix for MSTEST0006 (AvoidExpectedException) by @Youssef1313 in [#4038](https://github.com/microsoft/testfx/pull/4038) +* Implement 'Use proper Assert methods' analyzer by @Youssef1313 in [#4052](https://github.com/microsoft/testfx/pull/4052) +* Support ValueTask-returning test methods for all target frameworks by @Youssef1313 in [#4059](https://github.com/microsoft/testfx/pull/4059) +* Support rsp in MTP by @Youssef1313 in [#4072](https://github.com/microsoft/testfx/pull/4072) +* Enable UseProperAssertMethodsAnalyzer by default by @Youssef1313 in [#4076](https://github.com/microsoft/testfx/pull/4076) +* Add property to SDK for Fakes feature by @Evangelink in [#4121](https://github.com/microsoft/testfx/pull/4121) +* Support VS/.NET CLI localization in MTP, and add our own env variable as well by @Youssef1313 in [#4122](https://github.com/microsoft/testfx/pull/4122) +* Implement `--config` for specifying testconfig.json file by @Youssef1313 in [#4124](https://github.com/microsoft/testfx/pull/4124) +* Add mac os on pr pipeline by @Evangelink in [#4155](https://github.com/microsoft/testfx/pull/4155) +* Implement codefix for MSTEST0037: Use proper 'Assert' methods by @Youssef1313 in [#4162](https://github.com/microsoft/testfx/pull/4162) +* Build targeting net9.0 by @Evangelink in [#4167](https://github.com/microsoft/testfx/pull/4167) +* Add a MSTest sample with a program.cs by @Evangelink in [#4201](https://github.com/microsoft/testfx/pull/4201) +* Obsolete public types that should not be public by @Evangelink in [#4208](https://github.com/microsoft/testfx/pull/4208) +* Allow to disable test expansion on implementations of ITestDataSource by @Evangelink in [#4269](https://github.com/microsoft/testfx/pull/4269) +* Display an error when '--maximum-failed-tests' is used with a framewo… by @Evangelink in [#4326](https://github.com/microsoft/testfx/pull/4326) +* Make MSTest.TestFramework depends upon MSTest.Analyzers (#4351) by @Evangelink in [#4361](https://github.com/microsoft/testfx/pull/4361) +* Add support for ValueTuple for all target frameworks (#4360) by @Evangelink in [#4364](https://github.com/microsoft/testfx/pull/4364) +* Support 'TestPropertyAttribute' on test classes by @Youssef1313 in [#4249](https://github.com/microsoft/testfx/pull/4249) +* Support '--maximum-failed-tests' to abort test run when failure threshold is reached by @Youssef1313 in [#4238](https://github.com/microsoft/testfx/pull/4238) + +### Fixed + +* Fix MSTEST0034 doesn't handle ClassCleanupExecutionAttribute by @engyebrahim in [#3741](https://github.com/microsoft/testfx/pull/3741) +* fix code format in readme by @SimonCropp in [#3750](https://github.com/microsoft/testfx/pull/3750) +* Fix running cleanup after first test method by @nohwnd in [#3766](https://github.com/microsoft/testfx/pull/3766) +* Fix timedout test does not fail test run (in ui) by @nohwnd in [#3772](https://github.com/microsoft/testfx/pull/3772) +* Fix typo by @engyebrahim in [#3797](https://github.com/microsoft/testfx/pull/3797) +* MSTEST0018: fix false positive with data member visibility by @Evangelink in [#3866](https://github.com/microsoft/testfx/pull/3866) +* Fix localization of test adapter messages by @nohwnd in [#3867](https://github.com/microsoft/testfx/pull/3867) +* Fix localization info to avoid translating workers and scope by @nohwnd in [#3869](https://github.com/microsoft/testfx/pull/3869) +* Fix resources included in MSTest.TestAdapter nupkg by @Evangelink in [#3874](https://github.com/microsoft/testfx/pull/3874) +* Fix MSTEST0036 is shown for cases where no shadowing happens by @engyebrahim in [#3881](https://github.com/microsoft/testfx/pull/3881) +* Fix MSTest hook to be always generated by @Evangelink in [#3889](https://github.com/microsoft/testfx/pull/3889) +* Fix CollectionAssert.AreEqual fails for list of strings using IEqualityComparer following by @engyebrahim in [#3886](https://github.com/microsoft/testfx/pull/3886) +* Fix CollectionAssert.AreEqual for collection of collections ignores even-items by @engyebrahim in [#3893](https://github.com/microsoft/testfx/pull/3893) +* Fix mstest0036 by @engyebrahim in [#3895](https://github.com/microsoft/testfx/pull/3895) +* Fix casing for event key value by @MarcoRossignoli in [#3915](https://github.com/microsoft/testfx/pull/3915) +* Fix concurrency issue with registering callback on TestRunCancellationToken by @Evangelink in [#3958](https://github.com/microsoft/testfx/pull/3958) +* Fix MSTEST0030 to correctly handle all methods by @Evangelink in [#3973](https://github.com/microsoft/testfx/pull/3973) +* Fix MSTEST0018 FP with IEnumerable by @Evangelink in [#3978](https://github.com/microsoft/testfx/pull/3978) +* Handle trivia properly in PreferTestCleanupOverDisposeFixer by @Youssef1313 in [#4000](https://github.com/microsoft/testfx/pull/4000) +* Only ship TestAdapter related resources by @nohwnd in [#4012](https://github.com/microsoft/testfx/pull/4012) +* Fix IsNonDerived implementation for attribute comparison by @Youssef1313 in [#4024](https://github.com/microsoft/testfx/pull/4024) +* Partially improve CollectionAssert message by @Youssef1313 in [#4027](https://github.com/microsoft/testfx/pull/4027) +* Respect custom ExpectedExceptionBase attribute implementations by @Youssef1313 in [#4045](https://github.com/microsoft/testfx/pull/4045) +* Consider readonly TestContext as valid by @Youssef1313 in [#4053](https://github.com/microsoft/testfx/pull/4053) +* Fix DataSourceAttribute not being discovered with TestDataSourceDiscoveryOption.DuringDiscovery by @Youssef1313 in [#4058](https://github.com/microsoft/testfx/pull/4058) +* Ensure `--minimum-expected-tests` description is localized by @Youssef1313 in [#4125](https://github.com/microsoft/testfx/pull/4125) +* Improve Regex to Reduce Matching Time by @thomhurst in [#4160](https://github.com/microsoft/testfx/pull/4160) +* Refactor WarnOnUnsupportedEntries by @Youssef1313 in [#4182](https://github.com/microsoft/testfx/pull/4182) +* Mark IgnoreAttribute as not inherited by @Youssef1313 in [#4183](https://github.com/microsoft/testfx/pull/4183) +* Small XML doc refreshing by @Youssef1313 in [#4184](https://github.com/microsoft/testfx/pull/4184) +* Fix local warning (and fix typo) by @Youssef1313 in [#4185](https://github.com/microsoft/testfx/pull/4185) +* Fix analyzers package to support VB.NET by @Evangelink in [#4224](https://github.com/microsoft/testfx/pull/4224) +* Preserve message and parameters in MSTEST0025 fixer by @Youssef1313 in [#4301](https://github.com/microsoft/testfx/pull/4301) +* Throw exception if ExpectedExceptionBaseAttribute is applied more than once by @Youssef1313 in [#4359](https://github.com/microsoft/testfx/pull/4359) +* Fix false positive for PreferTestCleanupOverDispose on non-test classes by @Youssef1313 in [#4380](https://github.com/microsoft/testfx/pull/4380) +* Simplify adapter props and targets by @Evangelink in [#4403](https://github.com/microsoft/testfx/pull/4403) +* Don't reference MTP in UWP by @Evangelink in [#4402](https://github.com/microsoft/testfx/pull/4402) +* Fix MSTestV2Files msbuild items by @Evangelink in [#4406](https://github.com/microsoft/testfx/pull/4406) + +### Housekeeping + +* Avoid nuspec when creating M.T.P.MSBuild package by @ViktorHofer in [#4004](https://github.com/microsoft/testfx/pull/4004) +* Move off validate arg from VSTest ObjectModel by @SimonCropp in [#4019](https://github.com/microsoft/testfx/pull/4019) +* [main] Bump System.Management from 8.0.0 to 9.0.0 by @dependabot in [#4136](https://github.com/microsoft/testfx/pull/4136) +* [main] Bump MicrosoftCodeAnalysisAnalyzersVersion from 3.11.0-beta1.24527.2 to 3.11.0-beta1.24574.2 by @dependabot in [#4137](https://github.com/microsoft/testfx/pull/4137) +* Bump version of playwright by @Evangelink in [#4140](https://github.com/microsoft/testfx/pull/4140) +* Update Fakes package version by @drognanar in [#4143](https://github.com/microsoft/testfx/pull/4143) +* Use Polyfill lock by @Evangelink in [#4153](https://github.com/microsoft/testfx/pull/4153) +* Further `System.Threading.Lock` usages by @thomhurst in [#4156](https://github.com/microsoft/testfx/pull/4156) +* Use VS version 17.12 by @Evangelink in [#4176](https://github.com/microsoft/testfx/pull/4176) +* Bump version in samples by @Evangelink in [#4232](https://github.com/microsoft/testfx/pull/4232) +* Sort UnsupportedRunConfigurationSettings by @Youssef1313 in [#4234](https://github.com/microsoft/testfx/pull/4234) +* Fix server mode in playground by @MarcoRossignoli in [#4243](https://github.com/microsoft/testfx/pull/4243) +* Cleanup FailedStates in TrxReportEngine by @Youssef1313 in [#4247](https://github.com/microsoft/testfx/pull/4247) +* [main] Bump MicrosoftCodeAnalysisAnalyzersVersion from 3.11.0-beta1.24574.2 to 3.11.0-beta1.24605.2 by @dependabot in [#4252](https://github.com/microsoft/testfx/pull/4252) +* Use `ValidationResult.ValidTask` instead of `Task.FromResult(ValidationResult.Valid())` by @Youssef1313 in [#4262](https://github.com/microsoft/testfx/pull/4262) +* Avoid Linq allocations from usage of Union by @Youssef1313 in [#4265](https://github.com/microsoft/testfx/pull/4265) +* Avoid repetitive string.Format call for every character of command-line options by @Youssef1313 in [#4264](https://github.com/microsoft/testfx/pull/4264) +* More efficient reflection by @Youssef1313 in [#4263](https://github.com/microsoft/testfx/pull/4263) +* [Performance] Avoid System.Action allocations for test context cancellation by @Youssef1313 in [#4272](https://github.com/microsoft/testfx/pull/4272) +* [Performance] Avoid TraitCollection.AddRange call with empty array by @Youssef1313 in [#4274](https://github.com/microsoft/testfx/pull/4274) +* [Performance] Don't parse the same runsettings for each class in the assembly by @Youssef1313 in [#4270](https://github.com/microsoft/testfx/pull/4270) +* Simplify Ignore handling in IsTestMethodRunnable by @Youssef1313 in [#4281](https://github.com/microsoft/testfx/pull/4281) +* Simplify AttributeComparer.IsDerived by @Youssef1313 in [#4280](https://github.com/microsoft/testfx/pull/4280) +* [Performance] Create dictionary with the right capacity by @Youssef1313 in [#4276](https://github.com/microsoft/testfx/pull/4276) +* [Performance] Avoid repetitive string allocations from TestRunDirectories by @Youssef1313 in [#4275](https://github.com/microsoft/testfx/pull/4275) +* cleanup SourceGeneratedFileOperations by @SimonCropp in [#4285](https://github.com/microsoft/testfx/pull/4285) +* remove some un-used parameters by @SimonCropp in [#4283](https://github.com/microsoft/testfx/pull/4283) +* remove redundant ascending by @SimonCropp in [#4287](https://github.com/microsoft/testfx/pull/4287) +* remove param values where same as default by @SimonCropp in [#4286](https://github.com/microsoft/testfx/pull/4286) +* [Performance] Ensure ReflectionOperations return `Attribute[]` when possible by @Youssef1313 in [#4271](https://github.com/microsoft/testfx/pull/4271) +* leverage out null pattern in IsValidDeploymentItem by @SimonCropp in [#4048](https://github.com/microsoft/testfx/pull/4048) +* Refactor GetTestFromMethod by @Youssef1313 in [#4279](https://github.com/microsoft/testfx/pull/4279) +* Avoid dictionary resizes when the size is approximately known by @Youssef1313 in [#4313](https://github.com/microsoft/testfx/pull/4313) +* Cleanup duplicate logic for timeout handling when creating assembly info by @Youssef1313 in [#4317](https://github.com/microsoft/testfx/pull/4317) +* Use `List` rather than `Collection` by @Youssef1313 in [#4315](https://github.com/microsoft/testfx/pull/4315) +* Cleanup MSTest.Sdk now that analyzers are deps of framework by @Evangelink in [#4407](https://github.com/microsoft/testfx/pull/4407) + +### Artifacts + +* MSTest: [3.7.0](https://www.nuget.org/packages/MSTest/3.7.0) +* MSTest.TestFramework: [3.7.0](https://www.nuget.org/packages/MSTest.TestFramework/3.7.0) +* MSTest.TestAdapter: [3.7.0](https://www.nuget.org/packages/MSTest.TestAdapter/3.7.0) +* MSTest.Analyzers: [3.7.0](https://www.nuget.org/packages/MSTest.Analyzers/3.7.0) +* MSTest.Sdk: [3.7.0](https://www.nuget.org/packages/MSTest.Sdk/3.7.0) +* Microsoft.Testing.Extensions.CrashDump: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.CrashDump/1.5.0) +* Microsoft.Testing.Extensions.HangDump: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.HangDump/1.5.0) +* Microsoft.Testing.Extensions.HotReload: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.HotReload/1.5.0) +* Microsoft.Testing.Extensions.Retry: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.Retry/1.5.0) +* Microsoft.Testing.Extensions.TrxReport: [1.5.0](https://www.nuget.org/packages/Microsoft.Testing.Extensions.TrxReport/1.5.0) + ## [3.6.4] - 2024-12-03 See full log [here](https://github.com/microsoft/testfx/compare/v3.6.3...v3.6.4) From 5e4d2161efa6a74e3bec8d7b7ccf4a15902e5ac1 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sat, 21 Dec 2024 08:17:44 +0100 Subject: [PATCH 157/273] Update issue templates (#4417) --- .github/ISSUE_TEMPLATE/bug-report.md | 2 +- .github/ISSUE_TEMPLATE/feature-request.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 5375827be7..88ed4a361d 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,6 +1,6 @@ --- name: Bug report -about: Create a bug report to help us improve MSTest +about: Create a bug report to help us improve Microsoft.Testing.Platform and MSTest labels: [bug, need-triage] --- diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md index 53121833f4..aa865b4bf0 100644 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -1,6 +1,6 @@ --- name: Feature request -about: Suggest a new feature/idea for MSTest +about: Suggest a new feature/idea for Microsoft.Testing.Platform or MSTest labels: [feature-request, need-triage] --- From 76665ae6fd8b8585d2b6a4717bc237136cb26ed4 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 22 Dec 2024 01:07:02 +1100 Subject: [PATCH 158/273] fix exception nullability in TryGetMessage (#4421) --- .../MSTest.TestAdapter/Extensions/ExceptionExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/ExceptionExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/ExceptionExtensions.cs index 67d14e8b73..318320906b 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/ExceptionExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/ExceptionExtensions.cs @@ -41,7 +41,7 @@ internal static Exception GetRealException(this Exception exception) /// /// An object. /// Exception message. - internal static string TryGetMessage(this Exception exception) + internal static string TryGetMessage(this Exception? exception) { if (exception == null) { From 0e39273eb845c22fee3302959ec5d8775bb0205e Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 23 Dec 2024 10:09:18 +0100 Subject: [PATCH 159/273] Allow AssemblyCleanup/ClassCleanup to have TestContext parameter (#4387) --- .../Execution/ClassCleanupManager.cs | 11 +++- .../Execution/TestAssemblyInfo.cs | 16 ++++- .../Execution/TestClassInfo.cs | 28 ++++++--- .../Execution/TestExecutionManager.cs | 6 +- .../Execution/UnitTestRunner.cs | 30 ++++++---- .../Extensions/MethodInfoExtensions.cs | 8 ++- .../IPlatformServiceProvider.cs | 4 +- .../PlatformServiceProvider.cs | 5 +- .../PublicAPI/PublicAPI.Unshipped.txt | 2 + .../Services/TestContextImplementation.cs | 29 ++++----- .../AssemblyCleanupShouldBeValidAnalyzer.cs | 14 ++++- ...AssemblyInitializeShouldBeValidAnalyzer.cs | 2 +- .../ClassCleanupShouldBeValidAnalyzer.cs | 16 +++-- .../ClassInitializeShouldBeValidAnalyzer.cs | 2 +- .../Helpers/FixtureParameterMode.cs | 22 +++++++ .../MSTest.Analyzers/Helpers/FixtureUtils.cs | 23 ++++++-- .../MSTest.Analyzers/Resources.Designer.cs | 10 ++-- src/Analyzers/MSTest.Analyzers/Resources.resx | 4 +- .../TestCleanupShouldBeValidAnalyzer.cs | 2 +- .../TestInitializeShouldBeValidAnalyzer.cs | 2 +- .../MSTest.Analyzers/xlf/Resources.cs.xlf | 8 +-- .../MSTest.Analyzers/xlf/Resources.de.xlf | 8 +-- .../MSTest.Analyzers/xlf/Resources.es.xlf | 8 +-- .../MSTest.Analyzers/xlf/Resources.fr.xlf | 8 +-- .../MSTest.Analyzers/xlf/Resources.it.xlf | 8 +-- .../MSTest.Analyzers/xlf/Resources.ja.xlf | 8 +-- .../MSTest.Analyzers/xlf/Resources.ko.xlf | 8 +-- .../MSTest.Analyzers/xlf/Resources.pl.xlf | 8 +-- .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 8 +-- .../MSTest.Analyzers/xlf/Resources.ru.xlf | 8 +-- .../MSTest.Analyzers/xlf/Resources.tr.xlf | 8 +-- .../xlf/Resources.zh-Hans.xlf | 8 +-- .../xlf/Resources.zh-Hant.xlf | 8 +-- .../CancellationTests.cs | 59 +++++++++++++++++++ .../InitializeAndCleanupTimeoutTests.cs | 51 ++++++++-------- ...semblyCleanupShouldBeValidAnalyzerTests.cs | 20 +------ .../ClassCleanupShouldBeValidAnalyzerTests.cs | 22 +------ .../Execution/TestClassInfoTests.cs | 27 +++++---- .../PlatformServiceProviderTests.cs | 2 +- .../TestablePlatformServiceProvider.cs | 9 ++- 40 files changed, 327 insertions(+), 203 deletions(-) create mode 100644 src/Analyzers/MSTest.Analyzers/Helpers/FixtureParameterMode.cs diff --git a/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs index 6cd4c78279..99ef44b6d7 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs @@ -2,9 +2,12 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Concurrent; +using System.Globalization; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; +using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; @@ -63,18 +66,20 @@ public void MarkTestComplete(TestMethodInfo testMethodInfo, TestMethod testMetho } } - internal static void ForceCleanup(TypeCache typeCache) + internal static void ForceCleanup(TypeCache typeCache, IDictionary sourceLevelParameters, IMessageLogger logger) { + using var writer = new ThreadSafeStringWriter(CultureInfo.InvariantCulture, "context"); + TestContext testContext = new TestContextImplementation(null, writer, sourceLevelParameters, logger); IEnumerable classInfoCache = typeCache.ClassInfoListWithExecutableCleanupMethods; foreach (TestClassInfo classInfo in classInfoCache) { - classInfo.ExecuteClassCleanup(); + classInfo.ExecuteClassCleanup(testContext); } IEnumerable assemblyInfoCache = typeCache.AssemblyInfoListWithExecutableCleanupMethods; foreach (TestAssemblyInfo assemblyInfo in assemblyInfoCache) { - assemblyInfo.ExecuteAssemblyCleanup(); + assemblyInfo.ExecuteAssemblyCleanup(testContext); } } } diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs index 2af076c1a9..9e688e720c 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs @@ -264,7 +264,7 @@ public void RunAssemblyInitialize(TestContext testContext) /// It is a replacement for RunAssemblyCleanup but as we are in a bug-fix version, we do not want to touch /// public API and so we introduced this method. /// - internal void ExecuteAssemblyCleanup() + internal void ExecuteAssemblyCleanup(TestContext testContext) { if (AssemblyCleanupMethod == null) { @@ -276,8 +276,18 @@ internal void ExecuteAssemblyCleanup() try { AssemblyCleanupException = FixtureMethodRunner.RunWithTimeoutAndCancellation( - () => AssemblyCleanupMethod.InvokeAsSynchronousTask(null), - new CancellationTokenSource(), + () => + { + if (AssemblyCleanupMethod.GetParameters().Length == 0) + { + AssemblyCleanupMethod.InvokeAsSynchronousTask(null); + } + else + { + AssemblyCleanupMethod.InvokeAsSynchronousTask(null, testContext); + } + }, + testContext.CancellationTokenSource, AssemblyCleanupMethodTimeoutMilliseconds, AssemblyCleanupMethod, new AssemblyExecutionContextScope(isCleanup: true), diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index 7fb4dd3131..1fcf49697a 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -491,12 +491,12 @@ UnitTestResult DoRun() try { classCleanupMethod = ClassCleanupMethod; - ClassCleanupException = classCleanupMethod is not null ? InvokeCleanupMethod(classCleanupMethod, BaseClassCleanupMethods.Count) : null; + ClassCleanupException = classCleanupMethod is not null ? InvokeCleanupMethod(classCleanupMethod, BaseClassCleanupMethods.Count, null!) : null; var baseClassCleanupQueue = new Queue(BaseClassCleanupMethods); while (baseClassCleanupQueue.Count > 0 && ClassCleanupException is null) { classCleanupMethod = baseClassCleanupQueue.Dequeue(); - ClassCleanupException = InvokeCleanupMethod(classCleanupMethod, baseClassCleanupQueue.Count); + ClassCleanupException = InvokeCleanupMethod(classCleanupMethod, baseClassCleanupQueue.Count, null!); } IsClassCleanupExecuted = ClassCleanupException is null; @@ -548,7 +548,7 @@ UnitTestResult DoRun() /// This is a replacement for RunClassCleanup but as we are on a bug fix version, we do not want to change /// the public API, hence this method. /// - internal void ExecuteClassCleanup() + internal void ExecuteClassCleanup(TestContext testContext) { if ((ClassCleanupMethod is null && BaseClassCleanupMethods.Count == 0) || IsClassCleanupExecuted) @@ -575,7 +575,7 @@ internal void ExecuteClassCleanup() { if (!ReflectHelper.Instance.IsNonDerivedAttributeDefined(classCleanupMethod.DeclaringType!, false)) { - ClassCleanupException = InvokeCleanupMethod(classCleanupMethod, remainingCleanupCount: BaseClassCleanupMethods.Count); + ClassCleanupException = InvokeCleanupMethod(classCleanupMethod, remainingCleanupCount: BaseClassCleanupMethods.Count, testContext); } } @@ -586,7 +586,7 @@ internal void ExecuteClassCleanup() classCleanupMethod = BaseClassCleanupMethods[i]; if (!ReflectHelper.Instance.IsNonDerivedAttributeDefined(classCleanupMethod.DeclaringType!, false)) { - ClassCleanupException = InvokeCleanupMethod(classCleanupMethod, remainingCleanupCount: BaseClassCleanupMethods.Count - 1 - i); + ClassCleanupException = InvokeCleanupMethod(classCleanupMethod, remainingCleanupCount: BaseClassCleanupMethods.Count - 1 - i, testContext); if (ClassCleanupException is not null) { break; @@ -707,7 +707,7 @@ void DoRun() using LogMessageListener logListener = new(MSTestSettings.CurrentSettings.CaptureDebugTraces); try { - ExecuteClassCleanup(); + ExecuteClassCleanup(testContext.Context); } finally { @@ -745,7 +745,7 @@ void DoRun() } } - private TestFailedException? InvokeCleanupMethod(MethodInfo methodInfo, int remainingCleanupCount) + private TestFailedException? InvokeCleanupMethod(MethodInfo methodInfo, int remainingCleanupCount, TestContext testContext) { TimeoutInfo? timeout = null; if (ClassCleanupMethodTimeoutMilliseconds.TryGetValue(methodInfo, out TimeoutInfo localTimeout)) @@ -754,8 +754,18 @@ void DoRun() } return FixtureMethodRunner.RunWithTimeoutAndCancellation( - () => methodInfo.InvokeAsSynchronousTask(null), - new CancellationTokenSource(), + () => + { + if (methodInfo.GetParameters().Length == 0) + { + methodInfo.InvokeAsSynchronousTask(null); + } + else + { + methodInfo.InvokeAsSynchronousTask(null, testContext); + } + }, + testContext.CancellationTokenSource, timeout, methodInfo, new ClassExecutionContextScope(ClassType, remainingCleanupCount), diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs index 1474062496..b08e8bbac3 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs @@ -415,7 +415,7 @@ private void ExecuteTestsInSource(IEnumerable tests, IRunContext? runC #if !WINDOWS_UWP if (MSTestGracefulStopTestExecutionCapability.Instance.IsStopRequested) { - testRunner.ForceCleanup(); + testRunner.ForceCleanup(sourceLevelParameters!, new RemotingMessageLogger(frameworkHandle)); } #endif @@ -436,6 +436,8 @@ private void ExecuteTestsWithTestRunner( ? tests.OrderBy(t => t.GetManagedType()).ThenBy(t => t.GetManagedMethod()) : tests; + var remotingMessageLogger = new RemotingMessageLogger(testExecutionRecorder); + foreach (TestCase currentTest in orderedTests) { _testRunCancellationToken?.ThrowIfCancellationRequested(); @@ -469,7 +471,7 @@ private void ExecuteTestsWithTestRunner( // testRunner could be in a different AppDomain. We cannot pass the testExecutionRecorder directly. // Instead, we pass a proxy (remoting object) that is marshallable by ref. - UnitTestResult[] unitTestResult = testRunner.RunSingleTest(unitTestElement.TestMethod, testContextProperties, new RemotingMessageLogger(testExecutionRecorder)); + UnitTestResult[] unitTestResult = testRunner.RunSingleTest(unitTestElement.TestMethod, testContextProperties, remotingMessageLogger); PlatformServiceProvider.Instance.AdapterTraceLogger.LogInfo("Executed test {0}", unitTestElement.TestMethod.Name); diff --git a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs index 8f706dd7a8..945c070280 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs @@ -139,13 +139,12 @@ internal UnitTestResult[] RunSingleTest(TestMethod testMethod, IDictionary(testContextProperties); - ITestContext testContext = PlatformServiceProvider.Instance.GetTestContext(testMethod, writer, properties, messageLogger); - testContext.SetOutcome(UTF.UnitTestOutcome.InProgress); + ITestContext testContextForTestExecution = PlatformServiceProvider.Instance.GetTestContext(testMethod, writer, properties, messageLogger, UTF.UnitTestOutcome.InProgress); // Get the testMethod TestMethodInfo? testMethodInfo = _typeCache.GetTestMethodInfo( testMethod, - testContext, + testContextForTestExecution, MSTestSettings.CurrentSettings.CaptureDebugTraces); UnitTestResult[] result; @@ -161,7 +160,9 @@ internal UnitTestResult[] RunSingleTest(TestMethod testMethod, IDictionary classInfoCache = typeCache.ClassInfoListWithExecutableCleanupMethods; foreach (TestClassInfo classInfo in classInfoCache) { - classInfo.ExecuteClassCleanup(); + classInfo.ExecuteClassCleanup(testContext.Context); } IEnumerable assemblyInfoCache = typeCache.AssemblyInfoListWithExecutableCleanupMethods; foreach (TestAssemblyInfo assemblyInfo in assemblyInfoCache) { - assemblyInfo.ExecuteAssemblyCleanup(); + assemblyInfo.ExecuteAssemblyCleanup(testContext.Context); } } finally @@ -364,5 +372,5 @@ private bool IsTestMethodRunnable( return true; } - internal void ForceCleanup() => ClassCleanupManager.ForceCleanup(_typeCache); + internal void ForceCleanup(IDictionary sourceLevelParameters, IMessageLogger logger) => ClassCleanupManager.ForceCleanup(_typeCache, sourceLevelParameters, logger); } diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs index e3efef79a4..647587ff1a 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs @@ -43,10 +43,16 @@ internal static bool HasCorrectClassOrAssemblyCleanupSignature(this MethodInfo m return method is { IsStatic: true, IsPublic: true } && - (method.GetParameters().Length == 0) && + HasCorrectClassOrAssemblyCleanupParameters(method) && method.IsValidReturnType(); } + private static bool HasCorrectClassOrAssemblyCleanupParameters(MethodInfo method) + { + ParameterInfo[] parameters = method.GetParameters(); + return parameters.Length == 0 || (parameters.Length == 1 && parameters[0].ParameterType == typeof(TestContext)); + } + /// /// Verifies that the test Initialize/cleanup has the correct signature. /// diff --git a/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs b/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs index db5390a5b9..c7d48ea95d 100644 --- a/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs @@ -5,6 +5,8 @@ using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; +using UTF = Microsoft.VisualStudio.TestTools.UnitTesting; + namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// @@ -122,5 +124,5 @@ ITestSourceHost CreateTestSourceHost( /// /// This was required for compatibility reasons since the TestContext object that the V1 adapter had for desktop is not .Net Core compliant. /// - ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties, IMessageLogger messageLogger); + ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties, IMessageLogger messageLogger, UTF.UnitTestOutcome outcome); } diff --git a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs index 38d8259a8e..60b2e84709 100644 --- a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs @@ -11,6 +11,8 @@ using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; +using UTF = Microsoft.VisualStudio.TestTools.UnitTesting; + namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// @@ -223,10 +225,11 @@ public ITestSourceHost CreateTestSourceHost( /// /// This was required for compatibility reasons since the TestContext object that the V1 adapter had for desktop is not .Net Core compliant. /// - public ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties, IMessageLogger messageLogger) + public ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties, IMessageLogger messageLogger, UTF.UnitTestOutcome outcome) { var testContextImplementation = new TestContextImplementation(testMethod, writer, properties, messageLogger); TestRunCancellationToken?.Register(CancelDelegate, testContextImplementation); + testContextImplementation.SetOutcome(outcome); return testContextImplementation; } } diff --git a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt index 6569d196f2..e2d86d5ce1 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/Adapter/MSTestAdapter.PlatformServices/PublicAPI/PublicAPI.Unshipped.txt @@ -1,3 +1,5 @@ #nullable enable Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ITestContext.DisplayMessage(Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel messageLevel, string! message) -> void +Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.TestContextImplementation(Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel.ITestMethod? testMethod, System.IO.StringWriter! stringWriter, System.Collections.Generic.IDictionary! properties) -> void override Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.DisplayMessage(Microsoft.VisualStudio.TestTools.UnitTesting.MessageLevel messageLevel, string! message) -> void +*REMOVED*Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.TestContextImplementation.TestContextImplementation(Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.ObjectModel.ITestMethod! testMethod, System.IO.StringWriter! stringWriter, System.Collections.Generic.IDictionary! properties) -> void diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs index 010994cdc4..8d5ea537df 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs @@ -41,11 +41,6 @@ public class TestContextImplementation : TestContext, ITestContext private readonly StringWriter _stringWriter; private readonly ThreadSafeStringWriter? _threadSafeStringWriter; - /// - /// Test Method. - /// - private readonly ITestMethod _testMethod; - /// /// Properties. /// @@ -81,7 +76,7 @@ public class TestContextImplementation : TestContext, ITestContext /// The writer where diagnostic messages are written to. /// Properties/configuration passed in. /// The message logger to use. - internal TestContextImplementation(ITestMethod testMethod, StringWriter stringWriter, IDictionary properties, IMessageLogger messageLogger) + internal TestContextImplementation(ITestMethod? testMethod, StringWriter stringWriter, IDictionary properties, IMessageLogger messageLogger) : this(testMethod, stringWriter, properties) => _messageLogger = messageLogger; @@ -91,27 +86,29 @@ internal TestContextImplementation(ITestMethod testMethod, StringWriter stringWr /// The test method. /// The writer where diagnostic messages are written to. /// Properties/configuration passed in. - public TestContextImplementation(ITestMethod testMethod, StringWriter stringWriter, IDictionary properties) + public TestContextImplementation(ITestMethod? testMethod, StringWriter stringWriter, IDictionary properties) { - DebugEx.Assert(testMethod != null, "TestMethod is not null"); + // testMethod can be null when running ForceCleanup (done when reaching --maximum-failed-tests. DebugEx.Assert(properties != null, "properties is not null"); #if NETFRAMEWORK DebugEx.Assert(stringWriter != null, "StringWriter is not null"); #endif - _testMethod = testMethod; _stringWriter = stringWriter; // Cannot get this type in constructor directly, because all signatures for all platforms need to be the same. _threadSafeStringWriter = stringWriter as ThreadSafeStringWriter; - _properties = new Dictionary(properties) - { - [FullyQualifiedTestClassNameLabel] = _testMethod.FullClassName, - [ManagedTypeLabel] = _testMethod.ManagedTypeName, - [ManagedMethodLabel] = _testMethod.ManagedMethodName, - [TestNameLabel] = _testMethod.Name, - }; + _properties = testMethod is null + ? new Dictionary(properties) + : new Dictionary(properties) + { + [FullyQualifiedTestClassNameLabel] = testMethod.FullClassName, + [ManagedTypeLabel] = testMethod.ManagedTypeName, + [ManagedMethodLabel] = testMethod.ManagedMethodName, + [TestNameLabel] = testMethod.Name, + }; + _testResultFiles = []; } diff --git a/src/Analyzers/MSTest.Analyzers/AssemblyCleanupShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AssemblyCleanupShouldBeValidAnalyzer.cs index df919b1b36..0152e94b5d 100644 --- a/src/Analyzers/MSTest.Analyzers/AssemblyCleanupShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/AssemblyCleanupShouldBeValidAnalyzer.cs @@ -41,15 +41,23 @@ public override void Initialize(AnalysisContext context) { INamedTypeSymbol? taskSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingTasksTask); INamedTypeSymbol? valueTaskSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingTasksValueTask); + INamedTypeSymbol? testContextSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTestContext); bool canDiscoverInternals = context.Compilation.CanDiscoverInternals(); context.RegisterSymbolAction( - context => AnalyzeSymbol(context, assemblyCleanupAttributeSymbol, testClassAttributeSymbol, taskSymbol, valueTaskSymbol, canDiscoverInternals), + context => AnalyzeSymbol(context, assemblyCleanupAttributeSymbol, testClassAttributeSymbol, taskSymbol, valueTaskSymbol, testContextSymbol, canDiscoverInternals), SymbolKind.Method); } }); } - private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol assemblyCleanupAttributeSymbol, INamedTypeSymbol testClassAttributeSymbol, INamedTypeSymbol? taskSymbol, INamedTypeSymbol? valueTaskSymbol, bool canDiscoverInternals) + private static void AnalyzeSymbol( + SymbolAnalysisContext context, + INamedTypeSymbol assemblyCleanupAttributeSymbol, + INamedTypeSymbol testClassAttributeSymbol, + INamedTypeSymbol? taskSymbol, + INamedTypeSymbol? valueTaskSymbol, + INamedTypeSymbol? testContextSymbol, + bool canDiscoverInternals) { var methodSymbol = (IMethodSymbol)context.Symbol; @@ -58,7 +66,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo return; } - if (!methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: true, allowGenericType: false, testContextSymbol: null, testClassAttributeSymbol, fixtureAllowInheritedTestClass: false, out bool isFixable)) + if (!methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: true, allowGenericType: false, FixtureParameterMode.OptionalTestContext, testContextSymbol, testClassAttributeSymbol, fixtureAllowInheritedTestClass: false, out bool isFixable)) { context.ReportDiagnostic(isFixable ? methodSymbol.CreateDiagnostic(Rule, methodSymbol.Name) diff --git a/src/Analyzers/MSTest.Analyzers/AssemblyInitializeShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AssemblyInitializeShouldBeValidAnalyzer.cs index b547b9b71a..2e7ac95c28 100644 --- a/src/Analyzers/MSTest.Analyzers/AssemblyInitializeShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/AssemblyInitializeShouldBeValidAnalyzer.cs @@ -57,7 +57,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo if (methodSymbol.IsAssemblyInitializeMethod(assemblyInitializeAttributeSymbol) && !methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: true, - allowGenericType: false, testContextSymbol, testClassAttributeSymbol, fixtureAllowInheritedTestClass: false, out bool isFixable)) + allowGenericType: false, FixtureParameterMode.MustHaveTestContext, testContextSymbol, testClassAttributeSymbol, fixtureAllowInheritedTestClass: false, out bool isFixable)) { context.ReportDiagnostic(isFixable ? methodSymbol.CreateDiagnostic(Rule, methodSymbol.Name) diff --git a/src/Analyzers/MSTest.Analyzers/ClassCleanupShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/ClassCleanupShouldBeValidAnalyzer.cs index 46fd2292b6..9137406b6b 100644 --- a/src/Analyzers/MSTest.Analyzers/ClassCleanupShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/ClassCleanupShouldBeValidAnalyzer.cs @@ -42,22 +42,30 @@ public override void Initialize(AnalysisContext context) INamedTypeSymbol? taskSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingTasksTask); INamedTypeSymbol? inheritanceBehaviorSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingInheritanceBehavior); INamedTypeSymbol? valueTaskSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingTasksValueTask); + INamedTypeSymbol? testContextSymbol = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTestContext); bool canDiscoverInternals = context.Compilation.CanDiscoverInternals(); context.RegisterSymbolAction( - context => AnalyzeSymbol(context, classCleanupAttributeSymbol, taskSymbol, valueTaskSymbol, inheritanceBehaviorSymbol, testClassAttributeSymbol, canDiscoverInternals), + context => AnalyzeSymbol(context, classCleanupAttributeSymbol, taskSymbol, valueTaskSymbol, inheritanceBehaviorSymbol, testClassAttributeSymbol, testContextSymbol, canDiscoverInternals), SymbolKind.Method); } }); } - private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol classCleanupAttributeSymbol, INamedTypeSymbol? taskSymbol, - INamedTypeSymbol? valueTaskSymbol, INamedTypeSymbol? inheritanceBehaviorSymbol, INamedTypeSymbol testClassAttributeSymbol, bool canDiscoverInternals) + private static void AnalyzeSymbol( + SymbolAnalysisContext context, + INamedTypeSymbol classCleanupAttributeSymbol, + INamedTypeSymbol? taskSymbol, + INamedTypeSymbol? valueTaskSymbol, + INamedTypeSymbol? inheritanceBehaviorSymbol, + INamedTypeSymbol testClassAttributeSymbol, + INamedTypeSymbol? testContextSymbol, + bool canDiscoverInternals) { var methodSymbol = (IMethodSymbol)context.Symbol; bool isInheritanceModeSet = methodSymbol.IsInheritanceModeSet(inheritanceBehaviorSymbol, classCleanupAttributeSymbol); if (methodSymbol.IsClassInitializeMethod(classCleanupAttributeSymbol) && (!methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: true, - allowGenericType: isInheritanceModeSet, testContextSymbol: null, + allowGenericType: isInheritanceModeSet, FixtureParameterMode.OptionalTestContext, testContextSymbol, testClassAttributeSymbol, fixtureAllowInheritedTestClass: true, out bool isFixable) || (!isInheritanceModeSet && methodSymbol.ContainingType.IsAbstract) || (isInheritanceModeSet && methodSymbol.ContainingType.IsSealed))) diff --git a/src/Analyzers/MSTest.Analyzers/ClassInitializeShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/ClassInitializeShouldBeValidAnalyzer.cs index 1b25669209..0ef72850a0 100644 --- a/src/Analyzers/MSTest.Analyzers/ClassInitializeShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/ClassInitializeShouldBeValidAnalyzer.cs @@ -61,7 +61,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo bool isInheritanceModeSet = methodSymbol.IsInheritanceModeSet(inheritanceBehaviorSymbol, classInitializeAttributeSymbol); if (methodSymbol.IsClassInitializeMethod(classInitializeAttributeSymbol) && ((!methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: true, - allowGenericType: isInheritanceModeSet, testContextSymbol, + allowGenericType: isInheritanceModeSet, FixtureParameterMode.MustHaveTestContext, testContextSymbol, testClassAttributeSymbol, fixtureAllowInheritedTestClass: true, out bool isFixable)) || (!isInheritanceModeSet && methodSymbol.ContainingType.IsAbstract) || (isInheritanceModeSet && methodSymbol.ContainingType.IsSealed))) diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/FixtureParameterMode.cs b/src/Analyzers/MSTest.Analyzers/Helpers/FixtureParameterMode.cs new file mode 100644 index 0000000000..e7ff36eade --- /dev/null +++ b/src/Analyzers/MSTest.Analyzers/Helpers/FixtureParameterMode.cs @@ -0,0 +1,22 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace MSTest.Analyzers.Helpers; + +internal enum FixtureParameterMode +{ + /// + /// Indicates that there must not be a TestContext parameter. + /// + MustNotHaveTestContext, + + /// + /// Indicates that a TestContext parameter is mandatory. + /// + MustHaveTestContext, + + /// + /// Indicates that a TestContext parameter is optional. + /// + OptionalTestContext, +} diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/FixtureUtils.cs b/src/Analyzers/MSTest.Analyzers/Helpers/FixtureUtils.cs index 4f79378743..66353d82a6 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/FixtureUtils.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/FixtureUtils.cs @@ -32,6 +32,7 @@ public static bool IsTestCleanupMethod(this IMethodSymbol methodSymbol, INamedTy public static bool HasValidFixtureMethodSignature(this IMethodSymbol methodSymbol, INamedTypeSymbol? taskSymbol, INamedTypeSymbol? valueTaskSymbol, bool canDiscoverInternals, bool shouldBeStatic, bool allowGenericType, + FixtureParameterMode fixtureParameterMode, INamedTypeSymbol? testContextSymbol, INamedTypeSymbol testClassAttributeSymbol, bool fixtureAllowInheritedTestClass, out bool isFixable) { isFixable = false; @@ -60,7 +61,7 @@ public static bool HasValidFixtureMethodSignature(this IMethodSymbol methodSymbo return !methodSymbol.IsGenericMethod && methodSymbol.IsStatic == shouldBeStatic && !methodSymbol.IsAbstract - && HasCorrectParameters(methodSymbol, testContextSymbol) + && HasCorrectParameters(methodSymbol, fixtureParameterMode, testContextSymbol) && methodSymbol.IsPublicAndHasCorrectResultantVisibility(canDiscoverInternals) && HasValidReturnType(methodSymbol, taskSymbol, valueTaskSymbol); } @@ -125,10 +126,22 @@ public static bool IsInheritanceModeSet(this IMethodSymbol methodSymbol, INamedT return false; } - private static bool HasCorrectParameters(IMethodSymbol methodSymbol, INamedTypeSymbol? testContextSymbol) - => testContextSymbol is null - ? methodSymbol.Parameters.Length == 0 - : methodSymbol.Parameters.Length == 1 && SymbolEqualityComparer.Default.Equals(methodSymbol.Parameters[0].Type, testContextSymbol); + private static bool HasCorrectParameters(IMethodSymbol methodSymbol, FixtureParameterMode fixtureParameterMode, INamedTypeSymbol? testContextSymbol) + { + return fixtureParameterMode switch + { + FixtureParameterMode.MustNotHaveTestContext => DoesNotHaveTestContext(methodSymbol), + FixtureParameterMode.MustHaveTestContext => HasTestContext(methodSymbol, testContextSymbol), + FixtureParameterMode.OptionalTestContext => DoesNotHaveTestContext(methodSymbol) || HasTestContext(methodSymbol, testContextSymbol), + _ => throw ApplicationStateGuard.Unreachable(), + }; + + static bool DoesNotHaveTestContext(IMethodSymbol methodSymbol) + => methodSymbol.Parameters.Length == 0; + + static bool HasTestContext(IMethodSymbol methodSymbol, INamedTypeSymbol? testContextSymbol) + => testContextSymbol is not null && methodSymbol.Parameters.Length == 1 && SymbolEqualityComparer.Default.Equals(methodSymbol.Parameters[0].Type, testContextSymbol); + } private static bool HasValidReturnType(IMethodSymbol methodSymbol, INamedTypeSymbol? taskSymbol, INamedTypeSymbol? valueTaskSymbol) => methodSymbol is { ReturnsVoid: true, IsAsync: false } diff --git a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs index ff6155302f..1857d588fb 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs @@ -68,12 +68,10 @@ internal Resources() { ///-it should not be 'async void' ///-it should not be a special method (finalizer, operator...). ///-it should not be generic - ///-it should not take any parameter + ///-it should either not take any parameter, or take a single parameter of type 'TestContext' ///-return type should be 'void', 'Task' or 'ValueTask' /// - ///The type declaring these methods should also respect the following rules: - ///-The type should be a class - ///-The class should [rest of string was truncated]";. + ///The type declaring these methods should also respect the followi [rest of string was truncated]";. /// internal static string AssemblyCleanupShouldBeValidDescription { get { @@ -217,9 +215,9 @@ internal static string AvoidExpectedExceptionAttributeTitle { ///-it should not be 'async void' ///-it should not be a special method (finalizer, operator...). ///-it should not be generic - ///-it should not take any parameter + ///-it should either not take any parameter, or take a single parameter of type 'TestContext' ///-return type should be 'void', 'Task' or 'ValueTask' - ///-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be spec [rest of string was truncated]";. + ///-'InheritanceBehavior.B [rest of string was truncated]";. /// internal static string ClassCleanupShouldBeValidDescription { get { diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx index 41cf404fa7..8f8bdb3481 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.resx +++ b/src/Analyzers/MSTest.Analyzers/Resources.resx @@ -125,7 +125,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -197,7 +197,7 @@ The type declaring these methods should also respect the following rules: -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' diff --git a/src/Analyzers/MSTest.Analyzers/TestCleanupShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/TestCleanupShouldBeValidAnalyzer.cs index 14fa48d1b5..e6efcf42ca 100644 --- a/src/Analyzers/MSTest.Analyzers/TestCleanupShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/TestCleanupShouldBeValidAnalyzer.cs @@ -55,7 +55,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo var methodSymbol = (IMethodSymbol)context.Symbol; if (methodSymbol.IsTestCleanupMethod(testCleanupAttributeSymbol) && !methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: false, - allowGenericType: true, testContextSymbol: null, testClassAttributeSymbol, fixtureAllowInheritedTestClass: true, out bool isFixable)) + allowGenericType: true, FixtureParameterMode.MustNotHaveTestContext, testContextSymbol: null, testClassAttributeSymbol, fixtureAllowInheritedTestClass: true, out bool isFixable)) { context.ReportDiagnostic(isFixable ? methodSymbol.CreateDiagnostic(Rule, methodSymbol.Name) diff --git a/src/Analyzers/MSTest.Analyzers/TestInitializeShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/TestInitializeShouldBeValidAnalyzer.cs index 8a48f29d91..de98ece3e0 100644 --- a/src/Analyzers/MSTest.Analyzers/TestInitializeShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/TestInitializeShouldBeValidAnalyzer.cs @@ -55,7 +55,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo var methodSymbol = (IMethodSymbol)context.Symbol; if (methodSymbol.IsTestInitializeMethod(testInitializeAttributeSymbol) && !methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: false, - allowGenericType: true, testContextSymbol: null, testClassAttributeSymbol, fixtureAllowInheritedTestClass: true, out bool isFixable)) + allowGenericType: true, FixtureParameterMode.MustNotHaveTestContext, testContextSymbol: null, testClassAttributeSymbol, fixtureAllowInheritedTestClass: true, out bool isFixable)) { context.ReportDiagnostic(isFixable ? methodSymbol.CreateDiagnostic(Rule, methodSymbol.Name) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index 6982430e5b..ca63a6457a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Aby byly metody s označením [AssemblyCleanup] platné, musí se řídit následujícím rozložením: + Aby byly metody s označením [AssemblyCleanup] platné, musí se řídit následujícím rozložením: – Nesmí být deklarované pro obecnou třídu. – Musí být public. – Musí být static. @@ -140,7 +140,7 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Aby byly metody s označením [ClassCleanup] platné, musí se řídit následujícím rozložením: + Aby byly metody s označením [ClassCleanup] platné, musí se řídit následujícím rozložením: – Nesmí být deklarované pro obecnou třídu bez nastavení režimu InheritanceBehavior. – Musí být public. – Musí být static. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 37d70ae6af..fd0add94ec 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methoden, die mit „[AssemblyCleanup]“ gekennzeichnet sind, müssen dem folgenden Layout folgen, um gültig zu sein: + Methoden, die mit „[AssemblyCleanup]“ gekennzeichnet sind, müssen dem folgenden Layout folgen, um gültig zu sein: – kann nicht für eine generische Klasse deklariert werden. – muss „public“ sein – muss „static“ sein @@ -140,7 +140,7 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methoden, die mit „[ClassCleanup]“ gekennzeichnet sind, müssen dem folgenden Layout folgen, um gültig zu sein: + Methoden, die mit „[ClassCleanup]“ gekennzeichnet sind, müssen dem folgenden Layout folgen, um gültig zu sein: – kann nicht für eine generische Klasse deklariert werden, ohne dass der Modus „InheritanceBehavior“ auf festgelegt ist. – muss „public“ sein diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 3b9dedcf56..86a34dab9d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Los métodos marcados con '[AssemblyCleanup]' deben seguir el siguiente diseño para ser válidos: + Los métodos marcados con '[AssemblyCleanup]' deben seguir el siguiente diseño para ser válidos: -no se puede declarar en una clase genérica - debería ser 'público' - debería estar 'estático' @@ -140,7 +140,7 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Los métodos marcados con '[ClassCleanup]' deben seguir el siguiente diseño para ser válidos: + Los métodos marcados con '[ClassCleanup]' deben seguir el siguiente diseño para ser válidos: -no se puede declarar en una clase genérica sin el modo 'InheritanceBehavior' establecido - debería ser 'público' - debería estar 'estático' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 9c798da092..a9ba1c9f6a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Les méthodes marquées par « [AssemblyCleanup] » doivent respecter le schéma suivant pour être valides : + Les méthodes marquées par « [AssemblyCleanup] » doivent respecter le schéma suivant pour être valides : -il ne peut pas être déclarée dans une classe générique – il doit être « public » – il doit être « static » @@ -140,7 +140,7 @@ Le type doit être une classe -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Les méthodes marquées par « [ClassCleanup] » doivent respecter le schéma suivant pour être valides : + Les méthodes marquées par « [ClassCleanup] » doivent respecter le schéma suivant pour être valides : -il ne peut pas être déclarée dans une classe générique si le mode ’InheritanceBehavior’ n’est pas activé. – il doit être « public » – il doit être « static » diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index 6fe19f3fd9..ea347a5f3f 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - I metodi contrassegnati con ‘[AssemblyCleanup]’ devono seguire il layout seguente per essere validi: + I metodi contrassegnati con ‘[AssemblyCleanup]’ devono seguire il layout seguente per essere validi: -Non può essere dichiarato in una classe generica - Deve essere 'public' - Deve essere 'static' @@ -140,7 +140,7 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - I metodi contrassegnati con ‘[ClassCleanup]’ devono seguire il layout seguente per essere validi: + I metodi contrassegnati con ‘[ClassCleanup]’ devono seguire il layout seguente per essere validi: -Non può essere dichiarato in una classe generica se la modalità 'InheritanceBehavior' non è impostata - Deve essere 'public' - Deve essere 'static' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index e7e4b11bb7..0df3d78dd4 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[AssemblyCleanup]' でマークされたメソッドを有効にするには、次のレイアウトに従う必要があります: + '[AssemblyCleanup]' でマークされたメソッドを有効にするには、次のレイアウトに従う必要があります: - ジェネリック クラスで宣言することはできません - 'public' である必要があります - 'static' である必要があります @@ -140,7 +140,7 @@ The type declaring these methods should also respect the following rules: -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[ClassCleanup]' でマークされたメソッドを有効にするには、次のレイアウトに従う必要があります: + '[ClassCleanup]' でマークされたメソッドを有効にするには、次のレイアウトに従う必要があります: - 'InheritanceBehavior' モードが設定されていないと、ジェネリック クラスで宣言できません - 'public' である必要があります - 'static' である必要があります diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 50810c8346..a1a3cf53af 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[AssemblyCleanup]'으로 표시된 메서드가 유효하려면 다음 레이아웃을 따라야 합니다. + '[AssemblyCleanup]'으로 표시된 메서드가 유효하려면 다음 레이아웃을 따라야 합니다. -제네릭 클래스에서 선언할 수 없습니다. - 'public'이어야 합니다. - 'static'이어야 합니다. @@ -140,7 +140,7 @@ The type declaring these methods should also respect the following rules: -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[ClassCleanup]'으로 표시된 메서드가 유효하려면 다음 레이아웃을 따라야 합니다. + '[ClassCleanup]'으로 표시된 메서드가 유효하려면 다음 레이아웃을 따라야 합니다. -'InheritanceBehavior' 모드가 설정되지 않은 제네릭 클래스에서 선언할 수 없습니다. - 'public'이어야 합니다. - 'static'이어야 합니다. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 82fd0f8278..63ab26b91a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Metody oznaczone za pomocą [AssemblyCleanup] powinny być zgodne z następującym układem, aby były prawidłowe: + Metody oznaczone za pomocą [AssemblyCleanup] powinny być zgodne z następującym układem, aby były prawidłowe: — nie może być zadeklarowana w klasie ogólnej — powinna być typu „public” — powinna mieć wartość „static” @@ -140,7 +140,7 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Metody oznaczone za pomocą [ClassCleanup] powinny być zgodne z następującym układem, aby były prawidłowe: + Metody oznaczone za pomocą [ClassCleanup] powinny być zgodne z następującym układem, aby były prawidłowe: -nie może być zadeklarowana w klasie ogólnej bez ustawionego trybu „InheritanceBehavior” — powinna być typu „public” — powinna mieć wartość „static” diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 4a1bbdc5d4..15ccef0d90 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Os métodos marcados com “[AssemblyCleanup]” devem seguir o seguinte layout para serem válidos: + Os métodos marcados com “[AssemblyCleanup]” devem seguir o seguinte layout para serem válidos: -não podem ser declarados em uma classe genérica -devem ser "públicos" -devem ser "estáticos" @@ -140,7 +140,7 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Os métodos marcados com “[ClassCleanup]” devem seguir o seguinte layout para serem válidos: + Os métodos marcados com “[ClassCleanup]” devem seguir o seguinte layout para serem válidos: -não podem ser declarados em uma classe genérica sem que o modo “InheritanceBehavior” esteja definido -devem ser "públicos" -devem ser "estáticos" diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index d7b35bb2f2..5d3c70fd8e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Чтобы метод, помеченный "[AssemblyCleanup]", был допустимым, он должен соответствовать следующим правилам: + Чтобы метод, помеченный "[AssemblyCleanup]", был допустимым, он должен соответствовать следующим правилам: – не может быть объявлен для универсального класса ("generic"); – должен быть общедоступным ("public"); – должен быть статическим ("static"); @@ -142,7 +142,7 @@ The type declaring these methods should also respect the following rules: -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -153,7 +153,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Чтобы метод, помеченный "[ClassCleanup]", был допустимым, он должен соответствовать следующим правилам: + Чтобы метод, помеченный "[ClassCleanup]", был допустимым, он должен соответствовать следующим правилам: – не может быть объявлен для универсального класса, если не установлен режим InheritanceBehavior; – должен быть общедоступным ("public"); – должен быть статическим ("static"); diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index fe0feb4cd0..4551d1ce69 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[AssemblyCleanup]' ile işaretlenen yöntemlerin geçerli olması için aşağıdaki düzeni takip etmesi gerekir: + '[AssemblyCleanup]' ile işaretlenen yöntemlerin geçerli olması için aşağıdaki düzeni takip etmesi gerekir: -genel bir sınıfta tanımlanamaz -'public' olmalıdır -'static' olmalıdır @@ -140,7 +140,7 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[ClassCleanup]' ile işaretlenen yöntemlerin geçerli olması için aşağıdaki düzeni takip etmesi gereklidir: + '[ClassCleanup]' ile işaretlenen yöntemlerin geçerli olması için aşağıdaki düzeni takip etmesi gereklidir: -'InheritanceBehavior' modu ayarlanmadan genel bir sınıfta tanımlanamaz -'public' olmalıdır -'static' olmalıdır diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index fde4a6b1f6..7553dea1fc 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - 标记有“[AssemblyCleanup]”的方法应遵循以下布局才会有效: + 标记有“[AssemblyCleanup]”的方法应遵循以下布局才会有效: -不能在泛型类上声明它 - 它应为“public” - 它应为“static” @@ -140,7 +140,7 @@ The type declaring these methods should also respect the following rules: -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - 标记有“[ClassCleanup]”的方法应遵循以下布局才会有效: + 标记有“[ClassCleanup]”的方法应遵循以下布局才会有效: -如果未设置“InheritanceBehavior”模式,则不能在泛型类上声明它 - 它应为“public” - 它应为“static” diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 5e4f919fa6..8d0831bd2a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -10,7 +10,7 @@ -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' The type declaring these methods should also respect the following rules: @@ -19,7 +19,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - 標示為 '[AssemblyCleanup]' 的方法應該遵循下列配置才能有效: + 標示為 '[AssemblyCleanup]' 的方法應該遵循下列配置才能有效: -其不能在泛型類別上宣告 - 其應為 'public' - 其應為 'static' @@ -140,7 +140,7 @@ The type declaring these methods should also respect the following rules: -it should not be 'async void' -it should not be a special method (finalizer, operator...). -it should not be generic --it should not take any parameter +-it should either not take any parameter, or take a single parameter of type 'TestContext' -return type should be 'void', 'Task' or 'ValueTask' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' -'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' @@ -151,7 +151,7 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - 標示 '[ClassCleanup]' 的方法應該遵循下列配置,才會有效: + 標示 '[ClassCleanup]' 的方法應該遵循下列配置,才會有效: -未設定 'InheritanceBehavior' 模式的情況下不能在泛型類別上宣告它 - 其應為 'public' - 其應為 'static' diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs index 6bc078f8eb..36124bf44a 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs @@ -24,6 +24,21 @@ public async Task WhenCancelingTestContextTokenInAssemblyInit_MessageIsAsExpecte testHostResult.AssertOutputContains("Failed!"); } + [TestMethod] + public async Task WhenCancelingTestContextParameterTokenInAssemblyCleanup_MessageIsAsExpected() + { + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() + { + ["ASSEMBLYCLEANUP_CONTEXT_PARAMETER_CANCEL"] = "1", + }); + + // Assert + testHostResult.AssertExitCodeIs(2); + testHostResult.AssertOutputContains("Assembly cleanup method 'UnitTest1.AssemblyCleanup' was canceled"); + testHostResult.AssertOutputContains("Failed!"); + } + [TestMethod] public async Task WhenCancelingTestContextTokenInClassInit_MessageIsAsExpected() { @@ -69,6 +84,21 @@ public async Task WhenCancelingTestContextTokenInTestCleanup_MessageIsAsExpected testHostResult.AssertOutputContains("Failed!"); } + [TestMethod] + public async Task WhenCancelingTestContextParameterTokenInClassCleanup_MessageIsAsExpected() + { + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() + { + ["CLASSCLEANUP_CONTEXT_PARAMETER_CANCEL"] = "1", + }); + + // Assert + testHostResult.AssertExitCodeIs(2); + testHostResult.AssertOutputContains("Class cleanup method 'UnitTest2.ClassCleanup' was canceled"); + testHostResult.AssertOutputContains("Failed!"); + } + [TestMethod] public async Task WhenCancelingTestContextTokenInTestMethod_MessageIsAsExpected() { @@ -133,6 +163,16 @@ public static void AssemblyInitialize(TestContext testContext) } } + [AssemblyCleanup] + public static void AssemblyCleanup(TestContext testContext) + { + if (Environment.GetEnvironmentVariable("ASSEMBLYCLEANUP_CONTEXT_PARAMETER_CANCEL") == "1") + { + testContext.CancellationTokenSource.Cancel(); + testContext.CancellationTokenSource.Token.ThrowIfCancellationRequested(); + } + } + [ClassInitialize] public static void ClassInitialize(TestContext testContext) { @@ -175,6 +215,25 @@ public void TestMethod() } } } + +[TestClass] +public class UnitTest2 +{ + [ClassCleanup] + public static void ClassCleanup(TestContext testContext) + { + if (Environment.GetEnvironmentVariable("CLASSCLEANUP_CONTEXT_PARAMETER_CANCEL") == "1") + { + testContext.CancellationTokenSource.Cancel(); + testContext.CancellationTokenSource.Token.ThrowIfCancellationRequested(); + } + } + + [TestMethod] + public void TestMethod() + { + } +} """; } } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs index 2a78f7726f..49216055dd 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs @@ -197,7 +197,7 @@ public async Task CooperativeCancellation_WhenAssemblyInitTimeoutExpires_StepThr new() { ["TASKDELAY_ASSEMBLYINIT"] = "1" }); testHostResult.AssertOutputContains("AssemblyInit started"); - testHostResult.AssertOutputContains("Assembly initialize method 'TestClass.AssemblyInit' timed out"); + testHostResult.AssertOutputContains("Assembly initialize method 'TestClass.AssemblyInit' timed out after 100ms"); testHostResult.AssertOutputDoesNotContain("AssemblyInit Thread.Sleep completed"); testHostResult.AssertOutputDoesNotContain("AssemblyInit completed"); } @@ -212,7 +212,7 @@ public async Task CooperativeCancellation_WhenAssemblyCleanupTimeoutExpires_Step new() { ["TASKDELAY_ASSEMBLYCLEANUP"] = "1" }); testHostResult.AssertOutputContains("AssemblyCleanup started"); - testHostResult.AssertOutputContains("Assembly cleanup method 'TestClass.AssemblyCleanup' was canceled"); + testHostResult.AssertOutputContains("Assembly cleanup method 'TestClass.AssemblyCleanup' timed out after 100ms"); testHostResult.AssertOutputDoesNotContain("AssemblyCleanup Thread.Sleep completed"); testHostResult.AssertOutputDoesNotContain("AssemblyCleanup completed"); } @@ -227,7 +227,7 @@ public async Task CooperativeCancellation_WhenClassInitTimeoutExpires_StepThrows new() { ["TASKDELAY_CLASSINIT"] = "1" }); testHostResult.AssertOutputContains("ClassInit started"); - testHostResult.AssertOutputContains("Class initialize method 'TestClass.ClassInit' was canceled"); + testHostResult.AssertOutputContains("Class initialize method 'TestClass.ClassInit' timed out after 100ms"); testHostResult.AssertOutputDoesNotContain("ClassInit Thread.Sleep completed"); testHostResult.AssertOutputDoesNotContain("ClassInit completed"); } @@ -242,7 +242,7 @@ public async Task CooperativeCancellation_WhenClassCleanupTimeoutExpires_StepThr new() { ["TASKDELAY_CLASSCLEANUP"] = "1" }); testHostResult.AssertOutputContains("ClassCleanup started"); - testHostResult.AssertOutputContains("Class cleanup method 'TestClass.ClassCleanup' was canceled"); + testHostResult.AssertOutputContains("Class cleanup method 'TestClass.ClassCleanup' timed out after 100ms"); testHostResult.AssertOutputDoesNotContain("ClassCleanup Thread.Sleep completed"); testHostResult.AssertOutputDoesNotContain("ClassCleanup completed"); } @@ -257,7 +257,7 @@ public async Task CooperativeCancellation_WhenTestInitTimeoutExpires_StepThrows( new() { ["TASKDELAY_TESTINIT"] = "1" }); testHostResult.AssertOutputContains("TestInit started"); - testHostResult.AssertOutputContains("Test initialize method 'TestClass.TestInit' was canceled"); + testHostResult.AssertOutputContains("Test initialize method 'TestClass.TestInit' timed out after 100ms"); testHostResult.AssertOutputDoesNotContain("TestInit completed"); } @@ -271,11 +271,14 @@ public async Task CooperativeCancellation_WhenTestCleanupTimeoutExpires_StepThro new() { ["TASKDELAY_TESTCLEANUP"] = "1" }); testHostResult.AssertOutputContains("TestCleanup started"); + // TODO: We would expect to have the following line but that's not the case + // testHostResult.AssertOutputContains("Test cleanup method 'TestClass.TestCleanup' timed out after 100ms"); testHostResult.AssertOutputContains("Test cleanup method 'TestClass.TestCleanup' was canceled"); testHostResult.AssertOutputDoesNotContain("TestCleanup completed"); } [TestMethod] + [Ignore("Move to a different project")] [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenTestMethodTimeoutExpires_StepThrows(string tfm) { @@ -299,7 +302,7 @@ public async Task CooperativeCancellation_WhenAssemblyInitTimeoutExpiresAndUserC new() { ["CHECKTOKEN_ASSEMBLYINIT"] = "1" }); testHostResult.AssertOutputContains("AssemblyInit started"); - testHostResult.AssertOutputContains("Assembly initialize method 'TestClass.AssemblyInit' timed out"); + testHostResult.AssertOutputContains("Assembly initialize method 'TestClass.AssemblyInit' timed out after 100ms"); testHostResult.AssertOutputContains("AssemblyInit Thread.Sleep completed"); testHostResult.AssertOutputDoesNotContain("AssemblyInit completed"); } @@ -314,8 +317,8 @@ public async Task CooperativeCancellation_WhenAssemblyCleanupTimeoutExpiresAndUs new() { ["CHECKTOKEN_ASSEMBLYCLEANUP"] = "1" }); testHostResult.AssertOutputContains("AssemblyCleanup started"); - testHostResult.AssertOutputContains("Assembly cleanup method 'TestClass.AssemblyCleanup' timed out"); testHostResult.AssertOutputContains("AssemblyCleanup Thread.Sleep completed"); + testHostResult.AssertOutputContains("Assembly cleanup method 'TestClass.AssemblyCleanup' timed out after 100ms"); testHostResult.AssertOutputDoesNotContain("AssemblyCleanup completed"); } @@ -329,7 +332,7 @@ public async Task CooperativeCancellation_WhenClassInitTimeoutExpiresAndUserChec new() { ["CHECKTOKEN_CLASSINIT"] = "1" }); testHostResult.AssertOutputContains("ClassInit started"); - testHostResult.AssertOutputContains("Class initialize method 'TestClass.ClassInit' timed out"); + testHostResult.AssertOutputContains("Class initialize method 'TestClass.ClassInit' timed out after 100ms"); testHostResult.AssertOutputContains("ClassInit Thread.Sleep completed"); testHostResult.AssertOutputDoesNotContain("ClassInit completed"); } @@ -344,8 +347,8 @@ public async Task CooperativeCancellation_WhenClassCleanupTimeoutExpiresAndUserC new() { ["CHECKTOKEN_CLASSCLEANUP"] = "1" }); testHostResult.AssertOutputContains("ClassCleanup started"); - testHostResult.AssertOutputContains("Class cleanup method 'TestClass.ClassCleanup' timed out "); testHostResult.AssertOutputContains("ClassCleanup Thread.Sleep completed"); + testHostResult.AssertOutputContains("Class cleanup method 'TestClass.ClassCleanup' timed out after 100ms"); testHostResult.AssertOutputDoesNotContain("ClassCleanup completed"); } @@ -360,7 +363,7 @@ public async Task CooperativeCancellation_WhenTestInitTimeoutExpiresAndUserCheck testHostResult.AssertOutputContains("TestInit started"); testHostResult.AssertOutputDoesNotContain("TestInit completed"); - testHostResult.AssertOutputContains("Test initialize method 'TestClass.TestInit' timed out"); + testHostResult.AssertOutputContains("Test initialize method 'TestClass.TestInit' timed out after 100ms"); } [TestMethod] @@ -374,10 +377,11 @@ public async Task CooperativeCancellation_WhenTestCleanupTimeoutExpiresAndUserCh testHostResult.AssertOutputContains("TestCleanup started"); testHostResult.AssertOutputDoesNotContain("TestCleanup completed"); - testHostResult.AssertOutputContains("Test cleanup method 'TestClass.TestCleanup' timed out"); + testHostResult.AssertOutputContains("Test cleanup method 'TestClass.TestCleanup' timed out after 100ms"); } [TestMethod] + [Ignore("Move to a different project")] [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task CooperativeCancellation_WhenTestMethodTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) { @@ -484,34 +488,25 @@ public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture. [TestClass] public class TestClass { - private static TestContext _assemblyTestContext; - private static TestContext _classTestContext; - [Timeout(100, CooperativeCancellation = true)] [AssemblyInitialize] public static async Task AssemblyInit(TestContext testContext) - { - _assemblyTestContext = testContext; - await DoWork("ASSEMBLYINIT", "AssemblyInit", testContext); - } + => await DoWork("ASSEMBLYINIT", "AssemblyInit", testContext); [Timeout(100, CooperativeCancellation = true)] [AssemblyCleanup] - public static async Task AssemblyCleanup() - => await DoWork("ASSEMBLYCLEANUP", "AssemblyCleanup", _assemblyTestContext); + public static async Task AssemblyCleanup(TestContext testContext) + => await DoWork("ASSEMBLYCLEANUP", "AssemblyCleanup", testContext); [Timeout(100, CooperativeCancellation = true)] [ClassInitialize] public static async Task ClassInit(TestContext testContext) - { - _classTestContext = testContext; - await DoWork("CLASSINIT", "ClassInit", testContext); - } + => await DoWork("CLASSINIT", "ClassInit", testContext); [Timeout(100, CooperativeCancellation = true)] [ClassCleanup(ClassCleanupBehavior.EndOfClass)] - public static async Task ClassCleanup() - => await DoWork("CLASSCLEANUP", "ClassCleanup", _classTestContext); + public static async Task ClassCleanup(TestContext testContext) + => await DoWork("CLASSCLEANUP", "ClassCleanup", testContext); public TestContext TestContext { get; set; } @@ -525,10 +520,10 @@ public async Task TestInit() public async Task TestCleanup() => await DoWork("TESTCLEANUP", "TestCleanup", TestContext); - [Timeout(100, CooperativeCancellation = true)] [TestMethod] public async Task TestMethod() - => await DoWork("TESTMETHOD", "TestMethod", TestContext); + { + } private static async Task DoWork(string envVarSuffix, string stepName, TestContext testContext) { diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyCleanupShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyCleanupShouldBeValidAnalyzerTests.cs index 895d940aad..44aba361df 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyCleanupShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AssemblyCleanupShouldBeValidAnalyzerTests.cs @@ -252,29 +252,13 @@ public async Task WhenAssemblyCleanupHasParameters_Diagnostic() public class MyTestClass { [AssemblyCleanup] - public static void {|#0:AssemblyCleanup|}(TestContext testContext) + public static void AssemblyCleanup(TestContext testContext) { } } """; - string fixedCode = """ - using Microsoft.VisualStudio.TestTools.UnitTesting; - - [TestClass] - public class MyTestClass - { - [AssemblyCleanup] - public static void AssemblyCleanup() - { - } - } - """; - - await VerifyCS.VerifyCodeFixAsync( - code, - VerifyCS.Diagnostic().WithLocation(0).WithArguments("AssemblyCleanup"), - fixedCode); + await VerifyCS.VerifyCodeFixAsync(code, code); } [TestMethod] diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/ClassCleanupShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/ClassCleanupShouldBeValidAnalyzerTests.cs index 5c202bd625..bf5c6d78d3 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/ClassCleanupShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/ClassCleanupShouldBeValidAnalyzerTests.cs @@ -284,7 +284,7 @@ await VerifyCS.VerifyCodeFixAsync( } [TestMethod] - public async Task WhenClassCleanupHasParameters_Diagnostic() + public async Task WhenClassCleanupHasTestContextParameter_NoDiagnostic() { string code = """ using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -293,29 +293,13 @@ public async Task WhenClassCleanupHasParameters_Diagnostic() public class MyTestClass { [ClassCleanup] - public static void {|#0:ClassCleanup|}(TestContext testContext) + public static void ClassCleanup(TestContext testContext) { } } """; - string fixedCode = """ - using Microsoft.VisualStudio.TestTools.UnitTesting; - - [TestClass] - public class MyTestClass - { - [ClassCleanup] - public static void ClassCleanup() - { - } - } - """; - - await VerifyCS.VerifyCodeFixAsync( - code, - VerifyCS.Diagnostic().WithLocation(0).WithArguments("ClassCleanup"), - fixedCode); + await VerifyCS.VerifyCodeFixAsync(code, code); } [TestMethod] diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs index 9fc878852d..356bd5a972 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs @@ -5,6 +5,7 @@ using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Moq; @@ -103,7 +104,7 @@ public void TestClassInfoClassCleanupMethodShouldNotInvokeWhenNoTestClassInitial _testClassInfo.ClassCleanupMethod = typeof(DummyTestClass).GetMethod("ClassCleanupMethod"); _testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); - _testClassInfo.ExecuteClassCleanup(); // call cleanup without calling init + _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary())); // call cleanup without calling init Verify(classCleanupCallCount == 0); } @@ -116,7 +117,7 @@ public void TestClassInfoClassCleanupMethodShouldInvokeWhenTestClassInitializedI _testClassInfo.ClassInitializeMethod = typeof(DummyTestClass).GetMethod("ClassInitializeMethod"); _testClassInfo.RunClassInitialize(_testContext); - _testClassInfo.ExecuteClassCleanup(); // call cleanup without calling init + _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary())); // call cleanup without calling init Verify(classCleanupCallCount == 1); } @@ -130,7 +131,7 @@ public void TestClassInfoClassCleanupMethodShouldInvokeBaseClassCleanupMethodWhe _testClassInfo.BaseClassCleanupMethods.Add(typeof(DummyBaseTestClass).GetMethod("CleanupClassMethod")); _testClassInfo.RunClassInitialize(_testContext); - _testClassInfo.ExecuteClassCleanup(); + _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary())); Verify(classCleanupCallCount == 1); } @@ -420,7 +421,7 @@ public void RunClassCleanupShouldInvokeIfClassCleanupMethod() // Act _testClassInfo.RunClassInitialize(null); - _testClassInfo.ExecuteClassCleanup(); + _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary())); // Assert Verify(classCleanupCallCount == 1); @@ -434,7 +435,7 @@ public void RunClassCleanupShouldNotInvokeIfClassCleanupIsNull() _testClassInfo.ClassCleanupMethod = null; // Act - _testClassInfo.ExecuteClassCleanup(); + _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary())); // Assert Verify(classCleanupCallCount == 0); @@ -448,7 +449,7 @@ public void RunClassCleanupShouldReturnAssertFailureExceptionDetails() // Act _testClassInfo.RunClassInitialize(null); - Exception classCleanupException = VerifyThrows(_testClassInfo.ExecuteClassCleanup); + Exception classCleanupException = VerifyThrows(() => _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary()))); // Assert Verify(classCleanupException.Message.StartsWith("Class Cleanup method DummyTestClass.ClassCleanupMethod failed.", StringComparison.Ordinal)); @@ -464,7 +465,7 @@ public void RunClassCleanupShouldReturnAssertInconclusiveExceptionDetails() // Act _testClassInfo.RunClassInitialize(null); - Exception classCleanupException = VerifyThrows(_testClassInfo.ExecuteClassCleanup); + Exception classCleanupException = VerifyThrows(() => _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary()))); // Assert Verify(classCleanupException.Message.StartsWith("Class Cleanup method DummyTestClass.ClassCleanupMethod failed.", StringComparison.Ordinal)); @@ -480,7 +481,7 @@ public void RunClassCleanupShouldReturnExceptionDetailsOfNonAssertExceptions() // Act _testClassInfo.RunClassInitialize(null); - Exception classCleanupException = VerifyThrows(_testClassInfo.ExecuteClassCleanup); + Exception classCleanupException = VerifyThrows(() => _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary()))); // Assert Verify(classCleanupException.Message.StartsWith("Class Cleanup method DummyTestClass.ClassCleanupMethod failed.", StringComparison.Ordinal)); @@ -498,7 +499,7 @@ public void RunBaseClassCleanupWithNoDerivedClassCleanupShouldReturnExceptionDet // Act _testClassInfo.RunClassInitialize(null); - Exception classCleanupException = VerifyThrows(_testClassInfo.ExecuteClassCleanup); + Exception classCleanupException = VerifyThrows(() => _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary()))); // Assert Verify(classCleanupException.Message.StartsWith("Class Cleanup method DummyBaseTestClass.CleanupClassMethod failed.", StringComparison.Ordinal)); @@ -516,7 +517,7 @@ public void RunBaseClassCleanupEvenIfThereIsNoDerivedClassCleanup() _testClassInfo.BaseClassCleanupMethods.Add(baseClassCleanupMethod); // Act - _testClassInfo.ExecuteClassCleanup(); + _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary())); // Assert Verify(_testClassInfo.HasExecutableCleanupMethod); @@ -524,7 +525,7 @@ public void RunBaseClassCleanupEvenIfThereIsNoDerivedClassCleanup() // Act 2 _testClassInfo.RunClassInitialize(null); - _testClassInfo.ExecuteClassCleanup(); + _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary())); // Assert 2 Verify(_testClassInfo.HasExecutableCleanupMethod); @@ -532,7 +533,7 @@ public void RunBaseClassCleanupEvenIfThereIsNoDerivedClassCleanup() Verify(classCleanupCallCount == 1, "DummyBaseTestClass.CleanupClassMethod call count"); // Act 3 - _testClassInfo.ExecuteClassCleanup(); + _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary())); // Assert 3 Verify(_testClassInfo.HasExecutableCleanupMethod); @@ -548,7 +549,7 @@ public void RunClassCleanupShouldThrowTheInnerMostExceptionWhenThereAreMultipleN _testClassInfo.ClassCleanupMethod = typeof(DummyTestClass).GetMethod("ClassCleanupMethod"); _testClassInfo.RunClassInitialize(null); - Exception classCleanupException = VerifyThrows(_testClassInfo.ExecuteClassCleanup); + Exception classCleanupException = VerifyThrows(() => _testClassInfo.ExecuteClassCleanup(new TestContextImplementation(null, new StringWriter(), new Dictionary()))); Verify(classCleanupException.Message.StartsWith("Class Cleanup method DummyTestClass.ClassCleanupMethod failed. Error Message: System.InvalidOperationException: I fail..", StringComparison.Ordinal)); Verify(classCleanupException.Message.Contains("at Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestClassInfoTests.FailingStaticHelper..cctor()")); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/PlatformServiceProviderTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/PlatformServiceProviderTests.cs index 7109a8a7bf..9f85231bbf 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/PlatformServiceProviderTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/PlatformServiceProviderTests.cs @@ -64,7 +64,7 @@ public void GetTestContextShouldReturnAValidTestContext() testMethod.Setup(tm => tm.Name).Returns("M"); // Act. - PlatformServices.Interface.ITestContext testContext = PlatformServiceProvider.Instance.GetTestContext(testMethod.Object, writer, properties, null); + PlatformServices.Interface.ITestContext testContext = PlatformServiceProvider.Instance.GetTestContext(testMethod.Object, writer, properties, null, default); // Assert. Verify(testContext.Context.FullyQualifiedTestClassName == "A.C.M"); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs b/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs index 96627190a9..8c6355c3e8 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs @@ -11,6 +11,8 @@ using Moq; +using UTF = Microsoft.VisualStudio.TestTools.UnitTesting; + namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.TestableImplementations; internal class TestablePlatformServiceProvider : IPlatformServiceProvider @@ -126,7 +128,12 @@ public IReflectionOperations2 ReflectionOperations public TestRunCancellationToken TestRunCancellationToken { get; set; } - public ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties, IMessageLogger messageLogger) => new TestContextImplementation(testMethod, writer, properties, messageLogger); + public ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties, IMessageLogger messageLogger, UTF.UnitTestOutcome outcome) + { + var testContextImpl = new TestContextImplementation(testMethod, writer, properties, messageLogger); + testContextImpl.SetOutcome(outcome); + return testContextImpl; + } public ITestSourceHost CreateTestSourceHost(string source, TestPlatform.ObjectModel.Adapter.IRunSettings runSettings, TestPlatform.ObjectModel.Adapter.IFrameworkHandle frameworkHandle) => MockTestSourceHost.Object; From 6a91b2738139f2079d18bb51620fb6d824147e5e Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Mon, 23 Dec 2024 01:24:34 -0800 Subject: [PATCH 160/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2606972 --- .../Resources/xlf/Resource.cs.xlf | 2 +- .../Resources/xlf/Resource.de.xlf | 2 +- .../Resources/xlf/Resource.es.xlf | 2 +- .../Resources/xlf/Resource.fr.xlf | 2 +- .../Resources/xlf/Resource.it.xlf | 2 +- .../Resources/xlf/Resource.ja.xlf | 2 +- .../Resources/xlf/Resource.ko.xlf | 2 +- .../Resources/xlf/Resource.pl.xlf | 2 +- .../Resources/xlf/Resource.pt-BR.xlf | 2 +- .../Resources/xlf/Resource.ru.xlf | 2 +- .../Resources/xlf/Resource.tr.xlf | 2 +- .../Resources/xlf/Resource.zh-Hans.xlf | 2 +- .../Resources/xlf/Resource.zh-Hant.xlf | 2 +- .../MSTest.Analyzers/xlf/Resources.cs.xlf | 70 +++++++++--------- .../MSTest.Analyzers/xlf/Resources.de.xlf | 71 +++++++++--------- .../MSTest.Analyzers/xlf/Resources.es.xlf | 70 +++++++++--------- .../MSTest.Analyzers/xlf/Resources.fr.xlf | 70 +++++++++--------- .../MSTest.Analyzers/xlf/Resources.it.xlf | 70 +++++++++--------- .../MSTest.Analyzers/xlf/Resources.ja.xlf | 70 +++++++++--------- .../MSTest.Analyzers/xlf/Resources.ko.xlf | 70 +++++++++--------- .../MSTest.Analyzers/xlf/Resources.pl.xlf | 70 +++++++++--------- .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 70 +++++++++--------- .../MSTest.Analyzers/xlf/Resources.ru.xlf | 72 +++++++++---------- .../MSTest.Analyzers/xlf/Resources.tr.xlf | 70 +++++++++--------- .../xlf/Resources.zh-Hans.xlf | 70 +++++++++--------- .../xlf/Resources.zh-Hant.xlf | 70 +++++++++--------- 26 files changed, 468 insertions(+), 471 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf index bb36585c60..75dc16e953 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf @@ -63,7 +63,7 @@ byl však přijat tento počet argumentů: {4} s typy {5}. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + Dynamický zdroj dat '{0}' v typu '{1}' by měl existovat a být vlastností nebo metodou. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf index ac1b95cffd..0e8d214715 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf @@ -63,7 +63,7 @@ aber empfing {4} Argument(e) mit den Typen „{5}“. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + Die dynamische Datenquelle '{0}' im Typ '{1}' muss vorhanden sein und eine Eigenschaft oder Methode sein. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf index fb7c182bca..395a71c5bd 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf @@ -63,7 +63,7 @@ pero recibió {4} argumento(s), con los tipos "{5}". The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + El origen de datos dinámico '{0}' en el tipo '{1}' debe existir y ser una propiedad o un método. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf index e12d6a019a..b553cacfa8 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf @@ -63,7 +63,7 @@ mais a reçu {4} argument(s), avec les types « {5} ». The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + La source de données dynamique '{0}' dans le type '{1}' doit exister et être une propriété ou une méthode. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf index 5269afce00..6c5116a95b 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf @@ -63,7 +63,7 @@ ma ha ricevuto {4} argomenti, con tipi "{5}". The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + L'origine dati dinamica '{0}' nel tipo '{1}' deve esistere ed essere una proprietà o un metodo. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf index 561c093562..01bed386e8 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf @@ -64,7 +64,7 @@ but received {4} argument(s), with types '{5}'. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + 型 '{1}' の動的データ ソース '{0}' は、プロパティまたはメソッドである必要があります。 diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf index 062afab0ae..f5710bb237 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf @@ -63,7 +63,7 @@ but received {4} argument(s), with types '{5}'. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + '{1}' 형식의 동적 데이터 원본 '{0}' 존재하며 속성 또는 메서드여야 합니다. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf index f50f03f8ef..8e18340251 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf @@ -63,7 +63,7 @@ ale liczba odebranych argumentów to {4} z typami „{5}”. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + Dynamiczne źródło danych '{0}' w typie '{1}' powinno istnieć i być właściwością lub metodą. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf index 51e1317f57..d8232e39e2 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf @@ -63,7 +63,7 @@ mas {4} argumentos recebidos, com tipos '{5}'. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + A fonte de dados dinâmica '{0}' no tipo '{1}' deve existir e ser uma propriedade ou um método. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf index a9c4bf409b..ad1b9f9366 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf @@ -63,7 +63,7 @@ but received {4} argument(s), with types '{5}'. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + Динамический источник '{0}' в типе '{1}' должен существовать и быть свойством или методом. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf index 39bb0c917c..6854ff4926 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf @@ -63,7 +63,7 @@ ancak, '{5}' türüyle {4} argüman aldı. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + Dinamik veri kaynağı '{0}' türdeki '{1}' bir özellik veya yöntem olmalıdır. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf index 347c203c37..9f451c98c1 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf @@ -63,7 +63,7 @@ but received {4} argument(s), with types '{5}'. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + 类型 '{1}' 中的动态数据源 '{0}' 应存在,并且应为属性或方法。 diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf index cb94ea042b..2dce2845f5 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf @@ -63,7 +63,7 @@ but received {4} argument(s), with types '{5}'. The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. - The dynamic data source '{0}' in type '{1}' should exist and be a property or a method. + 類型 '{1}' 中的動態數據源 '{0}' 應該存在,而且必須是屬性或方法。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index ca63a6457a..36b7df5ccb 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Aby byly metody s označením [AssemblyCleanup] platné, musí se řídit následujícím rozložením: -– Nesmí být deklarované pro obecnou třídu. -– Musí být public. -– Musí být static. -– Nesmí být async void. -– Nesmí být speciální metodou (finalizační metoda, operátor...). -– Nesmí být obecné. -– Nesmí přijímat žádný parametr. -– Návratový typ musí být void, Task nebo ValueTask. + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -Typ deklarující tyto metody by měl také respektovat následující pravidla: -– Typ by měl být třída. -– Třída by měla být public nebo internal (pokud testovací projekt používá atribut [DiscoverInternals]). -– Třída by neměla být static. -– Třída by měla být označena atributem [TestClass] (nebo odvozeným atributem). -– Třída by neměla být obecná. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Aby byly metody s označením [ClassCleanup] platné, musí se řídit následujícím rozložením: -– Nesmí být deklarované pro obecnou třídu bez nastavení režimu InheritanceBehavior. -– Musí být public. -– Musí být static. -– Nesmí být async void. -– Nesmí být speciální metodou (finalizační metoda, operátor...). -– Nesmí být obecné. -– Nesmí přijímat žádný parametr. -– Návratový typ musí být void, Task nebo ValueTask. -– V případě třídy abstract by měl být zadán parametr atributu InheritanceBehavior.BeforeEachDerivedClass. -– V případě třídy sealed by neměl být zadán parametr atributu InheritanceBehavior.BeforeEachDerivedClass. + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -Typ deklarující tyto metody by měl také respektovat následující pravidla: -– Typ by měl být třída. -– Třída by měla být public nebo internal (pokud testovací projekt používá atribut [DiscoverInternals]). -– Třída by neměla být static. -– Pokud je třída sealed, měla by být označena atributem [TestClass] (nebo odvozeným atributem). -– Třída by neměla být obecná. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -364,17 +364,17 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' člen {0}.{1} je metoda, takže byste měli použít DynamicDataSourceType.AutoDetect nebo DynamicDataSourceType.Method (automatické zjišťování je výchozí, pokud není explicitně zadáno, a doporučuje se) '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' člen {0}.{1} není vlastnost ani metoda. Jsou podporovány pouze vlastnosti a metody. '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' člen {0}.{1} je vlastnost, takže byste měli použít DynamicDataSourceType.AutoDetect nebo DynamicDataSourceType.Property (automatické zjišťování je výchozí, pokud není explicitně zadáno, a doporučuje se) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index fd0add94ec..cae9cbbd09 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methoden, die mit „[AssemblyCleanup]“ gekennzeichnet sind, müssen dem folgenden Layout folgen, um gültig zu sein: -– kann nicht für eine generische Klasse deklariert werden. -– muss „public“ sein -– muss „static“ sein -– darf nicht „async void“ sein -– darf keine spezielle Methode sein (Finalizer, Operator...) -– darf nicht „generic“ sein -– darf keinen Parameter annehmen -– der Rückgabetyp muss „void“, „Task“ oder „ValueTask“ sein + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachten: -– Der Typ sollte eine Klasse sein. -– Die Klasse muss „public“ oder „internal“ sein (wenn das Testprojekt das Attribut „[DiscoverInternals]“ verwendet) -– Die Klasse darf nicht „static“ sein. -– Die Klasse muss mit „[TestClass]“ (oder einem abgeleiteten Attribut) markiert werden. -- die Klasse darf nicht generisch sein. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,25 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methoden, die mit „[ClassCleanup]“ gekennzeichnet sind, müssen dem folgenden Layout folgen, um gültig zu sein: -– kann nicht für eine generische Klasse deklariert werden, ohne dass der Modus „InheritanceBehavior“ auf - festgelegt ist. -– muss „public“ sein -– muss „static“ sein -– darf nicht „async void“ sein -– darf keine spezielle Methode sein (Finalizer, Operator...) -– darf nicht „generic“ sein -– darf keinen Parameter annehmen -– der Rückgabetyp muss „void“, „Task“ oder „ValueTask“ sein -– der Attributparameter „InheritanceBehavior.BeforeEachDerivedClass“ sollte angegeben werden, wenn die Klasse „abstract“ ist -– der Attributparameter „InheritanceBehavior.BeforeEachDerivedClass“ sollte angegeben werden, wenn die Klasse „sealed“ ist. + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachten: -– Der Typ sollte eine Klasse sein. -– Die Klasse muss „public“ oder „internal“ sein (wenn das Testprojekt das Attribut „[DiscoverInternals]“ verwendet) -– Die Klasse darf nicht „static“ sein. -– Wenn die Klasse „sealed“ ist, sollte sie mit „[TestClass]“ (oder einem abgeleiteten Attribut) markiert werden. -- die Klasse darf nicht generisch sein. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -366,17 +365,17 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' Member "{0}.{1}" ist eine Methode, daher sollten Sie "DynamicDataSourceType.AutoDetect" oder "DynamicDataSourceType.Method" verwenden (die automatische Erkennung ist der Standardwert, wenn sie nicht explizit angegeben wird und empfohlen wird). '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' Member "{0}.{1}" ist weder eine Eigenschaft noch eine Methode. Nur Eigenschaften und Methoden werden unterstützt. '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' Member "{0}.{1}" ist eine Eigenschaft, daher sollten Sie "DynamicDataSourceType.AutoDetect" oder "DynamicDataSourceType.Property" verwenden (die automatische Erkennung ist der Standardwert, wenn sie nicht explizit angegeben wird und empfohlen wird). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 86a34dab9d..8f749d02b8 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Los métodos marcados con '[AssemblyCleanup]' deben seguir el siguiente diseño para ser válidos: --no se puede declarar en una clase genérica -- debería ser 'público' -- debería estar 'estático' -- no debería ser 'async void' --no debe ser un método especial (finalizador, operador...). --no debe ser genérico --no debe tomar ningún parámetro -- El tipo de valor devuelto debe ser 'void', 'Task' o 'ValueTask' + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -El tipo que declara estos métodos también debe respetar las reglas siguientes: --El tipo debe ser una clase --La clase debe ser 'public' o 'internal' (si el proyecto de prueba usa el atributo '[DiscoverInternals]') --La clase no debe ser 'statico' --La clase debe marcarse con '[TestClass]' (o un atributo derivado) --la clase no debe ser genérica. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Los métodos marcados con '[ClassCleanup]' deben seguir el siguiente diseño para ser válidos: --no se puede declarar en una clase genérica sin el modo 'InheritanceBehavior' establecido -- debería ser 'público' -- debería estar 'estático' -- no debería ser 'async void' --no debe ser un método especial (finalizador, operador...). --no debe ser genérico --no debe tomar ningún parámetro -- El tipo de valor devuelto debe ser 'void', 'Task' o 'ValueTask' -Se debe especificar el parámetro de atributo -'InheritanceBehavior.BeforeEachDerivedClass' si la clase es 'abstract' -- No se debe especificar el parámetro del atributo 'InheritanceBehavior.BeforeEachDerivedClass' si la clase es 'sellada' + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -El tipo que declara estos métodos también debe respetar las reglas siguientes: --El tipo debe ser una clase --La clase debe ser 'public' o 'internal' (si el proyecto de prueba usa el atributo '[DiscoverInternals]') --La clase no debe ser 'static' --Si la clase es 'sealed', debe marcarse con '[TestClass]' (o un atributo derivado) --la clase no debe ser genérica. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -364,17 +364,17 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' miembro '{0}.{1}' es un método, por lo que debe usar 'DynamicDataSourceType.AutoDetect' o 'DynamicDataSourceType.Method' (la detección automática es el valor predeterminado cuando no se especifica explícitamente y se recomienda) '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' miembro '{0}.{1}' no es una propiedad ni un método. Solo se admiten propiedades y métodos. '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' miembro '{0}.{1}' es una propiedad, por lo que debe usar 'DynamicDataSourceType.AutoDetect' o 'DynamicDataSourceType.Property' (la detección automática es el valor predeterminado cuando no se especifica explícitamente y se recomienda) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index a9ba1c9f6a..224d7f41e6 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Les méthodes marquées par « [AssemblyCleanup] » doivent respecter le schéma suivant pour être valides : --il ne peut pas être déclarée dans une classe générique -– il doit être « public » -– il doit être « static » -– il ne doit pas être « async void » -– Il ne doit pas s’agir d’une méthode spéciale (finaliseur, opérateur...). -– il ne doit pas être générique -– il ne doit accepter aucun paramètre -- le type de retour doit être « vide », « Task » ou « ValueTask » + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -Le type déclarant ces méthodes doit également respecter les règles suivantes : -Le type doit être une classe --La classe doit être « public » ou « internal » (si le projet de test utilise l’attribut ’[DiscoverInternals]’) --La classe ne doit pas être» ’static » --La classe doit être marquée par « [TestClass] » (ou un attribut dérivé). --la classe ne doit pas être générique. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Les méthodes marquées par « [ClassCleanup] » doivent respecter le schéma suivant pour être valides : --il ne peut pas être déclarée dans une classe générique si le mode ’InheritanceBehavior’ n’est pas activé. -– il doit être « public » -– il doit être « static » -– il ne doit pas être « async void » -– Il ne doit pas s’agir d’une méthode spéciale (finaliseur, opérateur...). -– il ne doit pas être générique -– il ne doit accepter aucun paramètre -- le type de retour doit être « vide », « Task » ou « ValueTask » -- « InheritanceBehavior.BeforeEachDerivedClass » doit être spécifié si la classe est « abstract » --Le paramètre d’attribut « InheritanceBehavior.BeforeEachDerivedClass » ne doit pas être spécifié si la classe est « scellée » + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -Le type déclarant ces méthodes doit également respecter les règles suivantes : -Le type doit être une classe --La classe doit être « public » ou « internal » (si le projet de test utilise l’attribut ’[DiscoverInternals]’) --La classe ne doit pas être « static » --Si la classe est « sealed », elle doit être marquée avec « [TestClass] » (ou un attribut dérivé). --la classe ne doit pas être générique. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -364,17 +364,17 @@ Le type doit être une classe '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' membre ' {0}.{1}' est une méthode, vous devez donc utiliser 'DynamicDataSourceType.AutoDetect' ou 'DynamicDataSourceType.Method' (la détection automatique est la valeur par défaut quand elle n’est pas spécifiée explicitement et est recommandée) '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' membre '{0}.{1}' n’est ni une propriété ni une méthode. Seules les propriétés et les méthodes sont prises en charge. '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' membre « {0}.{1} » est une propriété, vous devez donc utiliser « DynamicDataSourceType.AutoDetect » ou « DynamicDataSourceType.Property » (la détection automatique est la valeur par défaut lorsqu’elle n’est pas spécifiée explicitement et est recommandée) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index ea347a5f3f..df5871d21a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - I metodi contrassegnati con ‘[AssemblyCleanup]’ devono seguire il layout seguente per essere validi: --Non può essere dichiarato in una classe generica -- Deve essere 'public' -- Deve essere 'static' -- Non deve essere 'async void' -- Non deve essere un metodo speciale (finalizzatore, operatore...). -- Non deve essere generico -- Non deve accettare alcun parametro -- il tipo restituito deve essere 'void', 'Task' o 'ValueTask' + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: --Il tipo deve essere una classe --La classe deve essere 'public' o 'internal' (se il progetto di test usa l'attributo '[DiscoverInternals]') --La classe non deve essere 'static' --La classe deve essere contrassegnata con '[TestClass]' (o un attributo derivato). --La classe non deve essere generica. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - I metodi contrassegnati con ‘[ClassCleanup]’ devono seguire il layout seguente per essere validi: --Non può essere dichiarato in una classe generica se la modalità 'InheritanceBehavior' non è impostata -- Deve essere 'public' -- Deve essere 'static' -- Non deve essere 'async void' -- Non deve essere un metodo speciale (finalizzatore, operatore...). -- Non deve essere generico -- Non deve accettare alcun parametro -- il tipo restituito deve essere 'void', 'Task' o 'ValueTask' -- È necessario specificare il parametro dell'attributo 'InheritanceBehavior.BeforeEachDerivedClass' se la classe è 'abstract' -- Non è necessario specificare il parametro dell'attributo 'InheritanceBehavior.BeforeEachDerivedClass' se la classe è 'sealed' + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: --Il tipo deve essere una classe --La classe deve essere 'public' o 'internal' (se il progetto di test usa l'attributo '[DiscoverInternals]') --La classe non deve essere 'static' --Se la classe è 'sealed', deve essere contrassegnata con '[TestClass]' (o un attributo derivato) --La classe non deve essere generica. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -364,17 +364,17 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' membro '{0}.{1}' è un metodo, quindi è consigliabile usare 'DynamicDataSourceType.AutoDetect' o 'DynamicDataSourceType.Method'. Il rilevamento automatico è l'impostazione predefinita quando non è specificata in modo esplicito ed è consigliabile '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' membro '{0}.{1}' non è una proprietà né un metodo. Sono supportati solo metodi e proprietà. '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' membro '{0}.{1}' è una proprietà, quindi è consigliabile usare 'DynamicDataSourceType.AutoDetect' o 'DynamicDataSourceType.Property'. Il rilevamento automatico è l'impostazione predefinita quando non è specificata in modo esplicito ed è consigliata diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 0df3d78dd4..e0b22196c5 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[AssemblyCleanup]' でマークされたメソッドを有効にするには、次のレイアウトに従う必要があります: -- ジェネリック クラスで宣言することはできません -- 'public' である必要があります -- 'static' である必要があります -- 'async void' にすることはできません -- 特殊なメソッド (ファイナライザー、演算子...) にすることはできません。 -- ジェネリックにすることはできません -- パラメーターを受け取ることができません -- 戻り値の型が 'void'、'Task'、または 'ValueTask' である必要があります + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -これらのメソッドを宣言する型も、次の規則に従う必要があります: -- 型はクラスである必要があります -- クラスは 'public' または 'internal' である必要があります (テスト プロジェクトが '[DiscoverInternals]' 属性を使用している場合) -- クラスを 'static' にすることはできません -- クラスは '[TestClass]' (または派生属性) でマークする必要があります -- クラスをジェネリックにすることはできません。 +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[ClassCleanup]' でマークされたメソッドを有効にするには、次のレイアウトに従う必要があります: -- 'InheritanceBehavior' モードが設定されていないと、ジェネリック クラスで宣言できません -- 'public' である必要があります -- 'static' である必要があります -- 'async void' にすることはできません -- 特殊なメソッド (ファイナライザー、演算子...) にすることはできません。 -- ジェネリックにすることはできません -- パラメーターを受け取ることができません -- 戻り値の型が 'void'、'Task'、または 'ValueTask' である必要があります -- クラスが 'abstract' である場合は 'InheritanceBehavior.BeforeEachDerivedClass' 属性パラメーターーを指定する必要があります -- クラスが 'sealed' である場合は 'InheritanceBehavior.BeforeEachDerivedClass' 属性パラメーターーを指定しない必要があります + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -これらのメソッドを宣言する型も、次の規則に従う必要があります: -- 型はクラスである必要があります -- クラスは 'public' または 'internal' である必要があります (テスト プロジェクトが '[DiscoverInternals]' 属性を使用している場合) -- クラスを 'static' にすることはできません -- クラスが 'sealed' の場合は、'[TestClass]' (または派生属性) でマークする必要があります -- クラスをジェネリックにすることはできません。 +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -364,17 +364,17 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' メンバー '{0}.{1}' はメソッドであるため、'DynamicDataSourceType.AutoDetect' または 'DynamicDataSourceType.Method' を使用する必要があります (自動検出は明示的に指定されていない場合の既定値であり、推奨されます) '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + メンバー '{0}.{1}' '[DynamicData]' プロパティでもメソッドでもありません。プロパティとメソッドのみがサポートされています。 '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' メンバー '{0}.{1}' はプロパティであるため、'DynamicDataSourceType.AutoDetect' または 'DynamicDataSourceType.Property' を使用する必要があります (自動検出は明示的に指定されていない場合の既定値であり、推奨されます) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index a1a3cf53af..c7fa02f674 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[AssemblyCleanup]'으로 표시된 메서드가 유효하려면 다음 레이아웃을 따라야 합니다. --제네릭 클래스에서 선언할 수 없습니다. -- 'public'이어야 합니다. -- 'static'이어야 합니다. -- 'async void'가 아니어야 합니다. -- 특수 메서드(종료자, 연산자...)가 아니어야 합니다. -- 제네릭이 아니어야 합니다. -- 매개 변수를 사용하지 않아야 합니다. -- 반환 형식은 'void', 'Task' 또는 'ValueTask'여야 합니다. + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -이러한 메서드를 선언하는 형식은 다음 규칙도 준수해야 합니다. --형식은 클래스여야 합니다. --클래스는 'public' 또는 'internal'이어야 합니다(테스트 프로젝트에서 '[DiscoverInternals]' 특성을 사용하는 경우). --클래스는 'static'이 되어서는 안 됩니다. --클래스는 '[TestClass]'(또는 파생 특성)로 표시되어야 합니다. --클래스는 제네릭이 아니어야 합니다. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[ClassCleanup]'으로 표시된 메서드가 유효하려면 다음 레이아웃을 따라야 합니다. --'InheritanceBehavior' 모드가 설정되지 않은 제네릭 클래스에서 선언할 수 없습니다. -- 'public'이어야 합니다. -- 'static'이어야 합니다. -- 'async void'가 아니어야 합니다. -- 특수 메서드(종료자, 연산자...)가 아니어야 합니다. -- 제네릭이 아니어야 합니다. -- 매개 변수를 사용하지 않아야 합니다. -- 반환 형식은 'void', 'Task' 또는 'ValueTask'여야 합니다. -- 클래스가 'abstract'인 경우 'InheritanceBehavior.BeforeEachDerivedClass' 특성 매개 변수를 지정해야 합니다. -- 클래스가 'sealed'인 경우 'InheritanceBehavior.BeforeEachDerivedClass' 특성 매개 변수를 지정하면 안 됩니다. + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -이러한 메서드를 선언하는 형식은 다음 규칙도 준수해야 합니다. --형식은 클래스여야 합니다. --클래스는 'public' 또는 'internal'이어야 합니다(테스트 프로젝트에서 '[DiscoverInternals]' 특성을 사용하는 경우). --클래스는 'static'이 되어서는 안 됩니다. --클래스가 'sealed'인 경우 '[TestClass]'(또는 파생 특성)로 표시되어야 합니다. --클래스는 제네릭이 아니어야 합니다. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -364,17 +364,17 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' 멤버 '{0}.{1}'은(는) 'DynamicDataSourceType.AutoDetect' 또는 'DynamicDataSourceType.Method'를 사용해야 하는 메서드입니다.(명시적으로 지정하지 않은 경우 자동 검색이 기본값이며 권장) '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' 멤버 '{0}.{1}'은(는) 속성이나 메서드가 아닙니다. 속성 및 메서드만 지원됩니다. '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' 멤버 '{0}.{1}'은 속성이므로 'DynamicDataSourceType.AutoDetect' 또는 'DynamicDataSourceType.Property'를 사용해야 합니다(명시적으로 지정되지 않은 경우 자동 검색이 기본값이며 권장). diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 63ab26b91a..ee53e58591 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Metody oznaczone za pomocą [AssemblyCleanup] powinny być zgodne z następującym układem, aby były prawidłowe: -— nie może być zadeklarowana w klasie ogólnej -— powinna być typu „public” -— powinna mieć wartość „static” -— nie powinna to być wartość „async void” -— nie powinna to być metoda specjalna (finalizator, operator...). -— nie powinna być ogólna -— nie powinna przyjmować żadnego parametru -— zwracany typ powinien mieć wartość „void”, „Taks” lub „ValueTask” + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -Typ deklarujący te metody powinien również przestrzegać następujących reguł: -— Typ powinien być klasą -— Klasa powinna mieć wartość „public” lub „internal” (jeśli projekt testowy używa atrybutu „[DiscoverInternals]”) -— Klasa nie powinna mieć wartości „static” -— Klasa powinna być oznaczona znakiem „[TestClass]” (lub atrybutem pochodnym) -— Klasa nie powinna być ogólna. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Metody oznaczone za pomocą [ClassCleanup] powinny być zgodne z następującym układem, aby były prawidłowe: --nie może być zadeklarowana w klasie ogólnej bez ustawionego trybu „InheritanceBehavior” -— powinna być typu „public” -— powinna mieć wartość „static” -— nie powinna to być wartość „async void” -— nie powinna to być metoda specjalna (finalizator, operator...). -— nie powinna być ogólna -— nie powinna przyjmować żadnego parametru -— zwracany typ powinien mieć wartość „void”, „Taks” lub „ValueTask” -— parametr atrybutu „InheritanceBehavior.BeforeEachDerivedClass” powinien być określony, jeśli klasa ma wartość „abstract” -— parametr atrybutu „InheritanceBehavior.BeforeEachDerivedClass” nie powinien być określony, jeśli klasa ma wartość „sealed” + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -Typ deklarujący te metody powinien również przestrzegać następujących reguł: -— Typ powinien być klasą -— Klasa powinna mieć wartość „public” lub „internal” (jeśli projekt testowy używa atrybutu „[DiscoverInternals]”) -— Klasa nie powinna mieć wartości „static” -— Jeśli klasa ma wartość „sealed”, powinna być oznaczona znakiem „[TestClass]” (lub atrybutem pochodnym) -— Klasa nie powinna być ogólna. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -364,17 +364,17 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' składowej "{0}.{1}" jest metodą, dlatego należy użyć elementu "DynamicDataSourceType.AutoDetect" lub "DynamicDataSourceType.Method" (autowykrywanie jest domyślne, gdy nie zostało jawnie określone i jest zalecane) '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + składowa '[DynamicData]' "{0}.{1}" nie jest właściwością ani metodą. Obsługiwane są tylko właściwości i metody. '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' składowa "{0}.{1}" jest właściwością, dlatego należy użyć właściwości "DynamicDataSourceType.AutoDetect" lub "DynamicDataSourceType.Property" (wykrywanie automatyczne jest domyślne, gdy nie jest jawnie określone i jest zalecane) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 15ccef0d90..c4845babbe 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Os métodos marcados com “[AssemblyCleanup]” devem seguir o seguinte layout para serem válidos: --não podem ser declarados em uma classe genérica --devem ser "públicos" --devem ser "estáticos" --não devem ser "nulos assíncronos" --não devem ser um método especial (finalizador, operador...). --não devem ser genéricos --não devem usar nenhum parâmetro --o tipo de retorno deve ser “nulo”, “Tarefa” ou “ValueTask” + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -O tipo que declara esses métodos também deve respeitar as seguintes regras: --O tipo deve ser uma classe --A classe deve ser “público” ou '”interno” (se o projeto de teste estiver usando o atributo “[DiscoverInternals]”) --A classe não deve ser “estático” --A classe deve ser marcada com “[TestClass]” (ou um atributo derivado) --a classe não deve ser genérica. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Os métodos marcados com “[ClassCleanup]” devem seguir o seguinte layout para serem válidos: --não podem ser declarados em uma classe genérica sem que o modo “InheritanceBehavior” esteja definido --devem ser "públicos" --devem ser "estáticos" --não devem ser "nulos assíncronos" --não devem ser um método especial (finalizador, operador...). --não devem ser genéricos --não devem usar nenhum parâmetro --o tipo de retorno deve ser “nulo”, “Tarefa” ou “ValueTask” --"InheritanceBehavior.BeforeEachDerivedClass" deve ser especificado se a classe for "abstrato" --'InheritanceBehavior.BeforeEachDerivedClass' não deverá ser especificado se a classe for “selado” + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -O tipo que declara esses métodos também deve respeitar as seguintes regras: --O tipo deve ser uma classe --A classe deve ser “público” ou '”interno” (se o projeto de teste estiver usando o atributo “[DiscoverInternals]”) --A classe não deve ser “estático” --Se a classe for “selado”, ela deverá ser marcada com “[TestClass]” (ou um atributo derivado) --a classe não deve ser genérica. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -364,17 +364,17 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' membro '{0}.{1}' é um método, portanto, você deve usar 'DynamicDataSourceType.AutoDetect' ou 'DynamicDataSourceType.Method' (detectar automaticamente é o padrão quando não especificado explicitamente e é recomendado) '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' membro '{0}.{1}' não é uma propriedade nem um método. Somente propriedades e métodos têm suporte. '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' membro '{0}.{1}' é uma propriedade, portanto, você deve usar 'DynamicDataSourceType.AutoDetect' ou 'DynamicDataSourceType.Property' (detectar automaticamente é o padrão quando não especificado explicitamente e é recomendado) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index 5d3c70fd8e..4a189c8b80 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -19,23 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Чтобы метод, помеченный "[AssemblyCleanup]", был допустимым, он должен соответствовать следующим правилам: -– не может быть объявлен для универсального класса ("generic"); -– должен быть общедоступным ("public"); -– должен быть статическим ("static"); -– не быть асинхронным и не возвращающим значения ("async void") -– не быть специальным (метод завершения, оператор…). -– не быть общим ("generic") -; -– не принимать никаких параметров; -– тип возвращаемого значения должен быть "void", "Task" или "ValueTask"; + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -Тип, объявляющий такие методы, также должен соответствовать следующим правилам: -– должен быть классом; -– класс должен быть объявлен как "public" или "internal" (если тестовый проект использует атрибут "[DiscoverInternals]"); -– не должен быть статическим ("static"); -– должен быть помечен как "[TestClass]" (или производный атрибут); -– не должен быть универсальным ("generic"). +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -153,25 +152,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Чтобы метод, помеченный "[ClassCleanup]", был допустимым, он должен соответствовать следующим правилам: -– не может быть объявлен для универсального класса, если не установлен режим InheritanceBehavior; -– должен быть общедоступным ("public"); -– должен быть статическим ("static"); -– не быть асинхронным и не возвращающим значения ("async void") -– не быть специальным (метод завершения, оператор…). -– не быть общим ("generic") -; -– не принимать никаких параметров; -– тип возвращаемого значения должен быть "void", "Task" или "ValueTask"; -– если класс абстрактный, должен быть указан параметр атрибута "InheritanceBehavior.BeforeEachDerivedClass"; -– если класс запечатанный, не следует указывать параметр атрибута "InheritanceBehavior.BeforeEachDerivedClass"; + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -Тип, объявляющий такие методы, также должен соответствовать следующим правилам: -– должен быть классом; -– класс должен быть объявлен как "public" или "internal" (если тестовый проект использует атрибут "[DiscoverInternals]"); -– не должен быть объявлен как статический ("static"); -– если класс запечатанный, его следует пометить как "[TestClass]" (или производный атрибут); -– не должен быть универсальным ("generic"). +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -368,17 +366,17 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' "{0}.{1}" является методом, поэтому следует использовать "DynamicDataSourceType.AutoDetect" или "DynamicDataSourceType.Method" (автообнаружение используется по умолчанию, если не указано явно, и рекомендуется) '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' "{0}.{1}" не является свойством или методом. Поддерживаются только свойства и методы. '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' "{0}.{1}" является свойством, поэтому следует использовать "DynamicDataSourceType.AutoDetect" или "DynamicDataSourceType.Property" (автообнаружение используется по умолчанию, если не указано явно и рекомендуется) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index 4551d1ce69..01aac6dd4e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[AssemblyCleanup]' ile işaretlenen yöntemlerin geçerli olması için aşağıdaki düzeni takip etmesi gerekir: --genel bir sınıfta tanımlanamaz --'public' olmalıdır --'static' olmalıdır --'async void' olmamalıdır --özel bir yöntem (sonlandırıcı, işleç...) olmamalıdır. -- genel olmamalıdır -- herhangi bir parametre almamalıdır -- dönüş türü 'void', 'Task' veya 'ValueTask' olmalı + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: --Tür bir sınıf olmalıdır --Sınıf 'public' veya 'internal' olmalıdır (test projesi '[DiscoverInternals]' niteliğini kullanıyorsa) --Sınıf 'static' olmamalıdır --Sınıf '[TestClass]' (veya türetilmiş bir öznitelik) ile işaretlenmelidir --sınıf genel olmamalıdır. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - '[ClassCleanup]' ile işaretlenen yöntemlerin geçerli olması için aşağıdaki düzeni takip etmesi gereklidir: --'InheritanceBehavior' modu ayarlanmadan genel bir sınıfta tanımlanamaz --'public' olmalıdır --'static' olmalıdır --'async void' olmamalıdır --özel bir yöntem (sonlandırıcı, işleç...) olmamalıdır. -- genel olmamalıdır -- herhangi bir parametre almamalıdır -- dönüş türü 'void', 'Task' veya 'ValueTask' olmalı --Sınıf 'abstract' ise 'InheritanceBehavior.BeforeEachDerivedClass' öznitelik parametresi belirtilmelidir. --'InheritanceBehavior.BeforeEachDerivedClass' öznitelik parametresi, sınıf 'sealed' ise belirtilmemelidir + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: --Tür bir sınıf olmalıdır --Sınıf 'public' veya 'internal' olmalıdır (test projesi '[DiscoverInternals]' niteliğini kullanıyorsa) --Sınıf 'static' olmamalıdır --Sınıf 'sealed' ise '[TestClass]' (veya türetilmiş bir öznitelik) ile işaretlenmelidir. --sınıf genel olmamalıdır. +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -364,17 +364,17 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' üyesi '{0}.{1}' bir metot olduğundan 'DynamicDataSourceType.AutoDetect' veya 'DynamicDataSourceType.Method' kullanmalısınız (otomatik algılama açıkça belirtilmediğinden varsayılandır ve önerilir) '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' '{0}.{1}' üyesi bir özellik veya yöntem değil. Yalnızca özellikler ve yöntemler desteklenir. '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' üyesi '{0}.{1}' bir özelliktir, bu nedenle 'DynamicDataSourceType.AutoDetect' veya 'DynamicDataSourceType.Property' kullanmalısınız (otomatik algılama açıkça belirtilmediğinden varsayılandır ve önerilir) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 7553dea1fc..34e20fdb8d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - 标记有“[AssemblyCleanup]”的方法应遵循以下布局才会有效: --不能在泛型类上声明它 -- 它应为“public” -- 它应为“static” -- 它不应为“async void” -- 它不应是特殊方法(终结器、运算符...)。 -- 它不应是泛型的 -- 它不应采用任何参数 -- 返回类型应为“void”、“Task”或“ValueTask” + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -声明这些方法的类型还应遵循以下规则: --类型应为类 --类应为“public”或“internal”(如果测试项目正在使用“[DiscoverInternals]”属性) --类不应为“static” --应使用“[TestClass]”(或派生属性)标记类 --类不应是泛型的。 +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - 标记有“[ClassCleanup]”的方法应遵循以下布局才会有效: --如果未设置“InheritanceBehavior”模式,则不能在泛型类上声明它 -- 它应为“public” -- 它应为“static” -- 它不应为“async void” -- 它不应是特殊方法(终结器、运算符...)。 -- 它不应是泛型的 -- 它不应采用任何参数 -- 返回类型应为“void”、“Task”或“ValueTask” -- "InheritanceBehavior.BeforeEachDerivedClass" 属性参数应在类为 "abstract" 时指定 -- "InheritanceBehavior.BeforeEachDerivedClass" 属性参数不应在类为 "sealed" 时指定 + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -声明这些方法的类型还应遵循以下规则: --类型应为类 --类应为“public”或“internal”(如果测试项目正在使用“[DiscoverInternals]”属性) --类不应为“static” --如果类为“sealed”,则应使用“[TestClass]”(或派生属性)标记该类 --类不应是泛型的。 +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -364,17 +364,17 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' 成员 “{0}.{1}” 是一个方法,因此应使用 “DynamicDataSourceType.AutoDetect” 或 “DynamicDataSourceType.Method”,(未显式指定时,自动检测为默认值,建议) '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' 成员 “{0}.{1}” 既不是属性也不是方法。仅支持属性和方法。 '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' 成员 “{0}.{1}” 是属性,因此应使用 “DynamicDataSourceType.AutoDetect” 或 “DynamicDataSourceType.Property”,(自动检测在未显式指定时为默认值,建议) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 8d0831bd2a..f42c4d2bdf 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - 標示為 '[AssemblyCleanup]' 的方法應該遵循下列配置才能有效: --其不能在泛型類別上宣告 -- 其應為 'public' -- 其應為 'static' -- 其不應為 'async void' -- 其不應為特殊方法 (完成項、運算子...)。 -- 其不應為泛型 -- 其不應接受任何參數 -- 傳回類型應為 'void'、'Task' 或 'ValueTask' + Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' -宣告這些方法的類型還應遵循以下規則: --類型應為類別 --類別應為 'public' 或 'internal' (如果測試專案使用 '[DiscoverInternals]' 屬性) --類別不應為 'static' --類別應標示為 '[TestClass]' (或衍生屬性)。 --類別不應為泛型。 +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-The class should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - 標示 '[ClassCleanup]' 的方法應該遵循下列配置,才會有效: --未設定 'InheritanceBehavior' 模式的情況下不能在泛型類別上宣告它 -- 其應為 'public' -- 其應為 'static' -- 其不應為 'async void' -- 其不應為特殊方法 (完成項、運算子...)。 -- 其不應為泛型 -- 其不應接受任何參數 -- 傳回類型應為 'void'、'Task' 或 'ValueTask' -- 如果類別為 'abstract',應指定 'InheritanceBehavior.BeforeEachDerivedClass' 屬性參數。 -- 如果類別為 'sealed',則不應指定 'InheritanceBehavior.BeforeEachDerivedClass' 屬性參數。 + Methods marked with '[ClassCleanup]' should follow the following layout to be valid: +-it can't be declared on a generic class without the 'InheritanceBehavior' mode is set +-it should be 'public' +-it should be 'static' +-it should not be 'async void' +-it should not be a special method (finalizer, operator...). +-it should not be generic +-it should either not take any parameter, or take a single parameter of type 'TestContext' +-return type should be 'void', 'Task' or 'ValueTask' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' +-'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' -宣告這些方法的類型還應遵循以下規則: --類型應為類別 --類別應為 'public' 或 'internal' (如果測試專案使用 '[DiscoverInternals]' 屬性) --類別不應為 'static' --如果類別是 'sealed',則應標示為 '[TestClass]' (或衍生屬性)。 --類別不應為泛型。 +The type declaring these methods should also respect the following rules: +-The type should be a class +-The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) +-The class shouldn't be 'static' +-If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) +-the class should not be generic. @@ -364,17 +364,17 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a method so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Method' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' 成員 '{0}.{1}' 是方法,因此您應該使用 'DynamicDataSourceType.AutoDetect' 或 'DynamicDataSourceType.Method' (未明確指定時,自動偵測是預設值,建議) '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + '[DynamicData]' 成員 『{0}.{1}』 不是屬性也不是方法。只支援屬性和方法。 '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) - '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) + '[DynamicData]' 成員 '{0}.{1}' 是屬性,因此您應該使用 'DynamicDataSourceType.AutoDetect' 或 'DynamicDataSourceType.Property' (未明確指定自動偵測是預設值,建議) From 6047de0209b5669e46ecc7a8e509a5ef764a3a85 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Mon, 23 Dec 2024 01:25:54 -0800 Subject: [PATCH 161/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2606972 --- .../Resources/xlf/ExtensionResources.cs.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.de.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.es.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.fr.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.it.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.ja.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.ko.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.pl.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.pt-BR.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.ru.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.tr.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.zh-Hans.xlf | 6 +++--- .../Resources/xlf/ExtensionResources.zh-Hant.xlf | 6 +++--- 13 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf index 3353514f11..bf24eb49fe 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.cs.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + Opětovné načítání za provozu se podporuje pouze v rozhraní .NET 6.0 nebo novějším. Hot reload test session completed - Hot reload test session completed + Testovací relace opětovného načítání za provozu byla dokončena. Hot reload test session started - Hot reload test session started + Testovací relace opětovného načítání za provozu byla spuštěna. diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf index 6c746dfbf0..426d75c690 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.de.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + Hot Reload wird nur unter .NET 6.0 oder höher unterstützt. Hot reload test session completed - Hot reload test session completed + Hot Reload-Testsitzung abgeschlossen Hot reload test session started - Hot reload test session started + Hot Reload-Testsitzung gestartet diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf index c1f4fe7325..e014452c97 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.es.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + La recarga activa solo se admite en .NET 6.0 o posterior Hot reload test session completed - Hot reload test session completed + Sesión de prueba de recarga activa completada Hot reload test session started - Hot reload test session started + Se inició la sesión de prueba de recarga activa diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf index 3ae87ff772..311d81deac 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.fr.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + Le rechargement à chaud est uniquement pris en charge sur .NET 6.0 ou version ultérieure Hot reload test session completed - Hot reload test session completed + Session de test de rechargement à chaud terminée Hot reload test session started - Hot reload test session started + Session de test de rechargement à chaud démarrée diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf index 7f4825357d..f8c8801628 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.it.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + Il ricaricamento rapido è supportato solo in .NET 6.0 o versione successiva Hot reload test session completed - Hot reload test session completed + Sessione di test di ricaricamento rapido completata Hot reload test session started - Hot reload test session started + Sessione di test di ricaricamento rapido avviata diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf index 7d4742beed..73be365a65 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ja.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + ホット リロードは .NET 6.0 以降でのみサポートされています Hot reload test session completed - Hot reload test session completed + ホット リロード テスト セッションが完了しました Hot reload test session started - Hot reload test session started + ホット リロード テスト セッションが開始されました diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf index d34213e843..6dbdebaba2 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ko.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + 핫 다시 로드는 .NET 6.0 이상에서만 지원됩니다. Hot reload test session completed - Hot reload test session completed + 핫 다시 로드 테스트 세션 완료 Hot reload test session started - Hot reload test session started + 핫 다시 로드 테스트 세션 시작됨 diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf index b549ab6708..5b74462a80 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pl.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + Ponowne ładowanie na gorąco jest obsługiwane tylko na platformie .NET 6.0 lub nowszej Hot reload test session completed - Hot reload test session completed + Sesja testu ponownego ładowania na gorąco została ukończona Hot reload test session started - Hot reload test session started + Rozpoczęto sesję testu ponownego ładowania na gorąco diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf index ec4eb5d6cf..743f052c79 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.pt-BR.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + Só há suporte para a recarga dinâmica no .NET 6.0 ou superior Hot reload test session completed - Hot reload test session completed + Sessão de teste de recarga dinâmica concluída Hot reload test session started - Hot reload test session started + Sessão de teste de recarga dinâmica iniciada diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf index 6291815367..1f26adfb86 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.ru.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + Горячая перезагрузка поддерживается только в версии .NET 6.0 или более поздних версиях Hot reload test session completed - Hot reload test session completed + Тестовый сеанс горячей перезагрузки завершен Hot reload test session started - Hot reload test session started + Запущен тестовый сеанс горячей перезагрузки diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf index 4a493df8a0..70125a0e05 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.tr.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + Çalışırken yeniden yükleme yalnızca .NET 6.0 veya üzeri sürümlerde desteklenir Hot reload test session completed - Hot reload test session completed + Çalışırken yeniden yükleme test oturumu tamamlandı Hot reload test session started - Hot reload test session started + Çalışırken yeniden yükleme test oturumu başlatıldı diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf index 65bea4a4fd..af518ebd73 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hans.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + 仅 .NET 6.0 或更高版本支持热重载 Hot reload test session completed - Hot reload test session completed + 热重载测试会话已完成 Hot reload test session started - Hot reload test session started + 热重载测试会话已启动 diff --git a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf index 265c54fa97..0fd9224ca7 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.HotReload/Resources/xlf/ExtensionResources.zh-Hant.xlf @@ -4,17 +4,17 @@ Hot reload is only supported on .NET 6.0 or greater - Hot reload is only supported on .NET 6.0 or greater + 只有 .NET 6.0 或更新版本才支援熱重新載入 Hot reload test session completed - Hot reload test session completed + 熱重新載入測試工作階段已完成 Hot reload test session started - Hot reload test session started + 熱重新載入測試工作階段已開始 From 7907cbdcde1cf698bd9a558f9993d8a94da4c247 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Mon, 23 Dec 2024 01:27:16 -0800 Subject: [PATCH 162/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2606972 --- .../Resources/xlf/ExtensionResources.cs.xlf | 54 +++++++++---------- .../Resources/xlf/ExtensionResources.de.xlf | 54 +++++++++---------- .../Resources/xlf/ExtensionResources.es.xlf | 54 +++++++++---------- .../Resources/xlf/ExtensionResources.fr.xlf | 54 +++++++++---------- .../Resources/xlf/ExtensionResources.it.xlf | 54 +++++++++---------- .../Resources/xlf/ExtensionResources.ja.xlf | 54 +++++++++---------- .../Resources/xlf/ExtensionResources.ko.xlf | 54 +++++++++---------- .../Resources/xlf/ExtensionResources.pl.xlf | 54 +++++++++---------- .../xlf/ExtensionResources.pt-BR.xlf | 54 +++++++++---------- .../Resources/xlf/ExtensionResources.ru.xlf | 54 +++++++++---------- .../Resources/xlf/ExtensionResources.tr.xlf | 54 +++++++++---------- .../xlf/ExtensionResources.zh-Hans.xlf | 54 +++++++++---------- .../xlf/ExtensionResources.zh-Hant.xlf | 54 +++++++++---------- 13 files changed, 351 insertions(+), 351 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf index 576477cd56..fa82dcccef 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.cs.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + Nepovedlo se vytvořit adresář opakovaných pokusů kvůli kolizím v adresáři {0}, a to ani přes opakované pokusy. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + Je povolena zásada prahové hodnoty selhání, neúspěšné testy se nerestartují. Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + Prahová hodnota maximálního počtu neúspěšných testů je {0} a tento počet testů selhal: {1}. Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Procentuální prahová hodnota selhání je {0} % a toto procento testů selhalo: {1} % ({2}/{3}). @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +Přesouvání souborů prostředků posledního pokusu do výchozího adresáře výsledků ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + Soubor {0} se přesouvá do umístění {1}. Failed to start process '{0}' - Failed to start process '{0}' + Nepovedlo se spustit proces {0}. Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + Funkce opakování neúspěšných testů umožňuje po selhání znovu spustit test. Retry failed tests - Retry failed tests + Opakovat neúspěšné testy Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Opakování neúspěšných testů funguje pouze s tvůrci typu Microsoft.Testing.Platform.Builder.TestApplicationBuilder. Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + Zakázat mechanismus opakování, pokud je procento neúspěšných testů větší než zadaná hodnota Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + Zakázat mechanismus opakování, pokud je počet neúspěšných testů větší než zadaná hodnota Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + Funkce opakování neúspěšných testů není v režimu opětovného načítání za provozu podporovaná. Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + Funkce opakování neúspěšných testů není v režimu serveru podporovaná. Enable retry failed tests - Enable retry failed tests + Povolit opakování neúspěšných testů Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + Možnost {0} vyžaduje, aby byla zadaná možnost {1}. Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + Možnost {0} očekává jeden celočíselný argument. Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + Možnost {0} nelze používat společně s možností {1}. Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + Hostitelský proces testu byl ukončen dříve, než se k němu mohla služba opakování připojit. Ukončovací kód: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +Sada testů byla úspěšně dokončena při {0} pokusech ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +Sada testů selhala, celkový počet neúspěšných testů: {0}, ukončovací kód: {1}, pokus: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +Sada testů selhala při všech {0} pokusech ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Sada testů neproběhla úspěšně a ukončovací kód je jiný než 2 (neúspěšné testy). Selhání související s neočekávanou podmínkou. Ukončovací kód: {0} diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf index a523163bae..c7e44a2b31 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.de.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + Fehler beim Erstellen des Wiederholungsverzeichnisses aufgrund von Konflikten in „{0}“ trotz erneuter Versuche. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + Wenn die Richtlinie für fehlgeschlagene Tests aktiviert ist, werden fehlgeschlagene Tests nicht neu gestartet. Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + Der Schwellenwert für die maximale Anzahl fehlerhafter Tests ist {0} und {1} Tests mit Fehlern Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Der Schwellenwert für den Prozentsatz fehlgeschlagener Tests ist {0} %, und {1} % Tests mit Fehlern ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +Medienobjektdateien des letzten Versuchs werden in das Standardergebnisverzeichnis verschoben. ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + Die Datei "{0}" wird nach "{1}" verschoben Failed to start process '{0}' - Failed to start process '{0}' + Fehler beim Starten von Prozess "{0}". Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + Das Feature zum Wiederholen fehlerhafter Tests ermöglicht es, die Testausführung bei einem Fehler neu zu starten. Retry failed tests - Retry failed tests + Tests mit Wiederholungsfehlern Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Das Wiederholen fehlerhafter Tests funktioniert nur mit Generatoren vom Typ "Microsoft.Testing.Platform.Builder.TestApplicationBuilder". Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + Wiederholungsmechanismus deaktivieren, wenn der Prozentsatz fehlerhafter Tests größer als der angegebene Wert ist Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + Wiederholungsmechanismus deaktivieren, wenn die Anzahl fehlerhafter Tests größer als der angegebene Wert ist Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + Das Feature zum Wiederholen fehlerhafter Tests wird im Hot Reload-Modus nicht unterstützt Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + Das Feature zum Wiederholen fehlerhafter Tests wird im Servermodus nicht unterstützt Enable retry failed tests - Enable retry failed tests + Tests mit Wiederholungsfehlern aktivieren Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + Die "{0}"-Option erfordert, dass "{1}" angegeben ist Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + Option "{0}" erwartet ein einzelnes ganzzahliges Argument Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + Optionen "{0}" und "{1}" können nicht zusammen verwendet werden Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + Der Testhostprozess wurde beendet, bevor der Wiederholungsdienst eine Verbindung herstellen konnte. Exitcode: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +Die Testsammlung wurde in {0} Versuchen erfolgreich abgeschlossen. ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +Fehler bei der Testsammlung. Fehlerhafte Tests gesamt: {0}, Exitcode: {1}, Versuch: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +Fehler bei der Testsammlung bei allen {0} Versuchen. ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Bei der Testsammlung ist ein Fehler aufgetreten, und der Exitcode unterscheidet sich von 2 (fehlgeschlagene Tests). Fehler im Zusammenhang mit einer unerwarteten Bedingung. Exitcode "{0}" diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf index fa994d33b1..2a054009cb 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.es.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + No se pudo crear el directorio de reintentos debido a colisiones en '{0}' a pesar de volver a intentarlo. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + La directiva de umbral de errores está habilitada; no se reiniciarán las pruebas con errores. Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + El umbral máximo de pruebas con errores es {0} y {1} pruebas erróneas Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + El umbral de porcentaje de errores es {0}% y {1}% de pruebas no superadas ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +Moviendo los archivos de recursos del último intento al directorio de resultados predeterminado ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + Moviendo el archivo '{0}' a '{1}' Failed to start process '{0}' - Failed to start process '{0}' + No se pudo iniciar el proceso '{0}' Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + La característica Reintentar pruebas con errores permite reiniciar la ejecución de pruebas en caso de error. Retry failed tests - Retry failed tests + Reintentar pruebas con errores Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Reintentar pruebas con errores solo funciona con generadores de tipo "Microsoft.Testing.Platform.Builder.TestApplicationBuilder" Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + Deshabilitar el mecanismo de reintento si el porcentaje de pruebas con errores es mayor que el valor especificado Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + Deshabilitar el mecanismo de reintento si el número de pruebas con errores es mayor que el valor especificado Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + La característica Reintentar pruebas con errores no se admite en el modo de recarga activa Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + La característica reintentar pruebas con errores no se admite en el modo de servidor Enable retry failed tests - Enable retry failed tests + Habilitar pruebas con errores de reintento Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + La opción '{0}' requiere que se especifique la opción '{1}' Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + La opción '{0}' espera un único argumento entero Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + Las opciones '{0}' y '{1}' no se pueden usar juntas Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + El proceso de host de prueba se cerró antes de que el servicio de reintento pudiera conectarse a él. Código de salida: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +El conjunto de pruebas se completó correctamente en {0} intentos ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +Error del conjunto de pruebas, total de pruebas erróneas: {0}, código de salida: {1}, intento: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +Error del conjunto de pruebas en los {0} intentos ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Error del conjunto de pruebas con código de salida distinto de 2 (pruebas con errores). Error relacionado con una condición inesperada. '{0}' de código de salida diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf index 4bce56d0c7..ebc1cab4de 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.fr.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + Échec de la création du répertoire des nouvelles tentatives en raison de collisions dans « {0} » malgré une nouvelle tentative. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + La stratégie de seuil d’échec est activée, les tests ayant échoué ne seront pas redémarrés. Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + Le seuil maximal des tests ayant échoué est {0} et {1} tests ont échoué Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Le seuil de pourcentage d’échec est {0}% et {1}% de tests ont échoué ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +Déplacement des fichiers de ressources de la dernière tentative vers le répertoire de résultats par défaut ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + Déplacement du fichier '{0}' vers '{1}' Failed to start process '{0}' - Failed to start process '{0}' + Échec de démarrage du processus « {0} » Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + La fonctionnalité de nouvelles tentatives de tests ayant échoué permet de redémarrer l’exécution des tests en cas d’échec. Retry failed tests - Retry failed tests + Nouvelle tentative de tests ayant échoué Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Les nouvelles tentatives de tests ayant échoué fonctionnent uniquement avec les générateurs de type « Microsoft.Testing.Platform.Builder.TestApplicationBuilder » Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + Désactiver le mécanisme de nouvelle tentative si le pourcentage de tests ayant échoué est supérieur à la valeur spécifiée Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + Désactiver le mécanisme de nouvelle tentative si le nombre de tests ayant échoué est supérieur à la valeur spécifiée Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + La fonctionnalité de nouvelles tentatives de tests ayant échoué n’est pas prise en charge en mode rechargement à chaud Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + La fonctionnalité de nouvelles tentatives de tests ayant échoué n’est pas prise en charge en mode serveur Enable retry failed tests - Enable retry failed tests + Activer les nouvelles tentatives de tests ayant échoué Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + L’option '{0}' nécessite la spécification de l’option '{1}' Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + L’option '{0}' attend un seul argument entier Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + Les options «{0}» et «{1}» ne peuvent pas être utilisées ensemble Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + Le processus hôte de test s’est arrêté avant que le service de nouvelle tentative puisse s’y connecter. Code de sortie : {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +La suite de tests s’est correctement terminée dans les {0} tentatives ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +Échec de la suite de tests, nombre total de tests ayant échoué : {0}, code de sortie : {1}, tentative : {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +Échec de la suite de tests dans toutes les {0} tentatives ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + La suite de tests a échoué avec un code de sortie différent de 2 (tests échoués). Défaillance liée à une condition inattendue. Code de sortie « {0} » diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf index 5ea2087640..18d2389948 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.it.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + Non è possibile creare la directory dei tentativi a causa di collisioni in “{0}” nonostante i tentativi ripetuti. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + Se il criterio della soglia di errore è abilitato, i test non riusciti non verranno riavviati. Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + La soglia massima dei test non superati è {0} e i test {1} non sono riusciti Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + La soglia percentuale di operazioni non riuscite è del {0}% e del {1}% di test non riusciti ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +Spostamento dei file di asset dell'ultimo tentativo nella directory dei risultati predefinita ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + Spostamento del file '{0}' in '{1}' Failed to start process '{0}' - Failed to start process '{0}' + Impossibile avviare il processo '{0}' Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + La funzionalità di ripetizione dei test non riusciti consente di riavviare l'esecuzione dei test in caso di errore. Retry failed tests - Retry failed tests + Ripeti i test non riusciti Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + La ripetizione dei test non riusciti funziona solo con i generatori di tipo 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder'. Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + Disabilita il meccanismo di ripetizione dei tentativi se la percentuale di test non riusciti è maggiore del valore specificato. Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + Disabilita il meccanismo di ripetizione dei tentativi se il numero di test non riusciti è maggiore del valore specificato. Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + La funzionalità di ripetizione dei test non riusciti non è supportata nella modalità di ricaricamento rapido. Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + La funzionalità di ripetizione dei test non riusciti non è supportata in modalità server Enable retry failed tests - Enable retry failed tests + Abilita la ripetizione dei test non riusciti Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + L'opzione '{0}' richiede l'opzione '{1}' da specificare Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + L'opzione '{0}' prevede un singolo argomento integer Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + Le opzioni '{0}' e '{1}' non possono essere usate insieme Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + Il processo host di test è stato chiuso prima che il servizio di ripetizione potesse connettersi ad esso. Codice di uscita: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +Il gruppo di test è stato completato correttamente in {0} tentativi ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +Gruppo di test non riuscito, totale test non superati: {0}, codice di uscita: {1}, tentativo: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +Gruppo di test non riuscito in tutti i {0} tentativi ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Il gruppo di test non è riuscito e il codice di uscita è diverso da 2 (test non superati). Errore correlato a una condizione imprevista. Codice di uscita "{0}" diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf index 2f065b6bef..6593d426d2 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ja.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + 再試行中に '{0}' で競合が発生したため、再試行ディレクトリを作成できませんでした。 '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + 失敗しきい値ポリシーが有効になっているため、失敗したテストは再開されません。 Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + 失敗したテストの最大しきい値は {0} で、{1} のテストが失敗しました Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + 失敗率のしきい値は {0} % で、失敗したテストは {1} % です ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +前回試行した資産ファイルを既定の結果ディレクトリに移動しています ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + ファイル '{0}' を '{1}' に移動しています Failed to start process '{0}' - Failed to start process '{0}' + 処理 '{0}' を開始できませんでした Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + 失敗したテストの再試行機能を使用すると、失敗時にテストの実行を再開できます。 Retry failed tests - Retry failed tests + 失敗したテストの再試行 Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + 失敗したテストの再試行は、'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' 型のビルダーでのみ機能します Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + 失敗したテストの割合が指定した値を超える場合は再試行メカニズムを無効にする Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + 失敗したテストの数が指定した値を超える場合は再試行メカニズムを無効にする Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + 失敗したテストの再試行機能は、ホット リロード モードではサポートされていません Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + 失敗したテストの再試行機能は、サーバー モードではサポートされていません Enable retry failed tests - Enable retry failed tests + 失敗したテストの再試行を有効にする Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + オプション '{0}' では、オプション '{1}' を指定する必要があります Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + オプション '{0}' には 1 つの整数引数が必要です Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + オプション '{0}' と '{1}' を一緒に使用することはできません Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + 再試行サービスが接続する前に、テスト ホスト プロセスが終了しました。終了コード: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +テスト スイートが {0} 回の試行で正常に完了しました ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +テスト スイートが失敗しました。失敗したテストの合計数: {0}、終了コード: {1}、試行: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +テスト スイートが {0} 回の試行すべてで失敗しました ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + テスト スイートが失敗し、終了コードが 2 (失敗したテスト) と異なりました。予期しない状態に関連するエラーです。終了コード '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf index eab60aa795..d521ae9495 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ko.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + 다시 시도에도 불구하고 '{0}'의 충돌로 인해 재시도 디렉터리를 만들지 못했습니다. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + 실패 임계값 정책을 사용하도록 설정했습니다. 실패한 테스트는 다시 시작되지 않습니다. Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + 실패한 최대 테스트 임계값이 {0}이고 {1} 테스트가 실패했습니다. Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + 실패한 임계값 백분율은 {0}%이며 {1}% 테스트에 실패했습니다({2}/{3}). @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +마지막 시도 자산 파일을 기본 결과 디렉터리로 이동 ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + 파일 {0}을(를) {1}(으)로 이동 Failed to start process '{0}' - Failed to start process '{0}' + 프로세스 '{0}'을(를) 시작하지 못했습니다. Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + 실패한 테스트 다시 시도 기능을 사용하면 실패 시 테스트 실행을 다시 시작할 수 있습니다. Retry failed tests - Retry failed tests + 실패한 테스트 다시 시도 Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + 실패한 테스트 다시 시도는 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' 유형의 작성기에서만 작동합니다. Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + 실패한 테스트의 비율이 지정된 값보다 큰 경우 다시 시도 메커니즘을 사용하지 않도록 설정 Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + 실패한 테스트 수가 지정된 값보다 큰 경우 다시 시도 메커니즘을 사용하지 않도록 설정 Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + 실패한 테스트 다시 시도 기능은 핫 다시 로드 모드에서 지원되지 않습니다. Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + 실패한 테스트 다시 시도 기능은 서버 모드에서 지원되지 않습니다. Enable retry failed tests - Enable retry failed tests + 실패한 테스트 다시 시도 사용 Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + '{0}' 옵션을(를) 사용하려면 '{1}' 옵션을 지정해야 합니다. Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + '{0}' 옵션에는 단일 정수 인수가 필요합니다. Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + '{0}' 및 '{1}' 옵션은 함께 사용할 수 없습니다. Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + 다시 시도 서비스가 연결되기 전에 테스트 호스트 프로세스가 종료되었습니다. 종료 코드: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +테스트 도구 모음이 {0} 시도에서 완료되었습니다. ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +테스트 도구 모음이 실패했습니다. 실패한 총 테스트: {0}, 종료 코드: {1}, 시도: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +테스트 도구 모음이 모든 {0} 시도에 실패했습니다 ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + 테스트 도구 모음이 2와 다른 종료 코드를 사용하여 실패했습니다(테스트 실패). 예기치 않은 조건과 관련된 오류입니다. 종료 코드 '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf index 49774ebf39..9876de376e 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pl.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + Nie można utworzyć katalogu ponownych prób z powodu kolizji w katalogu „{0}” mimo ponownej próby. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + Zasady progu błędów są włączone, a testy zakończone niepowodzeniem nie zostaną ponownie uruchomione. Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + Próg maksymalnej liczby testów zakończonych niepowodzeniem to {0} i liczba testów zakończonych niepowodzeniem wyniosła {1} Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Wartość procentowa progu niepowodzenia wynosi {0}% i {1}% testów nie powiodło się ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +Przeniesienie plików zasobów ostatniej próby do domyślnego katalogu wyników ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + Przenoszenie pliku „{0}” do {1} Failed to start process '{0}' - Failed to start process '{0}' + Nie można uruchomić procesu „{0}” Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + Funkcja ponawiania testów zakończonych niepowodzeniem umożliwia ponowne uruchomienie wykonywania testu po niepowodzeniu. Retry failed tests - Retry failed tests + Ponów próbę testów zakończonych niepowodzeniem Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Ponawianie testów zakończonych niepowodzeniem działa tylko z konstruktorami typu „Microsoft.Testing.Platform.Builder.TestApplicationBuilder” Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + Wyłącz mechanizm ponawiania prób, jeśli procent testów zakończonych niepowodzeniem jest większy niż określona wartość Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + Wyłącz mechanizm ponawiania prób, jeśli liczba testów zakończonych niepowodzeniem jest większa niż określona wartość Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + Funkcja ponownych testów zakończonych niepowodzeniem nie jest obsługiwana w trybie ponownego ładowania na gorąco Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + Funkcja ponawiania testów zakończonych niepowodzeniem nie jest obsługiwana w trybie serwera Enable retry failed tests - Enable retry failed tests + Włącz testy zakończone niepowodzeniem ponowień Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + Opcja „{0}” wymaga określenia opcji „{1}” Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + Opcja „{0}” oczekuje argumentu pojedynczej liczby całkowitej Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + Opcji „{0}” i „{1}” nie można używać razem Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + Proces hosta testowego zakończył się, zanim usługa ponawiania próby mogła nawiązać z nim połączenie. Kod zakończenia: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +Pomyślnie ukończono pakiet testów w {0} próbach ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +Pakiet testów nie powiódł się, łączna liczba testów zakończonych niepowodzeniem: {0}, kod zakończenia: {1}, próba: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +Pakiet testów nie powiódł się we wszystkich {0} próbach ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Zestaw testów nie powiódł się. Kod zakończenia jest inny niż 2 (testy zakończone niepowodzeniem). Błąd związany z nieoczekiwanym warunkiem. Kod zakończenia „{0}” diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf index 904a8aef49..48006921c3 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.pt-BR.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + Falha ao criar o diretório de novas tentativas devido a colisões em '{0}', apesar das novas tentativas. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + A política de limite de falha está habilitada, os testes com falha não serão reiniciados. Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + O limite máximo de testes com falha é {0} e {1} testes falharam Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + O limite de porcentagem com falha é {0}% e {1}% dos testes falharam ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +Movendo arquivos de ativo da última tentativa para o diretório de resultados padrão ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + Movendo o arquivo ''{0}'' para ''{1}'' Failed to start process '{0}' - Failed to start process '{0}' + Falha ao iniciar o processo '{0}' Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + O recurso repetir testes com falha permite reiniciar a execução de teste após falha. Retry failed tests - Retry failed tests + Repetir testes com falha Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + A repetição de testes com falha funciona somente com construtores do tipo ''Microsoft.Testing.Platform.Builder.TestApplicationBuilder'' Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + Desabilitar o mecanismo de repetição se a porcentagem de testes com falha for maior que o valor especificado Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + Desabilitar o mecanismo de repetição se o número de testes com falha for maior que o valor especificado Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + Não há suporte para o recurso de repetição de testes com falha no modo de recarga dinâmica Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + Não há suporte para o recurso de repetição de testes com falha no modo de servidor Enable retry failed tests - Enable retry failed tests + Habilitar repetição de testes com falha Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + A opção ''{0}'' requer que a opção ''{1}'' seja especificada Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + A opção ''{0}'' espera um único argumento inteiro Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + As opções ''{0}'' e ''{1}'' não podem ser usadas juntas Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + O processo de host de teste foi encerrado antes que o serviço de repetição pudesse se conectar a ele. Código de saída: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +Pacote de testes concluído com êxito em {0} tentativas ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +Falha no pacote de testes, total de testes com falha: {0}, código de saída: {1}, tentativa: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +Falha no pacote de testes em todas as {0} tentativas ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Falha no conjunto de testes e código de saída diferente de 2 (testes com falha). Falha relacionada a uma condição inesperada. Código de saída "{0}" diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf index 5ec33b94b0..0f89116a98 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.ru.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + Не удалось создать каталог повторов из-за конфликтов в '{0}' несмотря на повторную попытку. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + Политика порога отказа включена, неудачные тесты не будут перезапущены. Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + Максимальное пороговое значение для неудачных тестов — {0}, и неудачных тестов — {1} Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Пороговое значение доли неудачных тестов — {0}%, и доля неудачных тестов — {1}% ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +Перемещение файлов ресурсов последней попытки в каталог результатов по умолчанию ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + Перемещение файла "{0}" в "{1}" Failed to start process '{0}' - Failed to start process '{0}' + Не удалось запустить процесс "{0}". Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + Функция повтора неудачных тестов позволяет перезапустить выполнение теста после сбоя. Retry failed tests - Retry failed tests + Включить повтор неудачных тестов Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Повтор неудачных тестов работает только с построителями типа "Microsoft.Testing.Platform.Builder.TestApplicationBuilder" Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + Отключить механизм повторных попыток, если процент неудачных тестов превышает указанное значение Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + Отключить механизм повторных попыток, если число неудачных тестов превышает указанное значение Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + Функция повтора неудачных тестов не поддерживается в режиме горячей перезагрузки Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + Функция повтора неудачных тестов не поддерживается в режиме сервера Enable retry failed tests - Enable retry failed tests + Включить повтор неудачных тестов Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + Параметр "{0}" требует указания параметра "{1}" Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + Параметр "{0}" ожидает один целочисленный аргумент Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + Параметры "{0}" и "{1}" не могут использоваться вместе Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + Тестовый хост-процесс завершился прежде, чем к нему смогла подключиться служба повторной попытки. Код выхода: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +Набор тестов успешно завершен за несколько ({0}) попыток ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +Сбой набора тестов. Всего неудачных тестов: {0}, код завершения: {1}, попытка: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +Сбой набора тестов во всех попытках ({0}) ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Сбой набора тестов с кодом завершения, который отличается от 2 (неудачные тесты). Сбой, связанный с неожиданным условием. Код завершения "{0}" diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf index f5cce9f379..a9c6d6ce52 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.tr.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + Yeniden denemeye rağmen '{0} ' içindeki çakışmalar nedeniyle yeniden deneme dizini oluşturulamadı. '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + Hata eşiği ilkesi etkinleştirildi, başarısız testler yeniden başlatılmaz. Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + Maksimum başarısız test eşiği {0} ve {1} test başarısız oldu Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + Başarısız olan yüzde eşiği %{0} ve başarısız %{1} ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +Son deneme varlık dosyaları, varsayılan sonuç dizinine taşınıyor ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + '{0}' dosyasını '{1}'e taşıma Failed to start process '{0}' - Failed to start process '{0}' + '{0}' işlemi başlatılamadı Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + Başarısız testleri yeniden dene özelliği, başarısızlık durumunda test yürütmenin yeniden başlatılmasına olanak tanır. Retry failed tests - Retry failed tests + Başarısız testleri yeniden deneyin Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + Başarısız testleri yeniden deneme yalnızca 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' türündeki oluşturucularla çalışır Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + Başarısız testlerin yüzdesi belirtilen değerden büyükse yeniden deneme mekanizmasını devre dışı bırak Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + Başarısız testlerin yüzdesi belirtilen değerden büyükse yeniden deneme mekanizmasını devre dışı bırak Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + Başarısız testleri yeniden deneme özelliği, çalışırken yeniden yükleme modunda desteklenmez Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + Başarısız testleri yeniden deneme özelliği sunucu modunda desteklenmiyor Enable retry failed tests - Enable retry failed tests + Başarısız testleri yeniden denemeyi etkinleştir Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + '{0}' seçeneği, '{1}' seçeneğinin belirtilmesini gerektirir Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + Seçenek '{0}' tek bir tamsayı argümanı bekliyor Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + '{0}' ve '{1}' seçenekleri birlikte kullanılamaz Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + Yeniden deneme hizmeti ona bağlanamadan test ana makinesi işleminden çıkıldı. Çıkış kodu: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +Test paketi {0} denemede de başarıyla tamamlandı ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +Test paketi başarısız oldu, toplam başarısız test: {0}, çıkış kodu: {1}, deneme: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +Test paketi tüm {0} denemede de başarısız oldu ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + Test paketi 2 (başarısız testler) kodundan farklı bir çıkış koduyla başarısız oldu. Beklenmeyen bir koşulla ilgili hata. Çıkış kodu '{0}' diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf index 7ea7359fc1..e558008090 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hans.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + 未能创建重试目录,因为尽管重试,但“{0}”中存在冲突。 '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + 已启用失败阈值策略,将不会重新启动失败的测试。 Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + 最大失败测试阈值为 {0},有 {1} 测试失败 Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + 失败的阈值百分比为 {0}%,有 {1}% 测试失败({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +正在将上次尝试资产文件移动到默认结果目录 ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + 正在将文件“{0}”移动到“{1}” Failed to start process '{0}' - Failed to start process '{0}' + 无法启动进程“{0}” Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + 重试失败的测试功能允许在失败时重新启动测试执行。 Retry failed tests - Retry failed tests + 重试失败的测试 Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + 重试失败的测试仅适用于“Microsoft.Testing.Platform.Builder.TestApplicationBuilder”类型的生成器 Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + 如果失败的测试百分比大于指定值,则禁用重试机制 Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + 如果失败的测试数大于指定值,则禁用重试机制 Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + 热重载模式下不支持重试失败的测试功能 Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + 服务器模式不支持重试失败的测试功能 Enable retry failed tests - Enable retry failed tests + 启用重试失败的测试 Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + 选项“{0}”需要指定选项“{1}” Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + 选项“{0}”需要单一整数参数 Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + 选项“{0}”和“{1}”不能一起使用 Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + 测试主机进程已在重试服务可以连接到它之前退出。退出代码: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +测试套件已成功完成 {0} 次尝试 ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +测试套件失败,失败的测试总数: {0},退出代码: {1},尝试次数: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +测试套件在所有 {0} 尝试中均失败 ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + 测试套件失败,且退出代码不是 2 (测试失败)。与意外情况相关的失败。退出代码“{0}” diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf index 5cc8cd74fb..d40bbad9ef 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/Resources/xlf/ExtensionResources.zh-Hant.xlf @@ -4,22 +4,22 @@ Failed to create retries directory due to collisions in '{0}' despite re-trying. - Failed to create retries directory due to collisions in '{0}' despite re-trying. + 無法建立重試目錄,因為 '{0}' 中發生衝突,但仍在重試。 '{0}' is the directory where collisions happen Failure threshold policy is enabled, failed tests will not be restarted. - Failure threshold policy is enabled, failed tests will not be restarted. + 已啟用失敗節流原則,將不會重新啟動失敗的測試。 Maximum failed tests threshold is {0} and {1} tests failed - Maximum failed tests threshold is {0} and {1} tests failed + 失敗的測試閾值上限是 {0},有 {1} 個測試失敗 Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) - Percentage failed threshold is {0}% and {1}% tests failed ({2}/{3}) + 失敗的百分比閾值為 {0}%,有 {1}% 個測試失敗 ({2}/{3}) @@ -28,81 +28,81 @@ Moving last attempt asset files to the default result directory ===================== - + ===================== -Moving last attempt asset files to the default result directory +將上次嘗試的資產檔案移至預設結果目錄 ===================== Moving file '{0}' to '{1}' - Moving file '{0}' to '{1}' + 正在將檔案 '{0}' 移至 '{1}' Failed to start process '{0}' - Failed to start process '{0}' + 無法啟動處理程序 '{0}' Retry failed tests feature allows to restart test execution upon failure. - Retry failed tests feature allows to restart test execution upon failure. + 重試失敗的測試功能允許在失敗時重新啟動測試執行。 Retry failed tests - Retry failed tests + 重試失敗的測試 Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' - Retry failed tests only works with builders of type 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' + 重試失敗的測試僅適用於類型為 'Microsoft.Testing.Platform.Builder.TestApplicationBuilder' 的建立器 Disable retry mechanism if the percentage of failed tests is greater than the specified value - Disable retry mechanism if the percentage of failed tests is greater than the specified value + 如果失敗的測試百分比大於指定的值,則停用重試機制 Disable retry mechanism if the number of failed tests is greater than the specified value - Disable retry mechanism if the number of failed tests is greater than the specified value + 如果失敗的測試數目大於指定的值,則停用重試機制 Retry failed tests feature is not supported in hot reload mode - Retry failed tests feature is not supported in hot reload mode + 熱重新載入模式不支援重試失敗的測試功能 Retry failed tests feature is not supported in server mode - Retry failed tests feature is not supported in server mode + 伺服器模式不支援重試失敗的測試功能 Enable retry failed tests - Enable retry failed tests + 啟用重試失敗的測試 Option '{0}' requires option '{1}' to be specified - Option '{0}' requires option '{1}' to be specified + 使用 '{0}' 選項時必須指定選項 '{1}'。 Option '{0}' expects a single integer argument - Option '{0}' expects a single integer argument + 選項 '{0}' 需要單一整數引數 Options '{0}' and '{1}' cannot be used together - Options '{0}' and '{1}' cannot be used together + 選項 '{0}' 和 '{1}' 不能同時使用 Test host process exited before the retry service could connect to it. Exit code: {0} - Test host process exited before the retry service could connect to it. Exit code: {0} + 測試主機處理序在重試服務連線到它之前已結束。結束代碼: {0} @@ -110,9 +110,9 @@ Moving last attempt asset files to the default result directory ===================== Tests suite completed successfully in {0} attempts ===================== - + ===================== -Tests suite completed successfully in {0} attempts +測試套件已順利在 {0} 次嘗試內完成 ===================== @@ -122,9 +122,9 @@ Tests suite completed successfully in {0} attempts Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== - + ===================== -Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} +測試套件失敗,失敗的測試總數: {0},結束代碼: {1},嘗試: {2}/{3} ===================== @@ -134,15 +134,15 @@ Tests suite failed, total failed tests: {0}, exit code: {1}, attempt: {2}/{3} ===================== Tests suite failed in all {0} attempts ===================== - + ===================== -Tests suite failed in all {0} attempts +測試套件在所有 {0} 次嘗試中都失敗 ===================== Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' - Test suite failed with and exit code different that 2 (failed tests). Failure related to an unexpected condition. Exit code '{0}' + 測試套件失敗,結束代碼與 2 不同 (測試失敗)。與未預期情况有關的失敗。結束代碼 '{0}' From 03868468ab7b00005e3d09c9c21908bae4c4832e Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Mon, 23 Dec 2024 01:28:30 -0800 Subject: [PATCH 163/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2606972 --- .../TestFramework/Resources/xlf/FrameworkMessages.cs.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.de.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.es.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.fr.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.it.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.ja.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.ko.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.pl.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.ru.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.tr.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf | 2 +- .../TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf index 088671ad85..efcae52e82 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.cs.xlf @@ -254,7 +254,7 @@ Skutečnost: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + Vlastnost nebo metoda {0} na návratovém typu {1} se nedá přiřadit k „IEnumerable“. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf index 92ad58b0e8..57407eec58 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.de.xlf @@ -254,7 +254,7 @@ Tatsächlich: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + Eigenschaft oder Methode {0} für {1} Rückgabetyp kann „IEnumerable“ nicht zugewiesen werden. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf index ab6c3262df..8a290bc795 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.es.xlf @@ -254,7 +254,7 @@ Real: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + La propiedad o el método {0} en el tipo de retorno {1} no se puede asignar a "IEnumerable". diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf index 749ee02e87..18dbed07b6 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.fr.xlf @@ -254,7 +254,7 @@ Réel : {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + La propriété ou la méthode {0} sur le type de retour {1} ne peut pas être attribuée à « IEnumerable ». diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf index 9e7406e31d..1006368d73 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.it.xlf @@ -254,7 +254,7 @@ Effettivo: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + La proprietà o il metodo {0} su {1} tipo restituito non è assegnabile a 'IEnumerable'. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf index 989996682a..b58f7b2049 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ja.xlf @@ -254,7 +254,7 @@ Actual: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + {1} 戻り値の型のプロパティまたはメソッド {0} は、'IEnumerable' に割り当てできません。 diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf index fe9b7199cb..fe070e4435 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ko.xlf @@ -254,7 +254,7 @@ Actual: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + {1} 반환 형식의 속성 또는 메서드 {0}은(는) 'IEnumerable'에 할당할 수 없습니다. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf index ec4aaa9fb6..e4b1caef63 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pl.xlf @@ -254,7 +254,7 @@ Rzeczywiste: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + Właściwości lub metody {0} dla zwracanego typu {1} nie można przypisać do elementu „IEnumerable”. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf index 372e307848..9adbd43bab 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.pt-BR.xlf @@ -254,7 +254,7 @@ Real: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + A propriedade ou o método {0} no tipo de retorno {1} não podem ser atribuídos a "IEnumerable". diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf index fe3737cf89..5c4480127b 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.ru.xlf @@ -254,7 +254,7 @@ Actual: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + Свойство или метод {0} в {1} тип возвращаемого значения не может быть назначен "IEnumerable". diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf index e8e420d934..b6bd361bb9 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.tr.xlf @@ -254,7 +254,7 @@ Gerçekte olan: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + {1} dönüş türündeki {0} özelliği veya yöntemi 'IEnumerable' öğesine atanamaz. diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf index b4c6af2102..3743d96cd0 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hans.xlf @@ -254,7 +254,7 @@ Actual: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + {1} 返回类型上的属性或方法 {0} 不能分配给 "IEnumerable"。 diff --git a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf index d2e361b7fa..8ab05baa18 100644 --- a/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf +++ b/src/TestFramework/TestFramework/Resources/xlf/FrameworkMessages.zh-Hant.xlf @@ -254,7 +254,7 @@ Actual: {2} Property or method {0} on {1} return type is not assignable to 'IEnumerable'. - Property or method {0} on {1} return type is not assignable to 'IEnumerable'. + {1} 傳回類型上的屬性或方法 {0} 無法指派給 'IEnumerable'。 From d3a3c36bf114573876786d771f9b45e64757d8ad Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 23 Dec 2024 21:44:39 +1100 Subject: [PATCH 164/273] use EnumPolyfill.IsDefined (#4418) --- src/Adapter/MSTest.TestAdapter/MSTestSettings.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs index 1be800f802..b773252ee3 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs +++ b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs @@ -865,11 +865,7 @@ private static void SetParallelSettings(XmlReader reader, MSTestSettings setting private static bool TryParseEnum(string value, out T result) where T : struct, Enum => Enum.TryParse(value, true, out result) -#if NET6_0_OR_GREATER - && Enum.IsDefined(result); -#else - && Enum.IsDefined(typeof(T), result); -#endif + && EnumPolyfill.IsDefined(result); private static void SetGlobalSettings( [StringSyntax(StringSyntaxAttribute.Xml, nameof(runsettingsXml))] string runsettingsXml, From 811d01491dfad473d9e99bb8a5a996506ff1def1 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 23 Dec 2024 21:46:22 +1100 Subject: [PATCH 165/273] use polyfill in TestFramework.ForTestingMSTest (#4412) --- .../CallerArgumentExpressionAttribute.cs | 27 ------------- .../CodeAnalysisAttributes.cs | 26 ------------- .../DoesNotReturnIfAttribute.cs | 39 ------------------- .../TestFramework.ForTestingMSTest.csproj | 1 + 4 files changed, 1 insertion(+), 92 deletions(-) delete mode 100644 test/Utilities/TestFramework.ForTestingMSTest/CallerArgumentExpressionAttribute.cs delete mode 100644 test/Utilities/TestFramework.ForTestingMSTest/CodeAnalysisAttributes.cs delete mode 100644 test/Utilities/TestFramework.ForTestingMSTest/DoesNotReturnIfAttribute.cs diff --git a/test/Utilities/TestFramework.ForTestingMSTest/CallerArgumentExpressionAttribute.cs b/test/Utilities/TestFramework.ForTestingMSTest/CallerArgumentExpressionAttribute.cs deleted file mode 100644 index 2ca70c0553..0000000000 --- a/test/Utilities/TestFramework.ForTestingMSTest/CallerArgumentExpressionAttribute.cs +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#if !NET5_0 && !NET6_0 -namespace System.Runtime.CompilerServices; - -/// -/// Allows capturing of the expressions passed to a method. -/// -[AttributeUsage(AttributeTargets.Parameter)] -internal sealed class CallerArgumentExpressionAttribute : Attribute -{ - /// - /// Initializes a new instance of the class. - /// - /// The name of the targeted parameter. - public CallerArgumentExpressionAttribute(string parameterName) => ParameterName = parameterName; - - /// - /// Gets the target parameter name of the CallerArgumentExpression. - /// - /// - /// The name of the targeted parameter of the CallerArgumentExpression. - /// - public string ParameterName { get; } -} -#endif diff --git a/test/Utilities/TestFramework.ForTestingMSTest/CodeAnalysisAttributes.cs b/test/Utilities/TestFramework.ForTestingMSTest/CodeAnalysisAttributes.cs deleted file mode 100644 index 42657395bd..0000000000 --- a/test/Utilities/TestFramework.ForTestingMSTest/CodeAnalysisAttributes.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#if !NETCOREAPP3_0_OR_GREATER -namespace System.Diagnostics.CodeAnalysis; - -/// Applied to a method that will never return under any circumstance. -[AttributeUsage(AttributeTargets.Method, Inherited = false)] -internal sealed class DoesNotReturnAttribute : Attribute; - -/// Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. -[AttributeUsage(AttributeTargets.Parameter)] -internal sealed class NotNullWhenAttribute : Attribute -{ - /// - /// Initializes a new instance of the class.Initializes the attribute with the specified return value condition. - /// - /// - /// The return value condition. If the method returns this value, the associated parameter will not be null. - /// - public NotNullWhenAttribute(bool returnValue) => ReturnValue = returnValue; - - /// Gets a value indicating whether gets to return value condition. - public bool ReturnValue { get; } -} -#endif diff --git a/test/Utilities/TestFramework.ForTestingMSTest/DoesNotReturnIfAttribute.cs b/test/Utilities/TestFramework.ForTestingMSTest/DoesNotReturnIfAttribute.cs deleted file mode 100644 index bb519abe20..0000000000 --- a/test/Utilities/TestFramework.ForTestingMSTest/DoesNotReturnIfAttribute.cs +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT license. See LICENSE file in the project root for full license information. - -#if NETSTANDARD2_0 || NETFRAMEWORK - -#pragma warning disable SA1623 // Remove ridiculous stylecop documentation warning -namespace System.Diagnostics.CodeAnalysis; - -/// -/// Specifies that the method will not return if the associated -/// parameter is passed the specified value. -/// -[ExcludeFromCodeCoverage] -[DebuggerNonUserCode] -[AttributeUsage(AttributeTargets.Parameter)] -public sealed class DoesNotReturnIfAttribute : - Attribute -{ - /// - /// Gets the condition parameter value. - /// Code after the method is considered unreachable by diagnostics if the argument - /// to the associated parameter matches this value. - /// - public bool ParameterValue { get; } - - /// - /// Initializes a new instance of the - /// class with the specified parameter value. - /// - /// - /// The condition parameter value. - /// Code after the method is considered unreachable by diagnostics if the argument - /// to the associated parameter matches this value. - /// - public DoesNotReturnIfAttribute(bool parameterValue) => - ParameterValue = parameterValue; -} - -#endif diff --git a/test/Utilities/TestFramework.ForTestingMSTest/TestFramework.ForTestingMSTest.csproj b/test/Utilities/TestFramework.ForTestingMSTest/TestFramework.ForTestingMSTest.csproj index 02afe9633d..cb92c85954 100644 --- a/test/Utilities/TestFramework.ForTestingMSTest/TestFramework.ForTestingMSTest.csproj +++ b/test/Utilities/TestFramework.ForTestingMSTest/TestFramework.ForTestingMSTest.csproj @@ -10,6 +10,7 @@ + From cc1acfd734fd2d539254a1d511b20a00af98539c Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 23 Dec 2024 21:51:18 +1100 Subject: [PATCH 166/273] use EnumPolyfill.GetNames correctly (#4413) --- .../MSTest.TestAdapter/MSTestSettings.cs | 32 ++++--------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs index b773252ee3..ac899af772 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs +++ b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs @@ -503,11 +503,7 @@ private static MSTestSettings ToSettings(XmlReader reader, IMessageLogger? logge CultureInfo.CurrentCulture, Resource.InvalidClassCleanupLifecycleValue, value, -#if NET - string.Join(", ", Enum.GetNames()))); -#else string.Join(", ", EnumPolyfill.GetNames()))); -#endif break; } @@ -834,11 +830,7 @@ private static void SetParallelSettings(XmlReader reader, MSTestSettings setting CultureInfo.CurrentCulture, Resource.InvalidParallelScopeValue, value, -#if NET - string.Join(", ", Enum.GetNames()))); -#else string.Join(", ", EnumPolyfill.GetNames()))); -#endif break; } @@ -987,22 +979,16 @@ internal static void SetSettingsFromConfig(IConfiguration configuration, IMessag if (configuration["mstest:classCleanupLifecycle"] is string classCleanupLifecycle) { - if (TryParseEnum(classCleanupLifecycle, out ClassCleanupBehavior lifecycle)) - { - settings.ClassCleanupLifecycle = lifecycle; - } - else + if (!TryParseEnum(classCleanupLifecycle, out ClassCleanupBehavior lifecycle)) { throw new AdapterSettingsException(string.Format( CultureInfo.CurrentCulture, Resource.InvalidClassCleanupLifecycleValue, classCleanupLifecycle, -#if NET - string.Join(", ", Enum.GetNames()))); -#else string.Join(", ", EnumPolyfill.GetNames()))); -#endif } + + settings.ClassCleanupLifecycle = lifecycle; } if (configuration["mstest:parallelism:workers"] is string workers) @@ -1026,22 +1012,16 @@ internal static void SetSettingsFromConfig(IConfiguration configuration, IMessag { value = value.Equals("class", StringComparison.OrdinalIgnoreCase) ? "ClassLevel" : value.Equals("methood", StringComparison.OrdinalIgnoreCase) ? "MethodLevel" : value; - if (TryParseEnum(value, out ExecutionScope scope)) - { - settings.ParallelizationScope = scope; - } - else + if (!TryParseEnum(value, out ExecutionScope scope)) { throw new AdapterSettingsException(string.Format( CultureInfo.CurrentCulture, Resource.InvalidParallelScopeValue, value, -#if NET - string.Join(", ", Enum.GetNames()))); -#else string.Join(", ", EnumPolyfill.GetNames()))); -#endif } + + settings.ParallelizationScope = scope; } MSTestSettingsProvider.Load(configuration); From 530bee336bcda0ff3734d48385051ee8b78c1cdd Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Mon, 23 Dec 2024 23:38:59 +1100 Subject: [PATCH 167/273] UnreachableException is more correct (#4431) --- .../MSTest.Analyzers/Helpers/ApplicationStateGuard.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/ApplicationStateGuard.cs b/src/Analyzers/MSTest.Analyzers/Helpers/ApplicationStateGuard.cs index 39acf92967..02826efc45 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/ApplicationStateGuard.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/ApplicationStateGuard.cs @@ -1,12 +1,13 @@ // 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.Diagnostics; using System.Runtime.CompilerServices; namespace MSTest.Analyzers.Helpers; internal static class ApplicationStateGuard { - public static InvalidOperationException Unreachable([CallerFilePath] string? path = null, [CallerLineNumber] int line = 0) + public static UnreachableException Unreachable([CallerFilePath] string? path = null, [CallerLineNumber] int line = 0) => new($"This program location is thought to be unreachable. File='{path}' Line={line}"); } From d0e61e2674a8c24c8a0be3bd6b2bc7538ce66621 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 24 Dec 2024 03:02:39 +1100 Subject: [PATCH 168/273] leverage some global usings (#4424) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- Directory.Build.props | 17 +++++++++++++++++ samples/FxExtensibility/AssertEx.cs | 3 --- samples/FxExtensibility/AssertIs.cs | 2 -- .../FxExtensibility/Properties/AssemblyInfo.cs | 2 -- samples/Playground/DebuggerUtility.cs | 6 ------ samples/Playground/Program.cs | 2 -- samples/Playground/ServerMode/LogsCollector.cs | 2 -- .../Playground/ServerMode/TelemetryCollector.cs | 2 -- .../ServerMode/TestNodeUpdateCollector.cs | 2 -- .../ServerMode/TestingPlatformClientFactory.cs | 4 ---- .../Playground/ServerMode/v1.0.0/ClientInfo.cs | 2 -- .../ServerMode/v1.0.0/InitializeRequest.cs | 2 -- .../Playground/ServerMode/v1.0.0/RpcListener.cs | 2 -- .../Playground/ServerMode/v1.0.0/ServerInfo.cs | 2 -- .../ServerMode/v1.0.0/TestingPlatformClient.cs | 3 --- .../Discovery/AssemblyEnumerator.cs | 4 ---- .../Discovery/AssemblyEnumeratorWrapper.cs | 3 --- .../Discovery/TestMethodValidator.cs | 4 ---- .../Discovery/TypeEnumerator.cs | 4 ---- .../Discovery/TypeValidator.cs | 4 ---- .../Discovery/UnitTestDiscoverer.cs | 3 --- .../MSTest.TestAdapter/DynamicDataOperations.cs | 8 -------- .../Execution/ClassCleanupManager.cs | 3 --- .../Execution/ExceptionHelper.cs | 4 ---- .../Execution/LogMessageListener.cs | 3 --- .../Execution/TestAssemblyInfo.cs | 4 ---- .../Execution/TestAssemblySettingsProvider.cs | 1 - .../Execution/TestCaseDiscoverySink.cs | 9 +-------- .../Execution/TestClassInfo.cs | 5 ----- .../Execution/TestExecutionManager.cs | 5 ----- .../Execution/TestMethodInfo.cs | 6 ------ .../Execution/TestMethodRunner.cs | 4 ---- .../Execution/TestRunCancellationToken.cs | 2 -- .../MSTest.TestAdapter/Execution/TypeCache.cs | 5 ----- .../Execution/UnitTestRunner.cs | 3 --- .../Extensions/ExceptionExtensions.cs | 4 ---- .../Extensions/MethodInfoExtensions.cs | 4 ---- src/Adapter/MSTest.TestAdapter/Friends.cs | 2 -- .../Helpers/DataSerializationHelper.cs | 2 -- .../Helpers/FixtureMethodRunner.cs | 4 ---- .../MSTest.TestAdapter/Helpers/ReflectHelper.cs | 4 ---- .../Helpers/RunSettingsUtilities.cs | 4 ---- .../Helpers/TestRunParameters.cs | 3 --- .../MSTest.TestAdapter.csproj | 1 + .../MSTest.TestAdapter/MSTestSettings.cs | 5 ----- .../ObjectModel/TestMethod.cs | 1 - .../ObjectModel/UnitTestElement.cs | 3 --- .../ObjectModel/UnitTestResult.cs | 3 --- .../PlatformServiceProvider.cs | 2 -- .../RunConfigurationSettings.cs | 5 ----- .../SourceGeneratedFileOperations.cs | 2 -- .../SourceGeneratedReflectionDataProvider.cs | 2 -- .../SourceGeneratedReflectionOperations.cs | 2 -- .../MSTest.TestAdapter/TestMethodFilter.cs | 2 -- .../MSTestBannerCapability.cs | 3 --- .../MSTestBridgedTestFramework.cs | 3 --- .../TestingPlatformAdapter/MSTestExtension.cs | 2 -- .../TestApplicationBuilderExtensions.cs | 2 -- .../TestingPlatformBuilderHook.cs | 2 -- .../VSTestAdapter/MSTestExecutor.cs | 2 -- .../AssemblyResolver.cs | 2 -- .../Data/CsvDataConnection.cs | 4 ---- .../Data/TestDataConnection.cs | 3 --- .../Data/TestDataConnectionSql.cs | 4 ---- .../Data/XmlDataConnection.cs | 4 ---- .../Deployment/AssemblyLoadWorker.cs | 3 --- .../Deployment/DeploymentItem.cs | 1 - .../Deployment/TestRunDirectories.cs | 2 -- .../MSTestAdapter.PlatformServices/Friends.cs | 2 -- .../Interfaces/IFileOperations.cs | 2 -- .../Interfaces/IReflectionOperations.cs | 3 --- .../Interfaces/IReflectionOperations2.cs | 2 -- .../Interfaces/ISettingsProvider.cs | 2 -- .../Interfaces/ITestDeployment.cs | 2 -- .../Interfaces/ITestSource.cs | 2 -- .../Interfaces/ITestSourceHost.cs | 2 -- .../Properties/AssemblyInfo.cs | 9 --------- .../RecursiveDirectoryPath.cs | 1 - .../Services/DiaSessionOperations.cs | 2 -- .../Services/ExecutionContextService.cs | 3 --- .../Services/FileOperations.cs | 3 --- .../Services/MSTestAdapterSettings.cs | 2 -- .../Services/ReflectionOperations.cs | 6 ------ .../Services/ReflectionOperations2.cs | 2 -- .../Services/SettingsProvider.cs | 5 ----- .../Services/TestContextImplementation.cs | 2 -- .../Services/TestDataSource.cs | 2 -- .../Services/TestDeployment.cs | 3 --- .../Services/TestSource.cs | 2 -- .../Services/TestSourceHost.cs | 2 -- .../Services/ThreadOperations.cs | 4 ---- .../Services/ThreadSafeStringWriter.cs | 2 -- .../Services/TraceListener.cs | 4 ---- .../Services/TraceListenerManager.cs | 4 ---- .../Utilities/AppDomainUtilities.cs | 4 ---- .../Utilities/ApplicationStateGuard.cs | 3 --- .../Utilities/AssemblyUtility.cs | 4 ---- .../Utilities/DeploymentItemUtility.cs | 5 ----- .../Utilities/DeploymentUtility.cs | 4 ---- .../Utilities/DeploymentUtilityBase.cs | 3 --- .../Utilities/FileUtility.cs | 3 --- .../Utilities/IAssemblyUtility.cs | 2 -- .../Utilities/RandomIntPermutation.cs | 3 --- .../Utilities/ReflectionUtility.cs | 6 ------ .../Utilities/SequentialIntPermutation.cs | 2 -- .../Utilities/VSInstallationUtilities.cs | 3 --- .../Utilities/XmlUtilities.cs | 6 ------ .../UseProperAssertMethodsFixer.cs | 2 -- .../Helpers/ApplicationStateGuard.cs | 3 --- .../RoslynAnalyzerHelpers/ArrayBuilder.cs | 2 -- .../CompilationExtensions.cs | 2 -- .../DiagnosticExtensions.cs | 1 - .../IMethodSymbolExtensions.cs | 2 -- .../IOperationExtensions.cs | 4 ---- .../ITypeSymbolExtensions.cs | 2 -- .../RoslynAnalyzerHelpers/ObjectPool.cs | 2 -- .../PerformanceSensitiveAttribute.cs | 1 - .../RoslynAnalyzerHelpers/PooledHashSet.cs | 2 -- .../RoslynAnalyzerHelpers/RoslynDebug.cs | 3 --- .../WellKnownTypeProvider.cs | 3 --- .../UseProperAssertMethodsAnalyzer.cs | 1 - .../MSTestObsoleteTypesSuppressor.cs | 1 - .../CrashDumpCommandLineProvider.cs | 2 -- .../CrashDumpEnvironmentVariableProvider.cs | 2 -- .../CrashDumpProcessLifetimeHandler.cs | 2 -- .../HangDumpActivityIndicator.cs | 3 --- .../HangDumpCommandLineProvider.cs | 2 -- .../HangDumpEnvironmentVariableProvider.cs | 2 -- .../HangDumpProcessLifetimeHandler.cs | 5 ----- .../Helpers/FNV1HashHelper.cs | 2 -- .../WindowsMiniDumpWriteDump.cs | 4 ---- .../MSBuildConsumer.cs | 3 --- .../MSBuildTestApplicationLifecycleCallbacks.cs | 2 -- .../RetryCommandLineOptionsProvider.cs | 2 -- .../RetryOrchestrator.cs | 4 ---- .../AppInsightsProvider.cs | 4 ---- .../AppInsightsTelemetryProviderExtensions.cs | 4 ---- .../GlobalSuppressions.cs | 2 -- .../TrxCompareTool.CommandLine.cs | 2 -- .../TrxCompareTool.cs | 4 ---- .../TrxDataConsumer.cs | 2 -- .../TrxEnvironmentVariableProvider.cs | 2 -- .../TrxProcessLifetimeHandler.cs | 2 -- .../TrxReportEngine.cs | 4 ---- .../TrxTestApplicationLifecycleCallbacks.cs | 2 -- .../RunSettingsCommandLineOptionsProvider.cs | 2 -- ...stRunParametersCommandLineOptionsProvider.cs | 2 -- .../RunSettingsConfigurationProvider.cs | 2 -- .../Helpers/DebugUtils.cs | 2 -- .../ObjectModel/Condition.cs | 4 ---- .../ObjectModel/ContextAdapterBase.cs | 2 -- .../ObjectModel/FastFilter.cs | 3 --- .../ObjectModel/FilterExpression.cs | 6 ------ .../ObjectModel/FilterExpressionWrapper.cs | 3 --- .../ObjectModel/ObjectModelConverters.cs | 2 -- .../ObjectModel/RunContextAdapter.cs | 4 ---- .../ObjectModel/RunSettingsAdapter.cs | 3 --- .../ObjectModel/RunSettingsPatcher.cs | 2 -- ...SingleSessionVSTestAndTestAnywhereAdapter.cs | 3 --- .../RunSettingsEnvironmentVariableProvider .cs | 2 -- .../Tasks/DotnetMuxerLocator.cs | 4 ---- .../Tasks/FailedTestHelper.cs | 3 --- .../Tasks/InvokeTestingPlatformTask.cs | 5 ----- .../Tasks/MSBuildCompatibilityHelper.cs | 2 -- .../Tasks/StackTraceHelper.cs | 5 ----- .../TestingPlatformAutoRegisteredExtensions.cs | 4 ---- .../Tasks/TestingPlatformEntryPointTask.cs | 2 -- .../Builder/TestApplication.cs | 9 --------- .../IBannerMessageOwnerCapability.cs | 2 -- .../IGracefulStopTestExecutionCapability.cs | 2 -- .../TestFrameworkCapabilitiesExtensions.cs | 2 -- .../CommandLine/CommandLineHandler.cs | 5 ----- .../CommandLine/CommandLineOption.cs | 3 --- .../CommandLine/CommandLineOptionsProxy.cs | 2 -- .../CommandLine/CommandLineOptionsValidator.cs | 3 --- .../CommandLine/ICommandLineManager.cs | 2 -- .../CommandLine/ICommandLineOptions.cs | 2 -- .../MaxFailedTestsCommandLineOptionsProvider.cs | 2 -- .../CommandLine/ParseResult.cs | 4 ---- .../CommandLine/Parser.cs | 2 -- .../CommandLine/PlatformCommandLineProvider.cs | 3 --- .../CommandLine/ResponseFileHelper.cs | 3 --- ...EnvironmentVariablesConfigurationProvider.cs | 3 --- .../JsonConfigurationFileParser.cs | 2 -- .../JsonConfigurationFileParser.netstandard.cs | 2 -- .../Configurations/JsonConfigurationProvider.cs | 2 -- .../Extensions/ValidationResult.cs | 2 -- .../GlobalSuppressions.cs | 2 -- .../Helpers/ActionResult.cs | 2 -- .../Helpers/ApplicationStateGuard.cs | 4 ---- .../Helpers/ArgumentGuard.cs | 2 -- .../Helpers/EnvironmentVariableConstants.cs | 2 -- .../NonCooperativeParentProcessListener.cs | 3 --- .../Helpers/ObjectPool.cs | 7 ------- .../Helpers/RoslynDebug.cs | 3 --- .../Helpers/RoslynHashCode.cs | 2 -- .../Helpers/RoslynString.cs | 2 -- .../Helpers/Sha256Hasher.cs | 2 -- .../Helpers/System/IEnvironment.cs | 2 -- .../Helpers/System/IProcessHandler.cs | 2 -- .../Helpers/System/ITask.cs | 2 -- .../Helpers/System/SystemConsole.cs | 4 ---- .../Helpers/System/SystemEnvironment.cs | 3 --- .../Helpers/System/SystemMainModule.cs | 2 -- .../Helpers/System/SystemProcess.cs | 2 -- .../Helpers/System/SystemProcessHandler.cs | 4 ---- .../Helpers/System/SystemRuntimeFeature.cs | 4 ---- .../Helpers/System/SystemStopwatch.cs | 2 -- .../Helpers/TaskExtensions.cs | 3 --- .../Helpers/TestApplicationBuilderExtensions.cs | 2 -- .../Helpers/TimeSpanParser.cs | 2 -- .../Helpers/UILanguageOverride.cs | 2 -- .../Hosts/ConsoleTestHost.cs | 3 --- .../Hosts/ServerTestHost.cs | 3 --- .../Hosts/TestFrameworkProxy.cs | 2 -- .../Hosts/TestHostBuilder.cs | 5 ----- .../Hosts/TestHostControllersTestHost.cs | 4 ---- .../Hosts/ToolsTestHost.cs | 4 ---- .../IPC/NamedPipeBase.cs | 2 -- .../IPC/NamedPipeClient.cs | 1 - .../IPC/NamedPipeServer.cs | 2 -- .../IPC/Serializers/BaseSerializer.cs | 2 -- .../Logging/FileLogger.cs | 5 ----- .../Logging/ServerLogMessage.cs | 2 -- .../Logging/ServerLogMessageInMemoryStore.cs | 3 --- .../Logging/TypeNameHelper.cs | 3 --- .../Messages/AsynchronousMessageBus.cs | 4 ---- .../Messages/ChannelConsumerDataProcessor.cs | 1 - .../ConsumingEnumerableConsumerDataProcessor.cs | 2 -- .../Messages/DataWithSessionUid.cs | 2 -- .../Messages/FileArtifacts.cs | 2 -- .../Messages/MessageBusProxy.cs | 2 -- .../Messages/PropertyBag.Property.cs | 3 --- .../PropertyBag.PropertyBagEnumerable.cs | 2 -- .../Messages/PropertyBag.cs | 2 -- .../Messages/PropertyBagData.cs | 2 -- .../Messages/TestNode.cs | 2 -- .../Messages/TestNodeProperties.cs | 2 -- .../Messages/TestNodeUpdateMessage.cs | 2 -- .../Messages/TestRequestExecutionTimeInfo.cs | 2 -- .../OutputDevice/TargetFrameworkParser.cs | 2 -- .../OutputDevice/Terminal/AnsiDetector.cs | 2 -- .../OutputDevice/Terminal/AnsiTerminal.cs | 4 ---- .../Terminal/AnsiTerminalTestProgressFrame.cs | 2 -- .../OutputDevice/Terminal/FileUtilities.cs | 2 -- .../Terminal/HumanReadableDurationFormatter.cs | 3 --- .../OutputDevice/Terminal/NativeMethods.cs | 3 --- .../OutputDevice/Terminal/NonAnsiTerminal.cs | 3 --- .../Terminal/TerminalTestReporter.cs | 9 --------- .../Terminal/TestNodeResultsState.cs | 3 --- .../OutputDevice/TerminalOutputDevice.cs | 6 ------ .../IExecuteRequestCompletionNotifier.cs | 2 -- .../Requests/NopFilter.cs | 2 -- .../Requests/TestHostTestFrameworkInvoker.cs | 3 --- .../Requests/TreeNodeFilter/TreeNodeFilter.cs | 5 ----- .../ValueAndPropertyExpression.cs | 2 -- .../Requests/TreeNodeFilter/ValueExpression.cs | 3 --- .../DotnetTest/DotnetTestConnection.cs | 3 --- .../ServerMode/JsonRpc/ErrorCodes.cs | 2 -- .../ServerMode/JsonRpc/Json/Json.cs | 2 -- .../ServerMode/JsonRpc/MessageHandlerFactory.cs | 1 - .../ServerMode/JsonRpc/PassiveNode.cs | 2 -- .../PerRequestServerDataConsumerService.cs | 2 -- .../ServerMode/JsonRpc/ServerModeManager.cs | 2 -- .../JsonRpc/ServerModePerCallOutputDevice.cs | 4 ---- .../ServerMode/JsonRpc/StreamMessageHandler.cs | 2 -- .../CurrentTestApplicationModuleInfo.cs | 7 ------- .../Services/IClientInfo.cs | 2 -- .../Services/IPlatformInformation.cs | 4 ---- .../Services/ServiceProvider.cs | 2 -- .../Services/ServiceProviderExtensions.cs | 3 --- .../Services/StopPoliciesService.cs | 2 -- .../Services/TestApplicationResult.cs | 2 -- .../Telemetry/ExtensionInformationCollector.cs | 1 - .../TestFramework/ExecuteRequestContext.cs | 2 -- .../TestHost/TestHostManager.cs | 2 -- .../TestHostControllers/EnvironmentVariables.cs | 3 --- .../IReadOnlyEnvironmentVariables.cs | 2 -- .../SystemEnvironmentVariableProvider.cs | 2 -- .../TestHostControllerInfo.cs | 2 -- .../TestHostControllersManager.cs | 2 -- .../TestHostOrchestratorManager.cs | 2 -- .../TestFramework.Extensions/AppModel.cs | 4 ---- .../Attributes/UWP_UITestMethodAttribute.cs | 1 - .../Attributes/WinUITestTargetAttribute.cs | 1 - .../Attributes/WinUI_UITestMethodAttribute.cs | 3 --- .../DataSourceElementCollection.cs | 1 - .../TestFramework.Extensions/Friends.cs | 2 -- .../TestFramework.Extensions/PrivateObject.cs | 3 --- .../TestFramework.Extensions/PrivateType.cs | 3 --- .../Properties/AssemblyInfo.cs | 6 ------ .../RuntimeTypeHelper.cs | 2 -- .../TestFramework.Extensions/TestContext.cs | 3 --- .../TestFramework/Assertions/Assert.AreEqual.cs | 3 --- .../TestFramework/Assertions/Assert.AreSame.cs | 3 --- .../TestFramework/Assertions/Assert.Fail.cs | 2 -- .../Assertions/Assert.Inconclusive.cs | 3 --- .../Assertions/Assert.IsInstanceOfType.cs | 3 --- .../TestFramework/Assertions/Assert.IsNull.cs | 2 -- .../TestFramework/Assertions/Assert.IsTrue.cs | 2 -- .../Assertions/Assert.ThrowsException.cs | 2 -- .../TestFramework/Assertions/Assert.cs | 3 --- .../Assertions/CollectionAssert.cs | 5 ----- .../TestFramework/Assertions/StringAssert.cs | 4 ---- .../Attributes/DataSource/DataRowAttribute.cs | 2 -- .../DataSource/DataSourceAttribute.cs | 2 -- .../DataSource/DynamicDataAttribute.cs | 2 -- .../DataSource/DynamicDataProvider.cs | 2 -- .../DataSource/IDynamicDataOperations.cs | 2 -- .../TestMethod/ExpectedExceptionAttribute.cs | 2 -- .../ExpectedExceptionBaseAttribute.cs | 3 --- .../TestMethod/TestCategoryAttribute.cs | 2 -- .../Attributes/TestMethod/TestTimeout.cs | 2 -- src/TestFramework/TestFramework/Friends.cs | 2 -- .../TestFramework/GenericParameterHelper.cs | 3 --- .../EmptyDataSourceExceptionInfoExtensions.cs | 3 --- .../TestFramework/Interfaces/ITestDataSource.cs | 2 -- ...estDataSourceEmptyDataSourceExceptionInfo.cs | 2 -- .../TestFramework/Interfaces/ITestMethod.cs | 2 -- .../TestFramework/Internal/DebugEx.cs | 3 --- .../Internal/ReflectionTestMethodInfo.cs | 3 --- .../TestFramework/Internal/StringEx.cs | 2 -- .../Internal/TestDataSourceUtilities.cs | 4 ---- .../TestFramework/Internal/UtfHelper.cs | 4 ---- src/TestFramework/TestFramework/Logger.cs | 4 ---- .../AbortionTests.cs | 2 -- .../GenericTestMethodTests.cs | 2 -- .../InitializeAndCleanupTimeoutTests.cs | 2 -- .../MaxFailedTestsExtensionTests.cs | 3 --- .../NativeAotTests.cs | 2 -- .../Program.cs | 3 --- .../RunsettingsTests.cs | 2 -- .../STATestClassTests.cs | 2 -- .../STATestMethodTests.cs | 2 -- .../SdkTests.cs | 2 -- .../ServerMode/LogsCollector.cs | 2 -- .../ServerMode/ServerModeTestsBase.cs | 4 ---- .../ServerMode/TelemetryCollector.cs | 2 -- .../ServerMode/TestNodeUpdateCollector.cs | 2 -- .../ServerMode/v1.0.0/ClientInfo.cs | 2 -- .../ServerMode/v1.0.0/InitializeRequest.cs | 2 -- .../ServerMode/v1.0.0/RpcListener.cs | 2 -- .../ServerMode/v1.0.0/ServerInfo.cs | 2 -- .../ServerMode/v1.0.0/TestingPlatformClient.cs | 3 --- .../ThreadingTests.cs | 2 -- .../MSTest.IntegrationTests/OutputTests.cs | 2 -- .../Utilities/CLITestBase.discovery.cs | 2 -- .../Utilities/TestCaseFilterFactory.cs | 3 --- .../DeploymentTests.cs | 2 -- .../Parameterized tests/DataSourceTests.cs | 2 -- .../AbortionTests.cs | 2 -- .../CrashDumpTests.cs | 2 -- .../CrashPlusHangDumpTests.cs | 2 -- .../DiagnosticTests.cs | 2 -- .../ExecutionTests.cs | 2 -- .../ExitOnProcessExitTests.cs | 2 -- .../HangDumpOutputTests.cs | 2 -- .../HangDumpTests.cs | 2 -- .../Helpers/AcceptanceAssert.cs | 4 ---- .../Helpers/AcceptanceTestBase.cs | 5 ----- .../MSBuildTests.ConfigurationFile.cs | 2 -- .../MSBuildTests.Test.cs | 4 ---- .../Program.cs | 3 --- .../RetryFailedTestsTests.cs | 2 -- .../ServerLoggingTests.cs | 2 -- .../TelemetryTests.cs | 2 -- .../TrxTests.cs | 3 --- .../UnhandledExceptionPolicyTests.cs | 2 -- .../DesktopTestSourceHostTests.cs | 3 --- .../ReflectionUtilityTests.cs | 3 --- .../DataRowTests_DerivedClass.cs | 2 -- .../DataRowTestProject/DataRowTests_Enums.cs | 2 -- .../DataRowTests_OverriddenGetDisplayName.cs | 2 -- .../DynamicDataTestProject/DataProvider.cs | 2 -- .../DynamicDataTestProject/DynamicDataTests.cs | 2 -- .../FxExtensibilityTestProject/AssertExTest.cs | 2 -- .../TestDataSourceExTests.cs | 3 --- .../HierarchyProject/ClassWithNoNamespace.cs | 2 -- .../TestAssets/OutputTestProject/Assembly.cs | 2 ++ .../OutputTestProject/OutputTestProject.csproj | 1 + .../TestAssets/OutputTestProject/UnitTest1.cs | 2 -- .../TestAssets/OutputTestProject/UnitTest2.cs | 2 -- .../TestAssets/ParallelTestClass/Constants.cs | 2 ++ .../TestAssets/ParallelTestMethods/Constants.cs | 2 ++ .../LifeCycleAssemblyInitializeAndCleanup.cs | 2 -- .../LifeCycleClassCleanup.cs | 2 -- .../LifeCycleClassCleanupEndOfAssembly.cs | 2 -- ...nupEndOfAssemblyAndBeforeEachDerivedClass.cs | 3 --- ...LifeCycleClassCleanupEndOfAssemblyAndNone.cs | 3 --- .../LifeCycleClassCleanupEndOfClass.cs | 2 -- ...leanupEndOfClassAndBeforeEachDerivedClass.cs | 3 --- .../LifeCycleClassCleanupEndOfClassAndNone.cs | 3 --- ...nitializeAndCleanupBeforeEachDerivedClass.cs | 3 --- .../LifeCycleClassInitializeAndCleanupNone.cs | 3 --- ...BeforeEachDerivedClassAndClassCleanupNone.cs | 3 --- ...NoneAndClassCleanupBeforeEachDerivedClass.cs | 3 --- ...nupEndOfAssemblyAndBeforeEachDerivedClass.cs | 2 -- ...leDerivedClassCleanupEndOfAssemblyAndNone.cs | 2 -- ...leanupEndOfClassAndBeforeEachDerivedClass.cs | 2 -- ...CycleDerivedClassCleanupEndOfClassAndNone.cs | 2 -- ...nitializeAndCleanupBeforeEachDerivedClass.cs | 2 -- ...CycleDerivedClassInitializeAndCleanupNone.cs | 2 -- ...BeforeEachDerivedClassAndClassCleanupNone.cs | 2 -- ...NoneAndClassCleanupBeforeEachDerivedClass.cs | 2 -- .../TestIdCases.cs | 2 -- .../TestProject/Properties/AssemblyInfo.cs | 2 -- .../PipelinesRunner.cs | 2 -- .../MSTest.Performance.Runner/Program.cs | 1 - .../Scenarios/Scenario1.cs | 4 ---- .../Steps/ConcurrencyVisualizer.cs | 4 ---- .../Steps/DotnetTrace.cs | 2 -- .../Steps/PerfviewRunner.cs | 4 ---- .../Steps/PlainProcess.cs | 1 - .../Steps/VSDiagnostics.cs | 2 -- ...bleReferenceNotInitializedSuppressorTests.cs | 1 - .../MSTest.Analyzers.UnitTests/Program.cs | 2 -- ...yncSuffixTestFixtureMethodSuppressorTests.cs | 1 - .../UseAsyncSuffixTestMethodSuppressorTests.cs | 1 - .../Verifiers/CSharpCodeFixVerifier`2.cs | 2 -- .../AssemblyResolverTests.cs | 2 -- .../Deployment/AssemblyLoadWorkerTests.cs | 2 -- .../Deployment/DeploymentItemTests.cs | 2 -- .../Properties/AssemblyInfo.cs | 2 -- .../Services/DesktopFileOperationsTests.cs | 2 -- .../DesktopReflectionOperationsTests.cs | 3 --- .../Services/DesktopTestDeploymentTests.cs | 2 -- .../Services/DesktopTestSourceHostTests.cs | 1 - .../Services/DesktopTestSourceTests.cs | 2 -- .../Services/MSTestAdapterSettingsTests.cs | 2 -- .../Services/MSTestSettingsProviderTests.cs | 2 -- .../Services/ReflectionOperationsTests.cs | 2 -- .../Services/TestDeploymentTests.cs | 3 --- .../Services/ThreadSafeStringWriterTests.cs | 3 --- .../Services/TraceListenerManagerTests.cs | 2 -- .../Services/TraceListenerTests.cs | 2 -- .../Utilities/AppDomainUtilitiesTests.cs | 3 --- .../Utilities/DeploymentUtilityTests.cs | 3 --- .../Utilities/DesktopReflectionUtilityTests.cs | 3 --- .../Utilities/VSInstallationUtilitiesTests.cs | 2 -- .../Utilities/XmlUtilitiesTests.cs | 3 --- .../Utilities/ns13DeploymentItemUtilityTests.cs | 3 --- .../Utilities/ns13ReflectionUtilityTests.cs | 3 --- .../ns10TestSourceTests.cs | 2 -- .../Discovery/AssemblyEnumeratorTests.cs | 4 ---- .../Discovery/AssemblyEnumeratorWrapperTests.cs | 3 --- .../Discovery/TestMethodValidatorTests.cs | 3 --- ...Tests.MockedMethodInfoWithExtraAttributes.cs | 3 --- .../Discovery/TypeEnumeratorTests.cs | 3 --- .../Discovery/TypeValidatorTests.cs | 3 --- .../Discovery/UnitTestDiscovererTests.cs | 2 -- .../DynamicDataAttributeTests.cs | 5 ----- .../Execution/ClassCleanupManagerTests.cs | 2 -- .../Execution/TestAssemblyInfoTests.cs | 2 -- .../TestAssemblySettingsProviderTests.cs | 2 -- .../Execution/TestClassInfoTests.cs | 2 -- .../Execution/TestExecutionManagerTests.cs | 3 --- .../Execution/TestMethodFilterTests.cs | 2 -- .../Execution/TestMethodInfoTests.cs | 4 ---- .../Execution/TestMethodRunnerTests.cs | 5 ----- .../Execution/TypeCacheTests.cs | 3 --- .../Execution/UnitTestResultTest.cs | 2 -- .../Execution/UnitTestRunnerTests.cs | 4 ---- .../Extensions/ExceptionExtensionsTests.cs | 3 --- .../Extensions/MethodInfoExtensionsTests.cs | 4 ---- .../Extensions/TestCaseExtensionsTests.cs | 2 -- .../Helpers/ReflectHelperTests.cs | 2 -- .../MSTestAdapter.UnitTests.csproj | 4 ++++ .../MSTestDiscovererTests.cs | 2 -- .../MSTestExecutorTests.cs | 2 -- .../MSTestSettingsTests.cs | 2 -- .../ObjectModel/UnitTestResultTests.cs | 2 -- .../TestablePlatformServiceProvider.cs | 2 -- .../CrashDumpTests.cs | 2 -- .../HangDumpTests.cs | 2 -- .../Helpers/TestCommandLineOptions.cs | 2 -- .../Program.cs | 4 ++-- .../RetryTests.cs | 2 -- .../TrxCompareToolCommandLineTests.cs | 2 -- .../TrxTests.cs | 3 --- ...unSettingsCommandLineOptionsProviderTests.cs | 2 -- ...nParameterCommandLineOptionsProviderTests.cs | 2 -- .../ObjectModel/RunSettingsPatcherTests.cs | 3 --- .../Program.cs | 4 ++-- .../MSBuildTests.cs | 2 -- .../Program.cs | 2 -- .../CommandLine/CommandLineTests.cs | 2 -- .../PlatformCommandLineProviderTests.cs | 2 -- .../AggregatedConfigurationTests.cs | 2 -- .../Configuration/ConfigurationManagerTests.cs | 2 -- .../Helpers/SystemAsyncMonitorTests.cs | 2 -- .../Helpers/TestCommandLineOptions.cs | 2 -- .../Logging/FileLoggerTests.cs | 4 ---- .../Logging/LoggerTests.cs | 2 -- .../Terminal/TerminalTestReporterTests.cs | 3 --- .../Program.cs | 4 ++-- .../ServerMode/FormatterUtilitiesTests.cs | 2 -- .../ServerMode/ServerTests.cs | 1 - .../TestApplicationBuilderTests.cs | 2 -- .../Assertions/AssertTests.AreEqualTests.cs | 3 --- .../Assertions/AssertTests.InconclusiveTests.cs | 2 -- .../AssertTests.IsInstanceOfTypeTests.cs | 2 -- .../Assertions/CollectionAssertTests.cs | 1 - .../Assertions/StringAssertTests.cs | 3 --- .../Attributes/DataRowAttributeTests.cs | 2 -- .../Automation.CLI/CLITestBase.common.cs | 2 -- .../Utilities/Automation.CLI/CLITestBase.e2e.cs | 2 -- .../Automation.CLI/DiscoveryEventsHandler.cs | 1 - .../Automation.CLI/Properties/AssemblyInfo.cs | 2 -- .../Automation.CLI/RunConfiguration.cs | 2 -- .../Automation.CLI/XmlRunSettingsUtilities.cs | 2 -- .../CommandLine.cs | 1 - .../Constants.cs | 2 -- .../DebuggerUtility.cs | 6 ------ .../DotnetCli.cs | 3 --- .../DotnetMuxerResult.cs | 2 -- .../ProcessFactory.cs | 2 -- .../ProcessHandle.cs | 2 -- .../ProjectSystem.cs | 4 ---- .../TargetFrameworks.cs | 2 -- .../TempDirectory.cs | 2 -- .../TestAssetFixtureBase.cs | 2 -- .../TestHost.cs | 4 ---- .../TestHostResult.cs | 2 -- .../AdapterToTestPlatform.cs | 4 ---- .../TestContainer.cs | 3 --- 525 files changed, 36 insertions(+), 1381 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 25e725ef65..a6ab7b17d8 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -67,4 +67,21 @@ 0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7 + + + + + + + + + + + + + + + + + diff --git a/samples/FxExtensibility/AssertEx.cs b/samples/FxExtensibility/AssertEx.cs index 595d001974..6e9abb7eb6 100644 --- a/samples/FxExtensibility/AssertEx.cs +++ b/samples/FxExtensibility/AssertEx.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace MSTest.Extensibility.Samples; diff --git a/samples/FxExtensibility/AssertIs.cs b/samples/FxExtensibility/AssertIs.cs index 91d3c662a7..eff6cfed75 100644 --- a/samples/FxExtensibility/AssertIs.cs +++ b/samples/FxExtensibility/AssertIs.cs @@ -1,8 +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.Globalization; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace MSTest.Extensibility.Samples; diff --git a/samples/FxExtensibility/Properties/AssemblyInfo.cs b/samples/FxExtensibility/Properties/AssemblyInfo.cs index d3592d292b..3c43a8702b 100644 --- a/samples/FxExtensibility/Properties/AssemblyInfo.cs +++ b/samples/FxExtensibility/Properties/AssemblyInfo.cs @@ -1,8 +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.Runtime.InteropServices; - // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. diff --git a/samples/Playground/DebuggerUtility.cs b/samples/Playground/DebuggerUtility.cs index 55fb8c75eb..5070a073d9 100644 --- a/samples/Playground/DebuggerUtility.cs +++ b/samples/Playground/DebuggerUtility.cs @@ -5,12 +5,6 @@ #pragma warning disable CA1837 // Use 'Environment.ProcessId' #pragma warning disable CA1416 // Validate platform compatibility -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; namespace Microsoft.Testing.TestInfrastructure; diff --git a/samples/Playground/Program.cs b/samples/Playground/Program.cs index 82315191c2..35fee852f9 100644 --- a/samples/Playground/Program.cs +++ b/samples/Playground/Program.cs @@ -1,8 +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.Reflection; - using Microsoft.Testing.Platform.Builder; using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.Extensions.TestFramework; diff --git a/samples/Playground/ServerMode/LogsCollector.cs b/samples/Playground/ServerMode/LogsCollector.cs index 037e12b643..8ac87d7e0a 100644 --- a/samples/Playground/ServerMode/LogsCollector.cs +++ b/samples/Playground/ServerMode/LogsCollector.cs @@ -1,8 +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.Concurrent; - using static Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100.TestingPlatformClient; namespace Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; diff --git a/samples/Playground/ServerMode/TelemetryCollector.cs b/samples/Playground/ServerMode/TelemetryCollector.cs index ac621b10fd..7b48806dc5 100644 --- a/samples/Playground/ServerMode/TelemetryCollector.cs +++ b/samples/Playground/ServerMode/TelemetryCollector.cs @@ -1,8 +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.Concurrent; - using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; namespace MSTest.Acceptance.IntegrationTests.Messages.V100; diff --git a/samples/Playground/ServerMode/TestNodeUpdateCollector.cs b/samples/Playground/ServerMode/TestNodeUpdateCollector.cs index 5943cf25fa..067a4f4410 100644 --- a/samples/Playground/ServerMode/TestNodeUpdateCollector.cs +++ b/samples/Playground/ServerMode/TestNodeUpdateCollector.cs @@ -1,8 +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.Concurrent; - using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; namespace MSTest.Acceptance.IntegrationTests.Messages.V100; diff --git a/samples/Playground/ServerMode/TestingPlatformClientFactory.cs b/samples/Playground/ServerMode/TestingPlatformClientFactory.cs index 2167bdefcd..44491c2798 100644 --- a/samples/Playground/ServerMode/TestingPlatformClientFactory.cs +++ b/samples/Playground/ServerMode/TestingPlatformClientFactory.cs @@ -1,12 +1,8 @@ // 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; -using System.Diagnostics; -using System.Globalization; using System.Net; using System.Net.Sockets; -using System.Text; using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; diff --git a/samples/Playground/ServerMode/v1.0.0/ClientInfo.cs b/samples/Playground/ServerMode/v1.0.0/ClientInfo.cs index a4548d891f..5acc6821ed 100644 --- a/samples/Playground/ServerMode/v1.0.0/ClientInfo.cs +++ b/samples/Playground/ServerMode/v1.0.0/ClientInfo.cs @@ -1,8 +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.Text.Json; - using Newtonsoft.Json; namespace Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; diff --git a/samples/Playground/ServerMode/v1.0.0/InitializeRequest.cs b/samples/Playground/ServerMode/v1.0.0/InitializeRequest.cs index abf5adb281..f15e94ab37 100644 --- a/samples/Playground/ServerMode/v1.0.0/InitializeRequest.cs +++ b/samples/Playground/ServerMode/v1.0.0/InitializeRequest.cs @@ -1,8 +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.Text.Json; - using Newtonsoft.Json; namespace Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; diff --git a/samples/Playground/ServerMode/v1.0.0/RpcListener.cs b/samples/Playground/ServerMode/v1.0.0/RpcListener.cs index 6bed732b68..e4eca6facb 100644 --- a/samples/Playground/ServerMode/v1.0.0/RpcListener.cs +++ b/samples/Playground/ServerMode/v1.0.0/RpcListener.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; internal sealed class ConsoleRpcListener : TraceListener diff --git a/samples/Playground/ServerMode/v1.0.0/ServerInfo.cs b/samples/Playground/ServerMode/v1.0.0/ServerInfo.cs index ccab026462..e2b0e4a49f 100644 --- a/samples/Playground/ServerMode/v1.0.0/ServerInfo.cs +++ b/samples/Playground/ServerMode/v1.0.0/ServerInfo.cs @@ -1,8 +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.Text.Json; - using Newtonsoft.Json; namespace Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; diff --git a/samples/Playground/ServerMode/v1.0.0/TestingPlatformClient.cs b/samples/Playground/ServerMode/v1.0.0/TestingPlatformClient.cs index 57a585299b..0d37b7f3d5 100644 --- a/samples/Playground/ServerMode/v1.0.0/TestingPlatformClient.cs +++ b/samples/Playground/ServerMode/v1.0.0/TestingPlatformClient.cs @@ -1,10 +1,7 @@ // 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.Concurrent; -using System.Diagnostics; using System.Net.Sockets; -using System.Text; using MSTest.Acceptance.IntegrationTests.Messages.V100; diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs index e810b570de..884fe813fb 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs @@ -1,12 +1,8 @@ // 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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; using System.Runtime.Serialization; using System.Security; -using System.Text; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs index 84fd028284..53ec74c28f 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumeratorWrapper.cs @@ -1,9 +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.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs index 005a6f2262..2669c119ad 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TestMethodValidator.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs index ca1eaf47a1..07d9327abd 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - using Microsoft.TestPlatform.AdapterUtilities; using Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs index 89529b150c..9e8e1c98d6 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TypeValidator.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs b/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs index d81212d69c..b3b92c1548 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/UnitTestDiscoverer.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel; diff --git a/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs b/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs index c33c1f1b7d..d78223016c 100644 --- a/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs @@ -1,14 +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; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; -#if NET471_OR_GREATER || NETCOREAPP -using System.Runtime.CompilerServices; -#endif - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs index 99ef44b6d7..86151717b6 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/ClassCleanupManager.cs @@ -1,9 +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.Concurrent; -using System.Globalization; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs b/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs index 5f2c2be59c..90acd6cd0b 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs @@ -1,10 +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.Globalization; -using System.Text; -using System.Text.RegularExpressions; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs b/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs index b574bd1f15..7e3dc95d39 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/LogMessageListener.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestTools.UnitTesting.Logging; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs index 9e688e720c..8da4e5c3de 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblyInfo.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblySettingsProvider.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblySettingsProvider.cs index 5c155daf58..4fb24e115c 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblySettingsProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestAssemblySettingsProvider.cs @@ -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.Reflection; using System.Security; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestCaseDiscoverySink.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestCaseDiscoverySink.cs index 2c81c236a6..20376c53dc 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestCaseDiscoverySink.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestCaseDiscoverySink.cs @@ -1,8 +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 Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; @@ -13,15 +11,10 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// internal sealed class TestCaseDiscoverySink : ITestCaseDiscoverySink { - /// - /// Initializes a new instance of the class. - /// - public TestCaseDiscoverySink() => Tests = new Collection(); - /// /// Gets the tests. /// - public ICollection Tests { get; } + public ICollection Tests { get; } = new List(); /// /// Sends the test case. diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index 1fcf49697a..417b507c24 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -1,11 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; -using System.Runtime.InteropServices; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs index b08e8bbac3..11e6383173 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs @@ -1,11 +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.Concurrent; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Runtime.InteropServices; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs index 259903d3d4..5a2152f2be 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs @@ -1,12 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; -using System.Text; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs index 017f45b100..e7fadf8759 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs @@ -1,10 +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.Diagnostics; -using System.Globalization; -using System.Runtime.InteropServices; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs index 436e5791ad..8ebb11d736 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestRunCancellationToken.cs @@ -1,8 +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.Concurrent; - namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; /// diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index 76fb7e3c4c..5e76ac275a 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -1,12 +1,7 @@ // 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.Concurrent; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; using System.Security; -using System.Text; using Microsoft.TestPlatform.AdapterUtilities.ManagedNameUtilities; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs index 945c070280..acfd86fdb3 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs @@ -1,9 +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.Concurrent; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; using System.Security; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/ExceptionExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/ExceptionExtensions.cs index 318320906b..648fbc41db 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/ExceptionExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/ExceptionExtensions.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs index 647587ff1a..d220cd9470 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/MethodInfoExtensions.cs @@ -1,10 +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.Globalization; -using System.Reflection; -using System.Runtime.CompilerServices; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter; diff --git a/src/Adapter/MSTest.TestAdapter/Friends.cs b/src/Adapter/MSTest.TestAdapter/Friends.cs index 989e6a0b7a..bdfd4316bd 100644 --- a/src/Adapter/MSTest.TestAdapter/Friends.cs +++ b/src/Adapter/MSTest.TestAdapter/Friends.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // Friend assemblies -using System.Runtime.CompilerServices; - [assembly: InternalsVisibleTo(assemblyName: "Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo(assemblyName: "DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] [assembly: InternalsVisibleTo(assemblyName: "MSTest.VstestConsoleWrapper.IntegrationTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/DataSerializationHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/DataSerializationHelper.cs index 0b9e1bc782..4f1a9253fe 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/DataSerializationHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/DataSerializationHelper.cs @@ -1,9 +1,7 @@ // 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.Concurrent; using System.Runtime.Serialization.Json; -using System.Text; namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/FixtureMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Helpers/FixtureMethodRunner.cs index f4c60e6e4b..c7f5f4b126 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/FixtureMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/FixtureMethodRunner.cs @@ -1,10 +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.Globalization; -using System.Reflection; -using System.Runtime.InteropServices; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index f321c9fb10..cc361ee215 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -1,10 +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.Concurrent; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; using System.Security; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/RunSettingsUtilities.cs b/src/Adapter/MSTest.TestAdapter/Helpers/RunSettingsUtilities.cs index 62b5a7e147..2503c9f3bb 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/RunSettingsUtilities.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/RunSettingsUtilities.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Xml; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/TestRunParameters.cs b/src/Adapter/MSTest.TestAdapter/Helpers/TestRunParameters.cs index 6703b44ce1..9a324be172 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/TestRunParameters.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/TestRunParameters.cs @@ -1,9 +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.Globalization; -using System.Xml; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj index 2103a10aa8..e195bbe50d 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.csproj @@ -148,6 +148,7 @@ + diff --git a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs index ac899af772..a4041e8345 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs +++ b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs @@ -1,11 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Xml; -using System.Xml.Linq; - using Microsoft.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; #if !WINDOWS_UWP diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs index e24df2d56c..61d75236bf 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs @@ -2,7 +2,6 @@ // 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 Microsoft.TestPlatform.AdapterUtilities; diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs index befe0aa491..a585c6afde 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs @@ -1,9 +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.Diagnostics; -using System.Globalization; - using Microsoft.TestPlatform.AdapterUtilities; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; using Microsoft.VisualStudio.TestPlatform.ObjectModel; diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs index 57f2ec8e28..73b33d4468 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestResult.cs @@ -1,9 +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.Diagnostics; -using System.Globalization; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs index 60b2e84709..6bb7a3348f 100644 --- a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - #if !WINDOWS_UWP using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration; #endif diff --git a/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs b/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs index e9a1701c71..d2386624c9 100644 --- a/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs +++ b/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs @@ -1,12 +1,7 @@ // 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.Diagnostics.CodeAnalysis; -using System.Xml; - #if !WINDOWS_UWP -using System.Globalization; - using Microsoft.Testing.Platform.Configurations; #endif diff --git a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedFileOperations.cs b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedFileOperations.cs index 96cfcf728f..c8b8ac98f3 100644 --- a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedFileOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedFileOperations.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; diff --git a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionDataProvider.cs b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionDataProvider.cs index 925eeba044..b29bb954be 100644 --- a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionDataProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionDataProvider.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using System.Reflection; - namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.SourceGeneration; /// diff --git a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs index 19877998ab..16bd0f9454 100644 --- a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using System.Diagnostics.CodeAnalysis; -using System.Reflection; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; diff --git a/src/Adapter/MSTest.TestAdapter/TestMethodFilter.cs b/src/Adapter/MSTest.TestAdapter/TestMethodFilter.cs index 862a71e0f1..a713f7acc8 100644 --- a/src/Adapter/MSTest.TestAdapter/TestMethodFilter.cs +++ b/src/Adapter/MSTest.TestAdapter/TestMethodFilter.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs index af5c0c0e4b..22f3d64a18 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using System.Runtime.InteropServices; -using System.Text; - using Microsoft.Testing.Platform.Capabilities.TestFramework; using Microsoft.Testing.Platform.Services; diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs index 6a9ca840a1..a5af5cb408 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using System.Diagnostics; -using System.Reflection; - using Microsoft.Testing.Extensions.VSTestBridge; using Microsoft.Testing.Extensions.VSTestBridge.Requests; using Microsoft.Testing.Platform.Capabilities.TestFramework; diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestExtension.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestExtension.cs index d39139e914..8fbd29bc26 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestExtension.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestExtension.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using System.Reflection; - using Microsoft.Testing.Platform.Extensions; namespace Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs index 3cb51f0732..045fc76a77 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using System.Reflection; - using Microsoft.Testing.Extensions.VSTestBridge.Capabilities; using Microsoft.Testing.Extensions.VSTestBridge.Helpers; using Microsoft.Testing.Platform.Builder; diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestingPlatformBuilderHook.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestingPlatformBuilderHook.cs index befda48370..a38ab697c8 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestingPlatformBuilderHook.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestingPlatformBuilderHook.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using System.Reflection; - using Microsoft.Testing.Platform.Builder; namespace Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs index 51f8df0a8b..9f1de06897 100644 --- a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs +++ b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs @@ -1,8 +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.Runtime.InteropServices; - using Microsoft.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.ObjectModel; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs index 6e09cd6020..d28be18d55 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NETFRAMEWORK || NET -using System.Diagnostics; -using System.Reflection; #if NETFRAMEWORK using System.Runtime.InteropServices.WindowsRuntime; using System.Security; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Data/CsvDataConnection.cs b/src/Adapter/MSTestAdapter.PlatformServices/Data/CsvDataConnection.cs index 759b8f9645..5a50d54742 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Data/CsvDataConnection.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Data/CsvDataConnection.cs @@ -3,12 +3,8 @@ #if NETFRAMEWORK -using System.Collections; using System.Data; using System.Data.OleDb; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnection.cs b/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnection.cs index 799a4cfbfd..dc617706d5 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnection.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnection.cs @@ -2,11 +2,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NETFRAMEWORK -using System.Collections; using System.Data; using System.Data.Common; -using System.Diagnostics; -using System.Globalization; using System.Security; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnectionSql.cs b/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnectionSql.cs index 1f9ca7507c..f2af39ca11 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnectionSql.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Data/TestDataConnectionSql.cs @@ -2,15 +2,11 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NETFRAMEWORK -using System.Collections; using System.Data; using System.Data.Common; using System.Data.Odbc; using System.Data.OleDb; using System.Data.SqlClient; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Data/XmlDataConnection.cs b/src/Adapter/MSTestAdapter.PlatformServices/Data/XmlDataConnection.cs index dfa7b3be55..66b155147c 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Data/XmlDataConnection.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Data/XmlDataConnection.cs @@ -2,12 +2,8 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NETFRAMEWORK -using System.Collections; using System.Data; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; using System.Security; -using System.Xml; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs index 7caef27a5a..1d3850dec8 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs @@ -3,9 +3,6 @@ #if NETFRAMEWORK -using System.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/DeploymentItem.cs b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/DeploymentItem.cs index f9a74383aa..e041ce0d32 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/DeploymentItem.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/DeploymentItem.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using System.Globalization; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs index db0a583a89..b7a07ea77d 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/TestRunDirectories.cs @@ -3,8 +3,6 @@ #if !WINDOWS_UWP -using System.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Friends.cs b/src/Adapter/MSTestAdapter.PlatformServices/Friends.cs index ac6b474721..ca53146909 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Friends.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Friends.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // Friend assemblies -using System.Runtime.CompilerServices; - [assembly: InternalsVisibleTo("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.UWP.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.WinUI.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs index 220384a574..44450a5669 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IFileOperations.cs @@ -1,8 +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.Reflection; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs index 6d45ad9137..eb93885e4a 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Reflection; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs index 7de179b9f6..0036e00cbb 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs @@ -1,8 +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.Reflection; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; internal interface IReflectionOperations2 : IReflectionOperations diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs index 84d99b8c11..47f27225d5 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ISettingsProvider.cs @@ -1,8 +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.Xml; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs index a8cd1766ef..705a700ec1 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestDeployment.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs index ee1321c162..9c997296af 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSource.cs @@ -1,8 +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.Reflection; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs index 9d2f93a7b5..93a3157526 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/ITestSourceHost.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Properties/AssemblyInfo.cs b/src/Adapter/MSTestAdapter.PlatformServices/Properties/AssemblyInfo.cs index e1f84be7e3..d7f4830787 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Properties/AssemblyInfo.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Properties/AssemblyInfo.cs @@ -1,15 +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. -#if NETFRAMEWORK || WIN_UI -using System.Runtime.CompilerServices; -#endif -using System.Runtime.InteropServices; - -#if WIN_UI -using System.Runtime.Versioning; -#endif - [assembly: ComVisible(false)] #if WIN_UI diff --git a/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs b/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs index 93f712ca1c..e2dbebb62f 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/RecursiveDirectoryPath.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using System.Diagnostics.CodeAnalysis; using System.Security; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/DiaSessionOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/DiaSessionOperations.cs index dd44632e3a..715db4e02b 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/DiaSessionOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/DiaSessionOperations.cs @@ -1,8 +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.Reflection; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; internal static class DiaSessionOperations diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ExecutionContextService.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ExecutionContextService.cs index c38800d1c0..9ba8f8c5d1 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ExecutionContextService.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ExecutionContextService.cs @@ -1,9 +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.Concurrent; -using System.Diagnostics; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; internal static class ExecutionContextService diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs index 6a257ae966..e28a2f5009 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/FileOperations.cs @@ -1,9 +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.Concurrent; -using System.Reflection; - #if WIN_UI using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.AppContainer; #endif diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs index 59ac48a834..a71a4322ba 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using System.Globalization; -using System.Xml; using Microsoft.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.ObjectModel; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs index f927fd9137..f72e120267 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations.cs @@ -1,12 +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. -#if !NETFRAMEWORK -using System.Diagnostics; -#endif -using System.Diagnostics.CodeAnalysis; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; #if NETFRAMEWORK using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs index 653a5d7499..cf7597438f 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs index 618229553b..6775530711 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs @@ -1,11 +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. -#if !WINDOWS_UWP -using System.Diagnostics.CodeAnalysis; -#endif -using System.Xml; - using Microsoft.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs index 8d5ea537df..4dc75ae796 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestContextImplementation.cs @@ -1,12 +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 System.Collections; #if NETFRAMEWORK using System.Data; using System.Data.Common; #endif -using System.Globalization; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs index da68aed004..232dc8d19b 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDataSource.cs @@ -4,8 +4,6 @@ #if NETFRAMEWORK using System.Configuration; using System.Data; -using System.Diagnostics; -using System.Globalization; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Data; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs index 142cbe85d6..257f02d895 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestDeployment.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Reflection; - #if !WINDOWS_UWP using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; #endif diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs index 07421a54a6..e24f91db0a 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSource.cs @@ -1,8 +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.Reflection; - #if WIN_UI using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.AppContainer; #endif diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs index 3947aae28b..441b3c7d5d 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TestSourceHost.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; #if NETFRAMEWORK using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs index 156a2e7efb..06f5b3a7ef 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs @@ -1,10 +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. -#if !NETFRAMEWORK -using System.Runtime.InteropServices; -#endif - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs index af48e6c7ae..2994696ebd 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadSafeStringWriter.cs @@ -1,8 +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.Text; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs index 25196e6784..667fa713c0 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListener.cs @@ -1,10 +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. -#if !WINDOWS_UWP && !WIN_UI -using System.Diagnostics; -#endif - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs index 7aa3dcbd53..0eec6af8f1 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/TraceListenerManager.cs @@ -1,10 +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. -#if !WINDOWS_UWP && !WIN_UI -using System.Diagnostics; -#endif - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs index a465deaebc..f76a25f500 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs @@ -3,10 +3,6 @@ #if NETFRAMEWORK -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ApplicationStateGuard.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ApplicationStateGuard.cs index 1028c8e7da..6e6c1f2bd7 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ApplicationStateGuard.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ApplicationStateGuard.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter; internal static class ApplicationStateGuard diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AssemblyUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AssemblyUtility.cs index 1c36284b18..18ddbf8cd5 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AssemblyUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AssemblyUtility.cs @@ -3,11 +3,7 @@ #if !WINDOWS_UWP -using System.Diagnostics.CodeAnalysis; #if NETFRAMEWORK -using System.Diagnostics; -using System.Globalization; -using System.Reflection; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.ObjectModel; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs index 07479ffe20..d8f2c5428f 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs @@ -3,11 +3,6 @@ #if !WINDOWS_UWP -using System.Collections; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs index 51c73227b0..e64336180e 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs @@ -3,10 +3,6 @@ #if !WINDOWS_UWP -#if NETFRAMEWORK || NETSTANDARD || NETCOREAPP3_1 -using System.Diagnostics; -#endif -using System.Globalization; #if NETFRAMEWORK using System.Security; #endif diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtilityBase.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtilityBase.cs index 0fbcabc78e..a63aa0656a 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtilityBase.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtilityBase.cs @@ -3,9 +3,6 @@ #if !WINDOWS_UWP -using System.Diagnostics.CodeAnalysis; -using System.Globalization; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs index 708fff0ec5..f97005e844 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/FileUtility.cs @@ -3,9 +3,6 @@ #if !WINDOWS_UWP -using System.Diagnostics.CodeAnalysis; -using System.Globalization; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/IAssemblyUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/IAssemblyUtility.cs index e180d9eada..1f923fb408 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/IAssemblyUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/IAssemblyUtility.cs @@ -3,8 +3,6 @@ #if NETFRAMEWORK -using System.Reflection; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; internal interface IAssemblyUtility diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/RandomIntPermutation.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/RandomIntPermutation.cs index aaf3965dbf..a18ca30068 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/RandomIntPermutation.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/RandomIntPermutation.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NETFRAMEWORK - -using System.Collections; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ReflectionUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ReflectionUtility.cs index 8ff05ead97..b9fe555b32 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ReflectionUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/ReflectionUtility.cs @@ -3,12 +3,6 @@ #if !WINDOWS_UWP -#if NETFRAMEWORK -using System.Collections; -#endif -using System.Diagnostics.CodeAnalysis; -using System.Reflection; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/SequentialIntPermutation.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/SequentialIntPermutation.cs index f4faf60807..179aeb21f1 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/SequentialIntPermutation.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/SequentialIntPermutation.cs @@ -3,8 +3,6 @@ #if NETFRAMEWORK -using System.Collections; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; /// diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs index 0a16f5e3f4..2e6ee4baaf 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs @@ -3,9 +3,6 @@ #if NETFRAMEWORK -using System.Diagnostics; -using System.Runtime.InteropServices; - using static System.String; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/XmlUtilities.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/XmlUtilities.cs index 3518df09ed..6c23bce1db 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/XmlUtilities.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/XmlUtilities.cs @@ -3,12 +3,6 @@ #if NETFRAMEWORK -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; -using System.Text; -using System.Xml; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/UseProperAssertMethodsFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/UseProperAssertMethodsFixer.cs index 9350d06abf..d8dfaf8a42 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/UseProperAssertMethodsFixer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/UseProperAssertMethodsFixer.cs @@ -3,8 +3,6 @@ using System.Collections.Immutable; using System.Composition; -using System.Diagnostics; -using System.Globalization; using Analyzer.Utilities; diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/ApplicationStateGuard.cs b/src/Analyzers/MSTest.Analyzers/Helpers/ApplicationStateGuard.cs index 02826efc45..bb088f14cb 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/ApplicationStateGuard.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/ApplicationStateGuard.cs @@ -1,9 +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.Diagnostics; -using System.Runtime.CompilerServices; - namespace MSTest.Analyzers.Helpers; internal static class ApplicationStateGuard diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ArrayBuilder.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ArrayBuilder.cs index 81c3fb5952..c033cd70fc 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ArrayBuilder.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ArrayBuilder.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. -using System.Collections; using System.Collections.Immutable; -using System.Diagnostics; #pragma warning disable CA1000 // Do not declare static members on generic types diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/CompilationExtensions.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/CompilationExtensions.cs index 283a392d83..e740b609c9 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/CompilationExtensions.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/CompilationExtensions.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.CodeAnalysis; namespace Analyzer.Utilities.Extensions; diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/DiagnosticExtensions.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/DiagnosticExtensions.cs index d5e5134011..afb5ae2ab1 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/DiagnosticExtensions.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/DiagnosticExtensions.cs @@ -1,7 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. using System.Collections.Immutable; -using System.Reflection; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs index 949e91704d..e308c35b21 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs @@ -2,8 +2,6 @@ #nullable disable warnings -using System.Diagnostics.CodeAnalysis; - using Microsoft.CodeAnalysis; using MSTest.Analyzers.Helpers; diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IOperationExtensions.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IOperationExtensions.cs index 1584ad6d0f..b4f48fb09f 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IOperationExtensions.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IOperationExtensions.cs @@ -1,10 +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; -using System.Collections.Generic; -using System.Text; - using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Operations; diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ITypeSymbolExtensions.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ITypeSymbolExtensions.cs index dbd736e80a..a76b4c0dc4 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ITypeSymbolExtensions.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ITypeSymbolExtensions.cs @@ -2,8 +2,6 @@ #nullable disable warnings -using System.Diagnostics.CodeAnalysis; - using Microsoft.CodeAnalysis; namespace Analyzer.Utilities.Extensions; diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ObjectPool.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ObjectPool.cs index 6a3a7e88aa..772b399e98 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ObjectPool.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ObjectPool.cs @@ -10,8 +10,6 @@ // #define DETECT_LEAKS //for now always enable DETECT_LEAKS in debug. // #endif -using System.Diagnostics; - #if DETECT_LEAKS using System.Runtime.CompilerServices; diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/PerformanceSensitiveAttribute.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/PerformanceSensitiveAttribute.cs index 2f753bdefb..0fe718cff9 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/PerformanceSensitiveAttribute.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/PerformanceSensitiveAttribute.cs @@ -4,7 +4,6 @@ #pragma warning disable CS1574 // XML comment has cref attribute that could not be resolved (not all builds have all types) using System; -using System.Diagnostics; namespace Roslyn.Utilities { diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/PooledHashSet.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/PooledHashSet.cs index 8adfb81f78..dfa3781100 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/PooledHashSet.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/PooledHashSet.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. -using System.Collections.Concurrent; using System.Collections.Immutable; -using System.Diagnostics; #pragma warning disable CA1000 // Do not declare static members on generic types diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/RoslynDebug.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/RoslynDebug.cs index 8a70ae87aa..948329696f 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/RoslynDebug.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/RoslynDebug.cs @@ -1,8 +1,5 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; - namespace Analyzer.Utilities; internal static class RoslynDebug diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs index f988d950c2..f470a13e05 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/WellKnownTypeProvider.cs @@ -1,9 +1,6 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. -using System.Collections.Concurrent; using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; using Analyzer.Utilities.Extensions; using Analyzer.Utilities.PooledObjects; diff --git a/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs index f76566038a..c82f67fc1d 100644 --- a/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; using Analyzer.Utilities; using Analyzer.Utilities.Extensions; diff --git a/src/Analyzers/MSTest.Internal.Analyzers/MSTestObsoleteTypesSuppressor.cs b/src/Analyzers/MSTest.Internal.Analyzers/MSTestObsoleteTypesSuppressor.cs index 2474a61e66..a844a1ee92 100644 --- a/src/Analyzers/MSTest.Internal.Analyzers/MSTestObsoleteTypesSuppressor.cs +++ b/src/Analyzers/MSTest.Internal.Analyzers/MSTestObsoleteTypesSuppressor.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Immutable; -using System.Globalization; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; diff --git a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.cs b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.cs index 7bed8e2ec8..195136e80c 100644 --- a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpCommandLineProvider.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.Diagnostics.Resources; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; diff --git a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs index ae351902ac..47dbe3465e 100644 --- a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs @@ -1,8 +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.Text; - using Microsoft.Testing.Extensions.Diagnostics.Resources; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; diff --git a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs index 8c92fc9a91..ecec7a268e 100644 --- a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs +++ b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpProcessLifetimeHandler.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.Diagnostics.Resources; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions.Messages; diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpActivityIndicator.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpActivityIndicator.cs index aeff5caa2a..9e3875463e 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpActivityIndicator.cs +++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpActivityIndicator.cs @@ -1,9 +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.Concurrent; -using System.Globalization; - using Microsoft.Testing.Extensions.Diagnostics.Resources; using Microsoft.Testing.Extensions.HangDump.Serializers; using Microsoft.Testing.Platform.CommandLine; diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpCommandLineProvider.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpCommandLineProvider.cs index 823de1e328..b69d97480a 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpCommandLineProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpCommandLineProvider.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.Diagnostics.Resources; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpEnvironmentVariableProvider.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpEnvironmentVariableProvider.cs index 6c855167bf..dd31977754 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpEnvironmentVariableProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpEnvironmentVariableProvider.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.Diagnostics.Resources; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs index 077c7ae384..42623822c7 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs +++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs @@ -1,11 +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.Globalization; -#if NETCOREAPP -using System.Runtime.InteropServices; -#endif - using Microsoft.Testing.Extensions.Diagnostics.Resources; using Microsoft.Testing.Extensions.HangDump.Serializers; using Microsoft.Testing.Platform; diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/Helpers/FNV1HashHelper.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/Helpers/FNV1HashHelper.cs index 26d5b0ea80..6063f65d9d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HangDump/Helpers/FNV1HashHelper.cs +++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/Helpers/FNV1HashHelper.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Helpers; [ExcludeFromCodeCoverage] diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/WindowsMiniDumpWriteDump.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/WindowsMiniDumpWriteDump.cs index 7217148459..41f2c6586d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HangDump/WindowsMiniDumpWriteDump.cs +++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/WindowsMiniDumpWriteDump.cs @@ -1,10 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; - using Microsoft.Win32.SafeHandles; namespace Microsoft.Testing.Extensions.Diagnostics; diff --git a/src/Platform/Microsoft.Testing.Extensions.MSBuild/MSBuildConsumer.cs b/src/Platform/Microsoft.Testing.Extensions.MSBuild/MSBuildConsumer.cs index d46dbd47a5..124be7cbb5 100644 --- a/src/Platform/Microsoft.Testing.Extensions.MSBuild/MSBuildConsumer.cs +++ b/src/Platform/Microsoft.Testing.Extensions.MSBuild/MSBuildConsumer.cs @@ -1,9 +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.Globalization; -using System.Text; - using Microsoft.Testing.Extensions.MSBuild.Serializers; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions.Messages; diff --git a/src/Platform/Microsoft.Testing.Extensions.MSBuild/MSBuildTestApplicationLifecycleCallbacks.cs b/src/Platform/Microsoft.Testing.Extensions.MSBuild/MSBuildTestApplicationLifecycleCallbacks.cs index dd4a62547c..7e830ab2b7 100644 --- a/src/Platform/Microsoft.Testing.Extensions.MSBuild/MSBuildTestApplicationLifecycleCallbacks.cs +++ b/src/Platform/Microsoft.Testing.Extensions.MSBuild/MSBuildTestApplicationLifecycleCallbacks.cs @@ -1,8 +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.Runtime.InteropServices; - using Microsoft.Testing.Extensions.MSBuild.Serializers; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryCommandLineOptionsProvider.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryCommandLineOptionsProvider.cs index 40ee1ac50d..954fb4dfe9 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryCommandLineOptionsProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryCommandLineOptionsProvider.cs @@ -1,8 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. -using System.Globalization; - using Microsoft.Testing.Extensions.Policy.Resources; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs index 849d286da2..219bf3121d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs @@ -1,10 +1,6 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. -using System.Diagnostics; -using System.Globalization; -using System.Text; - using Microsoft.Testing.Extensions.Policy.Resources; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; diff --git a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs index fc69d13e19..9bce278cf3 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs @@ -3,11 +3,7 @@ #if NETCOREAPP using System.Threading.Channels; -#else -using System.Collections.Concurrent; #endif -using System.Globalization; -using System.Text; using Microsoft.Testing.Platform; using Microsoft.Testing.Platform.Configurations; diff --git a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsTelemetryProviderExtensions.cs b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsTelemetryProviderExtensions.cs index 29f0e0ea24..4e391cb76f 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsTelemetryProviderExtensions.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsTelemetryProviderExtensions.cs @@ -8,10 +8,6 @@ using Microsoft.Testing.Platform.Services; using Microsoft.Testing.Platform.Telemetry; -#if NETCOREAPP -using System.Runtime.CompilerServices; -#endif - namespace Microsoft.Testing.Extensions; public static class AppInsightsTelemetryProviderExtensions diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport.Abstractions/GlobalSuppressions.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport.Abstractions/GlobalSuppressions.cs index 91e972bf72..c51ba7e88d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport.Abstractions/GlobalSuppressions.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport.Abstractions/GlobalSuppressions.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - // We usually do not want to suppress issues through GlobalSuppressions file but in this case we have to do it because // we are not able to suppress the issue differently. #pragma warning disable IDE0076 diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.CommandLine.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.CommandLine.cs index 71f2f4b9c5..05b2a63ed4 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.CommandLine.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.CommandLine.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.TestReports.Resources; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.cs index 3078a918f2..3e885d9f74 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxCompareTool.cs @@ -1,10 +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.Globalization; -using System.Text; -using System.Xml.Linq; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; using Microsoft.Testing.Platform.Extensions.OutputDevice; diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxDataConsumer.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxDataConsumer.cs index f7b963c788..b8359cfd8d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxDataConsumer.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxDataConsumer.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.TestReports.Resources; using Microsoft.Testing.Extensions.TrxReport.Abstractions.Serializers; using Microsoft.Testing.Platform.Capabilities.TestFramework; diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxEnvironmentVariableProvider.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxEnvironmentVariableProvider.cs index d19aa3f54e..9663d49ce9 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxEnvironmentVariableProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxEnvironmentVariableProvider.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.TestReports.Resources; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxProcessLifetimeHandler.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxProcessLifetimeHandler.cs index 3ecf341949..c73914056f 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxProcessLifetimeHandler.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxProcessLifetimeHandler.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.TestReports.Resources; using Microsoft.Testing.Extensions.TrxReport.Abstractions.Serializers; using Microsoft.Testing.Platform.CommandLine; diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportEngine.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportEngine.cs index 79a64331c9..db577d90bd 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportEngine.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxReportEngine.cs @@ -4,11 +4,7 @@ #if NETCOREAPP using System.Buffers; #endif -using System.Globalization; using System.Security.Cryptography; -using System.Text; -using System.Text.RegularExpressions; -using System.Xml.Linq; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; diff --git a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxTestApplicationLifecycleCallbacks.cs b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxTestApplicationLifecycleCallbacks.cs index 9102eeaa8e..33e0e73cff 100644 --- a/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxTestApplicationLifecycleCallbacks.cs +++ b/src/Platform/Microsoft.Testing.Extensions.TrxReport/TrxTestApplicationLifecycleCallbacks.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.TestReports.Resources; using Microsoft.Testing.Extensions.TrxReport.Abstractions.Serializers; using Microsoft.Testing.Platform.CommandLine; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/CommandLine/RunSettingsCommandLineOptionsProvider.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/CommandLine/RunSettingsCommandLineOptionsProvider.cs index dad26b9207..261f1e58d5 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/CommandLine/RunSettingsCommandLineOptionsProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/CommandLine/RunSettingsCommandLineOptionsProvider.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.VSTestBridge.Resources; using Microsoft.Testing.Platform; using Microsoft.Testing.Platform.CommandLine; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/CommandLine/TestRunParametersCommandLineOptionsProvider.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/CommandLine/TestRunParametersCommandLineOptionsProvider.cs index 1646d8df09..174f2022c8 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/CommandLine/TestRunParametersCommandLineOptionsProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/CommandLine/TestRunParametersCommandLineOptionsProvider.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.VSTestBridge.Resources; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Configurations/RunSettingsConfigurationProvider.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Configurations/RunSettingsConfigurationProvider.cs index 934ac816f7..da7ff8d85c 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Configurations/RunSettingsConfigurationProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Configurations/RunSettingsConfigurationProvider.cs @@ -1,8 +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.Xml.Linq; - using Microsoft.Testing.Extensions.VSTestBridge.CommandLine; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/DebugUtils.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/DebugUtils.cs index 57724e17e4..7801f753b1 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/DebugUtils.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/Helpers/DebugUtils.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.Extensions.VSTestBridge.Helpers; internal static class DebugUtils diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/Condition.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/Condition.cs index 3cdfd97863..90d9101af0 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/Condition.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/Condition.cs @@ -2,10 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // NOTE: This file is copied as-is from VSTest source code. -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; - using Microsoft.Testing.Platform; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ContextAdapterBase.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ContextAdapterBase.cs index 4d8a44bbee..e79410734a 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ContextAdapterBase.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ContextAdapterBase.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.VSTestBridge.CommandLine; using Microsoft.Testing.Platform; using Microsoft.Testing.Platform.CommandLine; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FastFilter.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FastFilter.cs index 3e0ec2232c..456384b72c 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FastFilter.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FastFilter.cs @@ -3,9 +3,6 @@ // NOTE: This file is copied as-is from VSTest source code. using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text.RegularExpressions; using Microsoft.Testing.Platform; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpression.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpression.cs index 53531b3d83..4f771bfc0f 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpression.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpression.cs @@ -2,12 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // NOTE: This file is copied as-is from VSTest source code. -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; -using System.Text.RegularExpressions; - using Microsoft.Testing.Platform; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpressionWrapper.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpressionWrapper.cs index 14cde5cba7..3b8e083a14 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpressionWrapper.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/FilterExpressionWrapper.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // NOTE: This file is copied as-is from VSTest source code. -using System.Diagnostics.CodeAnalysis; -using System.Text.RegularExpressions; - using Microsoft.Testing.Platform; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.cs index 81a3151552..76bc0af8cb 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.cs @@ -3,8 +3,6 @@ #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. -using System.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Extensions.TrxReport.Abstractions; using Microsoft.Testing.Platform; using Microsoft.Testing.Platform.Extensions.Messages; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunContextAdapter.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunContextAdapter.cs index 3b321ef613..48ab8bbb84 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunContextAdapter.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunContextAdapter.cs @@ -1,10 +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.Diagnostics; -using System.Text; -using System.Xml.Linq; - using Microsoft.Testing.Platform; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions.Messages; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs index 9e63be64bc..9ba6513f15 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsAdapter.cs @@ -3,9 +3,6 @@ #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. -using System.Globalization; -using System.Xml.Linq; - using Microsoft.Testing.Extensions.VSTestBridge.CommandLine; using Microsoft.Testing.Extensions.VSTestBridge.Resources; using Microsoft.Testing.Platform; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsPatcher.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsPatcher.cs index 736ba6833e..85cc81e2e2 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsPatcher.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/RunSettingsPatcher.cs @@ -3,8 +3,6 @@ #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. -using System.Xml.Linq; - using Microsoft.Testing.Extensions.VSTestBridge.CommandLine; using Microsoft.Testing.Extensions.VSTestBridge.Resources; using Microsoft.Testing.Platform; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/SynchronizedSingleSessionVSTestAndTestAnywhereAdapter.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/SynchronizedSingleSessionVSTestAndTestAnywhereAdapter.cs index 7cfbe47606..17ddf43eff 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/SynchronizedSingleSessionVSTestAndTestAnywhereAdapter.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/SynchronizedSingleSessionVSTestAndTestAnywhereAdapter.cs @@ -1,9 +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.Globalization; -using System.Reflection; - using Microsoft.Testing.Extensions.VSTestBridge.Requests; using Microsoft.Testing.Extensions.VSTestBridge.Resources; using Microsoft.Testing.Platform.Capabilities.TestFramework; diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/TestHostControllers/RunSettingsEnvironmentVariableProvider .cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/TestHostControllers/RunSettingsEnvironmentVariableProvider .cs index 23a6896af9..b1e9e21a15 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/TestHostControllers/RunSettingsEnvironmentVariableProvider .cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/TestHostControllers/RunSettingsEnvironmentVariableProvider .cs @@ -1,8 +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.Xml.Linq; - using Microsoft.Testing.Extensions.VSTestBridge.CommandLine; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs index 53ca25c7d6..5f6d7e4bb0 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs @@ -2,10 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // Adapted from https://github.com/microsoft/vstest/blob/main/src/Microsoft.TestPlatform.CoreUtilities/Helpers/DotnetHostHelper.cs -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; - using Microsoft.Win32; namespace Microsoft.Testing.Platform.MSBuild.Tasks; diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/FailedTestHelper.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/FailedTestHelper.cs index 14a8e0fad6..a344ed461d 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/FailedTestHelper.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/FailedTestHelper.cs @@ -1,9 +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.Globalization; -using System.Text; - using Microsoft.Testing.Extensions.MSBuild.Serializers; namespace Microsoft.Testing.Platform.MSBuild; diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs index fbebc18061..f62a9d809e 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/InvokeTestingPlatformTask.cs @@ -3,11 +3,6 @@ #pragma warning disable CS8618 // Properties below are set by MSBuild. -using System.Diagnostics; -using System.Globalization; -using System.Runtime.InteropServices; -using System.Text; - using Microsoft.Build.Framework; using Microsoft.Testing.Extensions.MSBuild; using Microsoft.Testing.Extensions.MSBuild.Serializers; diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/MSBuildCompatibilityHelper.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/MSBuildCompatibilityHelper.cs index 5d96eb1bf9..8edc1432e8 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/MSBuildCompatibilityHelper.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/MSBuildCompatibilityHelper.cs @@ -3,8 +3,6 @@ #pragma warning disable CS8618 // Properties below are set by MSBuild. -using System.Reflection; - using Microsoft.Build.Framework; namespace Microsoft.Testing.Platform.MSBuild; diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/StackTraceHelper.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/StackTraceHelper.cs index e4f936f99a..bb2c276601 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/StackTraceHelper.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/StackTraceHelper.cs @@ -1,11 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; -using System.Text.RegularExpressions; - namespace Microsoft.Testing.Platform.MSBuild; internal static class StackTraceHelper diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformAutoRegisteredExtensions.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformAutoRegisteredExtensions.cs index a1ce5ff9df..9b0bf36e79 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformAutoRegisteredExtensions.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformAutoRegisteredExtensions.cs @@ -3,10 +3,6 @@ #pragma warning disable CS8618 // Properties below are set by MSBuild. -using System.Diagnostics; -using System.Globalization; -using System.Text; - using Microsoft.Build.Framework; using Microsoft.Build.Utilities; diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformEntryPointTask.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformEntryPointTask.cs index d8ddd2b51a..ec44b532d6 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformEntryPointTask.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformEntryPointTask.cs @@ -3,8 +3,6 @@ #pragma warning disable CS8618 // Properties below are set by MSBuild. -using System.Diagnostics; - using Microsoft.Build.Framework; using Microsoft.Build.Utilities; diff --git a/src/Platform/Microsoft.Testing.Platform/Builder/TestApplication.cs b/src/Platform/Microsoft.Testing.Platform/Builder/TestApplication.cs index 7b618018a9..63ace972e3 100644 --- a/src/Platform/Microsoft.Testing.Platform/Builder/TestApplication.cs +++ b/src/Platform/Microsoft.Testing.Platform/Builder/TestApplication.cs @@ -1,15 +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.Diagnostics; -using System.Globalization; -using System.Reflection; -#if NETCOREAPP -using System.Runtime.CompilerServices; -#endif -using System.Runtime.InteropServices; -using System.Text; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; using Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IBannerMessageOwnerCapability.cs b/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IBannerMessageOwnerCapability.cs index 13f0fb4571..97f4c19d24 100644 --- a/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IBannerMessageOwnerCapability.cs +++ b/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IBannerMessageOwnerCapability.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Capabilities.TestFramework; /// diff --git a/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IGracefulStopTestExecutionCapability.cs b/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IGracefulStopTestExecutionCapability.cs index ee8a92dee3..d152211c28 100644 --- a/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IGracefulStopTestExecutionCapability.cs +++ b/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/IGracefulStopTestExecutionCapability.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Capabilities.TestFramework; /// diff --git a/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/TestFrameworkCapabilitiesExtensions.cs b/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/TestFrameworkCapabilitiesExtensions.cs index 4c934c097c..69d3d4c90f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/TestFrameworkCapabilitiesExtensions.cs +++ b/src/Platform/Microsoft.Testing.Platform/Capabilities/TestFramework/TestFrameworkCapabilitiesExtensions.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Capabilities.TestFramework; [Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")] diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineHandler.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineHandler.cs index 6ab0710778..761c267be0 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineHandler.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineHandler.cs @@ -1,11 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; -using System.Runtime.InteropServices; - using Microsoft.Testing.Platform.Extensions.CommandLine; using Microsoft.Testing.Platform.Extensions.OutputDevice; using Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs index aa3cf47b5e..2db11713d0 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOption.cs @@ -1,9 +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.Diagnostics; -using System.Globalization; - using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsProxy.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsProxy.cs index 6ec2f8f7d7..ee83a5664e 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsProxy.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsProxy.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.CommandLine; internal sealed class CommandLineOptionsProxy : ICommandLineOptions diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsValidator.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsValidator.cs index 3449c90813..aa67608816 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsValidator.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsValidator.cs @@ -1,9 +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.Globalization; -using System.Text; - using Microsoft.Testing.Platform.Extensions; using Microsoft.Testing.Platform.Extensions.CommandLine; using Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineManager.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineManager.cs index 9865b5e69f..481bd37a20 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineManager.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Platform.Extensions.CommandLine; namespace Microsoft.Testing.Platform.CommandLine; diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineOptions.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineOptions.cs index 30abc03a5e..bfb1e2455b 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineOptions.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/ICommandLineOptions.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.CommandLine; /// diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs index bf8842c405..4d4878b34d 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/MaxFailedTestsCommandLineOptionsProvider.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.Capabilities.TestFramework; using Microsoft.Testing.Platform.Extensions; using Microsoft.Testing.Platform.Extensions.CommandLine; diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/ParseResult.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/ParseResult.cs index eb4f7a79a5..a95ccc9e83 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/ParseResult.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/ParseResult.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; - namespace Microsoft.Testing.Platform.CommandLine; internal sealed class CommandLineParseResult(string? toolName, IReadOnlyList options, IReadOnlyList errors) : IEquatable diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/Parser.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/Parser.cs index b3d03c6b6f..ed1bf536d1 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/Parser.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/Parser.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs index ba26ab2f22..557efac8e0 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/PlatformCommandLineProvider.cs @@ -1,9 +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.Diagnostics; -using System.Globalization; - using Microsoft.Testing.Platform.Extensions; using Microsoft.Testing.Platform.Extensions.CommandLine; using Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/ResponseFileHelper.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/ResponseFileHelper.cs index 6b4d9979c9..ff9a0b029f 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/ResponseFileHelper.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/ResponseFileHelper.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - using Microsoft.Testing.Platform.Resources; // Most of the core logic is from: diff --git a/src/Platform/Microsoft.Testing.Platform/Configurations/EnvironmentVariablesConfigurationProvider.cs b/src/Platform/Microsoft.Testing.Platform/Configurations/EnvironmentVariablesConfigurationProvider.cs index 07808c30aa..1807b234dc 100644 --- a/src/Platform/Microsoft.Testing.Platform/Configurations/EnvironmentVariablesConfigurationProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/Configurations/EnvironmentVariablesConfigurationProvider.cs @@ -1,9 +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; -using System.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Platform.Helpers; namespace Microsoft.Testing.Platform.Configurations; diff --git a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.cs b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.cs index 5583122c4d..65a7f2a870 100644 --- a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.cs +++ b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; -using System.Globalization; using System.Text.Json; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.netstandard.cs b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.netstandard.cs index 74b89b15e0..3d21acc89f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.netstandard.cs +++ b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.netstandard.cs @@ -3,8 +3,6 @@ #if !NETCOREAPP -using System.Globalization; - using Jsonite; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationProvider.cs b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationProvider.cs index 5857586520..600d5232a7 100644 --- a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationProvider.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Logging; diff --git a/src/Platform/Microsoft.Testing.Platform/Extensions/ValidationResult.cs b/src/Platform/Microsoft.Testing.Platform/Extensions/ValidationResult.cs index f1161cfbc3..5b3a1e7f0b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Extensions/ValidationResult.cs +++ b/src/Platform/Microsoft.Testing.Platform/Extensions/ValidationResult.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Extensions; /// diff --git a/src/Platform/Microsoft.Testing.Platform/GlobalSuppressions.cs b/src/Platform/Microsoft.Testing.Platform/GlobalSuppressions.cs index 6e70346b51..a4f5d1ba6f 100644 --- a/src/Platform/Microsoft.Testing.Platform/GlobalSuppressions.cs +++ b/src/Platform/Microsoft.Testing.Platform/GlobalSuppressions.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - // We usually do not want to suppress issues through GlobalSuppressions file but in this case we have to do it because // we are not able to suppress the issue differently. #pragma warning disable IDE0076 diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/ActionResult.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/ActionResult.cs index 6f1407d5be..4e8ea92035 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/ActionResult.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/ActionResult.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Helpers; internal class ActionResult diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/ApplicationStateGuard.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/ApplicationStateGuard.cs index 49b361b7cc..4f3e8964a3 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/ApplicationStateGuard.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/ApplicationStateGuard.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Runtime.CompilerServices; - #if !PLATFORM_MSBUILD using Microsoft.Testing.Platform.Resources; #endif diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/ArgumentGuard.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/ArgumentGuard.cs index a22e2ad75c..b47f0bfe9e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/ArgumentGuard.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/ArgumentGuard.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Helpers; internal static class ArgumentGuard diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/EnvironmentVariableConstants.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/EnvironmentVariableConstants.cs index a08556f301..a5a971b4c0 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/EnvironmentVariableConstants.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/EnvironmentVariableConstants.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Helpers; [SuppressMessage("StyleCop.CSharp.NamingRules", "SA1310:Field names should not contain underscore", Justification = "Use nameof pattern")] diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/NonCooperativeParentProcessListener.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/NonCooperativeParentProcessListener.cs index 75e7b77b3a..040ed07481 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/NonCooperativeParentProcessListener.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/NonCooperativeParentProcessListener.cs @@ -1,9 +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.Diagnostics; -using System.Globalization; - using Microsoft.Testing.Platform.CommandLine; namespace Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/ObjectPool.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/ObjectPool.cs index 38dc4a7530..41b5d95a1b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/ObjectPool.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/ObjectPool.cs @@ -13,13 +13,6 @@ // #define DETECT_LEAKS //for now always enable DETECT_LEAKS in debug. // #endif -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; - -#if DETECT_LEAKS -using System.Runtime.CompilerServices; - -#endif namespace Microsoft.Testing.Platform.Helpers; /// diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynDebug.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynDebug.cs index 59940b9ff3..63e4afa6de 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynDebug.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynDebug.cs @@ -1,9 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; - // Copied from https://github.com/dotnet/roslyn-analyzers/blob/main/src/Utilities/Compiler/Debug.cs namespace Microsoft.Testing.Platform; diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynHashCode.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynHashCode.cs index 681f7d397a..947431977f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynHashCode.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynHashCode.cs @@ -47,8 +47,6 @@ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; using System.Security.Cryptography; namespace Microsoft.Testing.Platform; diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynString.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynString.cs index f70cdb5bad..609335384b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynString.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/RoslynString.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform; [SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs", Justification = "This is the replacement helper")] diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/Sha256Hasher.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/Sha256Hasher.cs index 3966c96b39..99f5c70729 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/Sha256Hasher.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/Sha256Hasher.cs @@ -1,9 +1,7 @@ // 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.Diagnostics.CodeAnalysis; using System.Security.Cryptography; -using System.Text; namespace Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/IEnvironment.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/IEnvironment.cs index 6a90462096..b44afb7377 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/IEnvironment.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/IEnvironment.cs @@ -1,8 +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; - namespace Microsoft.Testing.Platform.Helpers; internal interface IEnvironment diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/IProcessHandler.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/IProcessHandler.cs index 2502a9b078..cc5dea6734 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/IProcessHandler.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/IProcessHandler.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.Platform.Helpers; internal interface IProcessHandler diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/ITask.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/ITask.cs index b957247835..214fca68bf 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/ITask.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/ITask.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Helpers; [SuppressMessage("Style", "VSTHRD200:Use \"Async\" suffix for async methods", Justification = "Match the Task API")] diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs index a93dcc91ab..996ac44b11 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs @@ -1,10 +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. -#if NET8_0_OR_GREATER -using System.Runtime.InteropServices; -#endif - namespace Microsoft.Testing.Platform.Helpers; internal sealed class SystemConsole : IConsole diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemEnvironment.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemEnvironment.cs index 977d8b52ef..a7ea4efe62 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemEnvironment.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemEnvironment.cs @@ -1,9 +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; -using System.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Helpers; [SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs", Justification = "This is the wrapper for Environment type.")] diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemMainModule.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemMainModule.cs index 054d72d9d5..e85b8e599e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemMainModule.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemMainModule.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.Platform.Helpers; #if NETCOREAPP diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcess.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcess.cs index d33c9c7a54..7c7ed64699 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcess.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcess.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.Platform.Helpers; internal sealed class SystemProcess : IProcess, IDisposable diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcessHandler.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcessHandler.cs index 6794651a5c..dbb7589ad8 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcessHandler.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemProcessHandler.cs @@ -1,10 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; - using Microsoft.Testing.Platform.Resources; namespace Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemRuntimeFeature.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemRuntimeFeature.cs index 2fcb57b2e8..f6d536b611 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemRuntimeFeature.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemRuntimeFeature.cs @@ -1,10 +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. -#if NETCOREAPP -using System.Runtime.CompilerServices; -#endif - namespace Microsoft.Testing.Platform.Helpers; internal sealed class SystemRuntimeFeature : IRuntimeFeature diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemStopwatch.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemStopwatch.cs index 210513d609..7ce0c0b08a 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemStopwatch.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemStopwatch.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.Platform.Helpers; internal sealed class SystemStopwatch : IStopwatch diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/TaskExtensions.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/TaskExtensions.cs index 7ce3974fb7..e482f7ab42 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/TaskExtensions.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/TaskExtensions.cs @@ -1,9 +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.Diagnostics; -using System.Runtime.CompilerServices; - namespace Microsoft.Testing.Platform.Helpers; // The idea was taken from https://github.com/dotnet/aspnetcore/blob/main/src/Shared/TaskExtensions.cs diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs index 247c72a156..6ebc717cdc 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/TestApplicationBuilderExtensions.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Platform.Builder; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/TimeSpanParser.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/TimeSpanParser.cs index 7208cf0f0f..ffd6a8aea4 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/TimeSpanParser.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/TimeSpanParser.cs @@ -1,8 +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.Text.RegularExpressions; - namespace Microsoft.Testing.Platform.Helpers; internal static partial class TimeSpanParser diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/UILanguageOverride.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/UILanguageOverride.cs index e2244a0f58..4755b34dbb 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/UILanguageOverride.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/UILanguageOverride.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.Helpers; namespace Microsoft.Testing.Platform; diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs index 4a66392d2b..026b1365d8 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/ConsoleTestHost.cs @@ -1,9 +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.Diagnostics; -using System.Globalization; - using Microsoft.Testing.Internal.Framework; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions.TestFramework; diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs index 78f85cbb46..91154642f3 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/ServerTestHost.cs @@ -1,9 +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.Concurrent; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; using System.Net.Sockets; using Microsoft.Testing.Internal.Framework; diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestFrameworkProxy.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestFrameworkProxy.cs index 569bbae639..d48bcb76df 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestFrameworkProxy.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestFrameworkProxy.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.Extensions.TestFramework; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs index 5f27a72103..06c93611dc 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs @@ -1,11 +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.Diagnostics; -using System.Globalization; -using System.Reflection; -using System.Runtime.InteropServices; - using Microsoft.Testing.Internal.Framework; using Microsoft.Testing.Platform.Builder; using Microsoft.Testing.Platform.Capabilities.TestFramework; diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs index 9ee0415152..90bab575d7 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs @@ -1,10 +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.Diagnostics; -using System.Globalization; -using System.Text; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; using Microsoft.Testing.Platform.Extensions; diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs index b0ed844cc8..983cd2db40 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/ToolsTestHost.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; using Microsoft.Testing.Platform.Extensions.CommandLine; diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeBase.cs b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeBase.cs index 9f75028cd4..4a12606676 100644 --- a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeBase.cs +++ b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeBase.cs @@ -1,8 +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.Globalization; - #if !PLATFORM_MSBUILD using Microsoft.Testing.Platform.Resources; #endif diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs index d49a7b9cf6..9161243880 100644 --- a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs +++ b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeClient.cs @@ -8,7 +8,6 @@ #endif using System.IO.Pipes; -using System.Runtime.InteropServices; #if NET using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs index 4a88dea246..89deb4723e 100644 --- a/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs +++ b/src/Platform/Microsoft.Testing.Platform/IPC/NamedPipeServer.cs @@ -4,9 +4,7 @@ #if NET using System.Buffers; #endif -using System.Globalization; using System.IO.Pipes; -using System.Runtime.InteropServices; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Logging; diff --git a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/BaseSerializer.cs b/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/BaseSerializer.cs index 2b0df73190..ee10295eae 100644 --- a/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/BaseSerializer.cs +++ b/src/Platform/Microsoft.Testing.Platform/IPC/Serializers/BaseSerializer.cs @@ -10,8 +10,6 @@ using Microsoft.Testing.Platform.Resources; #endif -using System.Text; - namespace Microsoft.Testing.Platform.IPC.Serializers; internal abstract class BaseSerializer diff --git a/src/Platform/Microsoft.Testing.Platform/Logging/FileLogger.cs b/src/Platform/Microsoft.Testing.Platform/Logging/FileLogger.cs index f48b06ef98..b099b3aee5 100644 --- a/src/Platform/Microsoft.Testing.Platform/Logging/FileLogger.cs +++ b/src/Platform/Microsoft.Testing.Platform/Logging/FileLogger.cs @@ -3,12 +3,7 @@ #if NETCOREAPP using System.Threading.Channels; -#else -using System.Collections.Concurrent; #endif -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/Logging/ServerLogMessage.cs b/src/Platform/Microsoft.Testing.Platform/Logging/ServerLogMessage.cs index f114cb8656..74a0f910e4 100644 --- a/src/Platform/Microsoft.Testing.Platform/Logging/ServerLogMessage.cs +++ b/src/Platform/Microsoft.Testing.Platform/Logging/ServerLogMessage.cs @@ -1,8 +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.Text; - using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/Logging/ServerLogMessageInMemoryStore.cs b/src/Platform/Microsoft.Testing.Platform/Logging/ServerLogMessageInMemoryStore.cs index aa8c89f33a..b0ba1dbe45 100644 --- a/src/Platform/Microsoft.Testing.Platform/Logging/ServerLogMessageInMemoryStore.cs +++ b/src/Platform/Microsoft.Testing.Platform/Logging/ServerLogMessageInMemoryStore.cs @@ -1,9 +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; -using System.Collections.Concurrent; - using Microsoft.Testing.Platform.Hosts; namespace Microsoft.Testing.Platform.Logging; diff --git a/src/Platform/Microsoft.Testing.Platform/Logging/TypeNameHelper.cs b/src/Platform/Microsoft.Testing.Platform/Logging/TypeNameHelper.cs index d61f3c57ea..529043fd08 100644 --- a/src/Platform/Microsoft.Testing.Platform/Logging/TypeNameHelper.cs +++ b/src/Platform/Microsoft.Testing.Platform/Logging/TypeNameHelper.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Text; - namespace Microsoft.Testing.Platform.Logging; /// diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs b/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs index f9e4b0cdf6..a1c0e02066 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs @@ -1,10 +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.Diagnostics; -using System.Globalization; -using System.Text; - using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.Extensions.TestHost; using Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs b/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs index 4948060748..2982aeed35 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/ChannelConsumerDataProcessor.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NETCOREAPP -using System.Diagnostics; using System.Threading.Channels; using Microsoft.Testing.Platform.Extensions.Messages; diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/ConsumingEnumerableConsumerDataProcessor.cs b/src/Platform/Microsoft.Testing.Platform/Messages/ConsumingEnumerableConsumerDataProcessor.cs index 7b13cf0970..da00c06387 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/ConsumingEnumerableConsumerDataProcessor.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/ConsumingEnumerableConsumerDataProcessor.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !NETCOREAPP -using System.Collections.Concurrent; - using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.Extensions.TestHost; using Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/DataWithSessionUid.cs b/src/Platform/Microsoft.Testing.Platform/Messages/DataWithSessionUid.cs index 7eaedb7c68..c25e478742 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/DataWithSessionUid.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/DataWithSessionUid.cs @@ -1,8 +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.Text; - using Microsoft.Testing.Platform.TestHost; namespace Microsoft.Testing.Platform.Extensions.Messages; diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/FileArtifacts.cs b/src/Platform/Microsoft.Testing.Platform/Messages/FileArtifacts.cs index 273023fecd..c29dc9f6db 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/FileArtifacts.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/FileArtifacts.cs @@ -1,8 +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.Text; - using Microsoft.Testing.Platform.TestHost; namespace Microsoft.Testing.Platform.Extensions.Messages; diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/MessageBusProxy.cs b/src/Platform/Microsoft.Testing.Platform/Messages/MessageBusProxy.cs index 889dcd77c7..20f550e813 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/MessageBusProxy.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/MessageBusProxy.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.Extensions.TestHost; diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.Property.cs b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.Property.cs index 7904841d55..17234b658a 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.Property.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.Property.cs @@ -1,9 +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; -using System.Diagnostics; - namespace Microsoft.Testing.Platform.Extensions.Messages; public sealed partial class PropertyBag diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.PropertyBagEnumerable.cs b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.PropertyBagEnumerable.cs index d532cd64ac..06abb42e57 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.PropertyBagEnumerable.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.PropertyBagEnumerable.cs @@ -1,8 +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; - namespace Microsoft.Testing.Platform.Extensions.Messages; public sealed partial class PropertyBag diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.cs b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.cs index ba48bb2277..2a0475dbc9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBag.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Extensions.Messages; public sealed partial class PropertyBag diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBagData.cs b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBagData.cs index e438002206..d0bc0aa444 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBagData.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/PropertyBagData.cs @@ -1,8 +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.Text; - namespace Microsoft.Testing.Platform.Extensions.Messages; public abstract class PropertyBagData(string displayName, string? description) : IData diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/TestNode.cs b/src/Platform/Microsoft.Testing.Platform/Messages/TestNode.cs index ff3bc023ed..5a1096a0b5 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/TestNode.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/TestNode.cs @@ -1,8 +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.Text; - namespace Microsoft.Testing.Platform.Extensions.Messages; public class TestNode diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeProperties.cs b/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeProperties.cs index 01eb459e07..83afea914a 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeProperties.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeProperties.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Extensions.Messages; /// diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeUpdateMessage.cs b/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeUpdateMessage.cs index 28604fb2f4..45a4db59a9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeUpdateMessage.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/TestNodeUpdateMessage.cs @@ -1,8 +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.Text; - using Microsoft.Testing.Platform.TestHost; namespace Microsoft.Testing.Platform.Extensions.Messages; diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/TestRequestExecutionTimeInfo.cs b/src/Platform/Microsoft.Testing.Platform/Messages/TestRequestExecutionTimeInfo.cs index 02fc44e877..1e13d34da8 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/TestRequestExecutionTimeInfo.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/TestRequestExecutionTimeInfo.cs @@ -1,8 +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.Text; - namespace Microsoft.Testing.Platform.Extensions.Messages; internal readonly struct TestRequestExecutionTimeInfo(TimingInfo timingInfo) : IData diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TargetFrameworkParser.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TargetFrameworkParser.cs index 1e8e4ec7a5..4d7b84441c 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TargetFrameworkParser.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TargetFrameworkParser.cs @@ -1,8 +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.Globalization; - namespace Microsoft.Testing.Platform.OutputDevice; internal static class TargetFrameworkParser diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiDetector.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiDetector.cs index 3d949172d8..5dd4b3e884 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiDetector.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiDetector.cs @@ -5,8 +5,6 @@ // https://github.com/spectreconsole/spectre.console/blob/main/src/Spectre.Console/Internal/Backends/Ansi/AnsiDetector.cs // and from the supports-ansi project by Qingrong Ke // https://github.com/keqingrong/supports-ansi/blob/master/index.js -using System.Text.RegularExpressions; - namespace Microsoft.Testing.Platform.OutputDevice.Terminal; /// diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs index 21a664fbb4..55b320706a 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminal.cs @@ -1,10 +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.Globalization; -using System.Runtime.InteropServices; -using System.Text; - using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminalTestProgressFrame.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminalTestProgressFrame.cs index 35cd1f7e38..1d1bb64152 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminalTestProgressFrame.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/AnsiTerminalTestProgressFrame.cs @@ -1,8 +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.Globalization; - namespace Microsoft.Testing.Platform.OutputDevice.Terminal; /// diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/FileUtilities.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/FileUtilities.cs index 4171136311..4cee07e414 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/FileUtilities.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/FileUtilities.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.Platform.OutputDevice.Terminal; internal static class FileUtilities diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/HumanReadableDurationFormatter.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/HumanReadableDurationFormatter.cs index 27aa9af5d1..b28f5f0aa0 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/HumanReadableDurationFormatter.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/HumanReadableDurationFormatter.cs @@ -1,9 +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.Globalization; -using System.Text; - namespace Microsoft.Testing.Platform.OutputDevice.Terminal; internal static class HumanReadableDurationFormatter diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NativeMethods.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NativeMethods.cs index cd4ae2de81..42935d3710 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NativeMethods.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NativeMethods.cs @@ -1,9 +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.Runtime.InteropServices; -using System.Runtime.Versioning; - namespace Microsoft.Testing.Platform.OutputDevice.Terminal; internal static class NativeMethods diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs index 3f91a8a4be..44b8042803 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs @@ -1,9 +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.Globalization; -using System.Text; - using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs index 44b067a99c..c0d4233943 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs @@ -1,15 +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. -#if !NET7_0_OR_GREATER -using System.Diagnostics.CodeAnalysis; -using System.Reflection; -#endif - -using System.Collections.Concurrent; -using System.Globalization; -using System.Text.RegularExpressions; - using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs index d0dc3f4056..db574dfa97 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TestNodeResultsState.cs @@ -1,9 +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.Concurrent; -using System.Globalization; - using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs index f049246cab..a82729dc54 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs @@ -1,12 +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.Globalization; -using System.Reflection; -using System.Runtime.InteropServices; -using System.Runtime.Versioning; -using System.Text; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions; using Microsoft.Testing.Platform.Extensions.Messages; diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/IExecuteRequestCompletionNotifier.cs b/src/Platform/Microsoft.Testing.Platform/Requests/IExecuteRequestCompletionNotifier.cs index a60ec25302..09a2df1541 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/IExecuteRequestCompletionNotifier.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/IExecuteRequestCompletionNotifier.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Requests; [Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")] diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/NopFilter.cs b/src/Platform/Microsoft.Testing.Platform/Requests/NopFilter.cs index c8204a2493..3fbc1c9e55 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/NopFilter.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/NopFilter.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Requests; [Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")] diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs b/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs index edade0379b..f44eb1e82b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/TestHostTestFrameworkInvoker.cs @@ -1,9 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Platform.Capabilities; using Microsoft.Testing.Platform.Capabilities.TestFramework; using Microsoft.Testing.Platform.Extensions.Messages; diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs index c7ed1b6bfc..5421aee941 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs @@ -1,11 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; -using System.Text.RegularExpressions; - using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/ValueAndPropertyExpression.cs b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/ValueAndPropertyExpression.cs index f2930a0434..0c2403c349 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/ValueAndPropertyExpression.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/ValueAndPropertyExpression.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.Platform.Requests; /// diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/ValueExpression.cs b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/ValueExpression.cs index bc2c713522..9cc04aec54 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/ValueExpression.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/ValueExpression.cs @@ -1,9 +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.Diagnostics; -using System.Text.RegularExpressions; - namespace Microsoft.Testing.Platform.Requests; // An expression representing a single value. diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestConnection.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestConnection.cs index db8f4d248c..6ef3e8686f 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestConnection.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestConnection.cs @@ -1,9 +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.Globalization; -using System.Runtime.InteropServices; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions.CommandLine; using Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ErrorCodes.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ErrorCodes.cs index fba10b37fe..d001fa1d8c 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ErrorCodes.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ErrorCodes.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.ServerMode; [SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:Fields should be private", Justification = "Common pattern to use public static readonly fields")] diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/Json.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/Json.cs index c3410c2152..f829b100fd 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/Json.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/Json/Json.cs @@ -1,8 +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; -using System.Text; using System.Text.Json; using Microsoft.Testing.Platform.Extensions.Messages; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs index e5d33e11d0..8733a93026 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/MessageHandlerFactory.cs @@ -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.Globalization; using System.Net; using System.Net.Sockets; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PassiveNode.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PassiveNode.cs index 5cffc0761a..70a8642f30 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PassiveNode.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PassiveNode.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Hosts; using Microsoft.Testing.Platform.Logging; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PerRequestServerDataConsumerService.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PerRequestServerDataConsumerService.cs index e728b45fcf..0097e64ac7 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PerRequestServerDataConsumerService.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/PerRequestServerDataConsumerService.cs @@ -1,8 +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.Concurrent; - using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.Extensions.TestHost; using Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModeManager.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModeManager.cs index 763311a238..c0bc80727b 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModeManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModeManager.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Resources; using Microsoft.Testing.Platform.Services; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs index 8c831b8f7f..1ae054fcbd 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/ServerModePerCallOutputDevice.cs @@ -1,10 +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.Concurrent; -using System.Globalization; -using System.Text; - using Microsoft.Testing.Platform.Extensions.OutputDevice; using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Hosts; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/StreamMessageHandler.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/StreamMessageHandler.cs index e092e70a4d..c93aabf846 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/StreamMessageHandler.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/StreamMessageHandler.cs @@ -1,8 +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.Text; - #if NETCOREAPP using System.Buffers; #else diff --git a/src/Platform/Microsoft.Testing.Platform/Services/CurrentTestApplicationModuleInfo.cs b/src/Platform/Microsoft.Testing.Platform/Services/CurrentTestApplicationModuleInfo.cs index 15c7d4a418..b8346d8472 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/CurrentTestApplicationModuleInfo.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/CurrentTestApplicationModuleInfo.cs @@ -1,13 +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. -#if NETCOREAPP -using System.Diagnostics.CodeAnalysis; -#endif - -using System.Reflection; -using System.Runtime.InteropServices; - using Microsoft.Testing.Platform.Helpers; namespace Microsoft.Testing.Platform.Services; diff --git a/src/Platform/Microsoft.Testing.Platform/Services/IClientInfo.cs b/src/Platform/Microsoft.Testing.Platform/Services/IClientInfo.cs index b6a5d573b8..cb984ad86a 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/IClientInfo.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/IClientInfo.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Services; [Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")] diff --git a/src/Platform/Microsoft.Testing.Platform/Services/IPlatformInformation.cs b/src/Platform/Microsoft.Testing.Platform/Services/IPlatformInformation.cs index 2a90bf3569..92ba052ba9 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/IPlatformInformation.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/IPlatformInformation.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - namespace Microsoft.Testing.Platform.Services; [Experimental("TPEXP", UrlFormat = "https://aka.ms/testingplatform/diagnostics#{0}")] diff --git a/src/Platform/Microsoft.Testing.Platform/Services/ServiceProvider.cs b/src/Platform/Microsoft.Testing.Platform/Services/ServiceProvider.cs index c39ef4aedd..22baff7e4e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/ServiceProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/ServiceProvider.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.Extensions.TestFramework; using Microsoft.Testing.Platform.Extensions.TestHost; using Microsoft.Testing.Platform.Extensions.TestHostControllers; diff --git a/src/Platform/Microsoft.Testing.Platform/Services/ServiceProviderExtensions.cs b/src/Platform/Microsoft.Testing.Platform/Services/ServiceProviderExtensions.cs index bb694a845b..f817c49e38 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/ServiceProviderExtensions.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/ServiceProviderExtensions.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - using Microsoft.Testing.Platform.Capabilities.TestFramework; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; diff --git a/src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs b/src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs index fdd0b5f032..e92049f5aa 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/StopPoliciesService.cs @@ -1,8 +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.Concurrent; - using Microsoft.Testing.Platform.Helpers; namespace Microsoft.Testing.Platform.Services; diff --git a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs index 0b19b09d89..a8b5149079 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/TestApplicationResult.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.Extensions.OutputDevice; diff --git a/src/Platform/Microsoft.Testing.Platform/Telemetry/ExtensionInformationCollector.cs b/src/Platform/Microsoft.Testing.Platform/Telemetry/ExtensionInformationCollector.cs index 5d26c4fd12..ff91fab992 100644 --- a/src/Platform/Microsoft.Testing.Platform/Telemetry/ExtensionInformationCollector.cs +++ b/src/Platform/Microsoft.Testing.Platform/Telemetry/ExtensionInformationCollector.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NETCOREAPP -using System.Text; using System.Text.Json; #else using Jsonite; diff --git a/src/Platform/Microsoft.Testing.Platform/TestFramework/ExecuteRequestContext.cs b/src/Platform/Microsoft.Testing.Platform/TestFramework/ExecuteRequestContext.cs index d990139d3c..2a38535230 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestFramework/ExecuteRequestContext.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestFramework/ExecuteRequestContext.cs @@ -3,8 +3,6 @@ #pragma warning disable RS0016 // Add public types and members to the declared API -using System.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Platform.Messages; using Microsoft.Testing.Platform.Requests; diff --git a/src/Platform/Microsoft.Testing.Platform/TestHost/TestHostManager.cs b/src/Platform/Microsoft.Testing.Platform/TestHost/TestHostManager.cs index c591311896..684e3cfeec 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestHost/TestHostManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestHost/TestHostManager.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.Extensions; using Microsoft.Testing.Platform.Extensions.TestHost; using Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/EnvironmentVariables.cs b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/EnvironmentVariables.cs index ca8aa730b4..4ca6397932 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/EnvironmentVariables.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/EnvironmentVariables.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - using Microsoft.Testing.Platform.Extensions.TestHostControllers; using Microsoft.Testing.Platform.Logging; using Microsoft.Testing.Platform.Resources; diff --git a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/IReadOnlyEnvironmentVariables.cs b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/IReadOnlyEnvironmentVariables.cs index 12b9fadc1b..99f816a186 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/IReadOnlyEnvironmentVariables.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/IReadOnlyEnvironmentVariables.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.Testing.Platform.Extensions.TestHostControllers; /// diff --git a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/SystemEnvironmentVariableProvider.cs b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/SystemEnvironmentVariableProvider.cs index 8e7021df5c..6e4e6bac6e 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/SystemEnvironmentVariableProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/SystemEnvironmentVariableProvider.cs @@ -1,8 +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; - using Microsoft.Testing.Platform.Extensions; using Microsoft.Testing.Platform.Extensions.TestHostControllers; using Microsoft.Testing.Platform.Helpers; diff --git a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostControllerInfo.cs b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostControllerInfo.cs index d5acd12d96..74df6d11ca 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostControllerInfo.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostControllerInfo.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.CommandLine; namespace Microsoft.Testing.Platform.TestHostControllers; diff --git a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostControllersManager.cs b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostControllersManager.cs index 5635675e1b..63f76ad980 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostControllersManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestHostControllers/TestHostControllersManager.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.Configurations; using Microsoft.Testing.Platform.Extensions; using Microsoft.Testing.Platform.Extensions.TestHost; diff --git a/src/Platform/Microsoft.Testing.Platform/TestHostOrcherstrator/TestHostOrchestratorManager.cs b/src/Platform/Microsoft.Testing.Platform/TestHostOrcherstrator/TestHostOrchestratorManager.cs index 675e94dc09..d6f7a628bf 100644 --- a/src/Platform/Microsoft.Testing.Platform/TestHostOrcherstrator/TestHostOrchestratorManager.cs +++ b/src/Platform/Microsoft.Testing.Platform/TestHostOrcherstrator/TestHostOrchestratorManager.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.Resources; using Microsoft.Testing.Platform.Services; diff --git a/src/TestFramework/TestFramework.Extensions/AppModel.cs b/src/TestFramework/TestFramework.Extensions/AppModel.cs index 2b8f49683b..9efd65874c 100644 --- a/src/TestFramework/TestFramework.Extensions/AppModel.cs +++ b/src/TestFramework/TestFramework.Extensions/AppModel.cs @@ -2,10 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if WIN_UI -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; -using System.Text; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.AppContainer; /// diff --git a/src/TestFramework/TestFramework.Extensions/Attributes/UWP_UITestMethodAttribute.cs b/src/TestFramework/TestFramework.Extensions/Attributes/UWP_UITestMethodAttribute.cs index c4bc2f1b17..9aa48c7e3a 100644 --- a/src/TestFramework/TestFramework.Extensions/Attributes/UWP_UITestMethodAttribute.cs +++ b/src/TestFramework/TestFramework.Extensions/Attributes/UWP_UITestMethodAttribute.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if WINDOWS_UWP -using System.Runtime.CompilerServices; namespace Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; diff --git a/src/TestFramework/TestFramework.Extensions/Attributes/WinUITestTargetAttribute.cs b/src/TestFramework/TestFramework.Extensions/Attributes/WinUITestTargetAttribute.cs index a450e0b878..e440b2f31d 100644 --- a/src/TestFramework/TestFramework.Extensions/Attributes/WinUITestTargetAttribute.cs +++ b/src/TestFramework/TestFramework.Extensions/Attributes/WinUITestTargetAttribute.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if WIN_UI -using System.Globalization; namespace Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer; diff --git a/src/TestFramework/TestFramework.Extensions/Attributes/WinUI_UITestMethodAttribute.cs b/src/TestFramework/TestFramework.Extensions/Attributes/WinUI_UITestMethodAttribute.cs index ec26f36df5..88d9835a0d 100644 --- a/src/TestFramework/TestFramework.Extensions/Attributes/WinUI_UITestMethodAttribute.cs +++ b/src/TestFramework/TestFramework.Extensions/Attributes/WinUI_UITestMethodAttribute.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if WIN_UI -using System.Reflection; -using System.Runtime.CompilerServices; - using Microsoft.UI.Dispatching; using Microsoft.UI.Xaml; diff --git a/src/TestFramework/TestFramework.Extensions/ConfigurationSettings/DataSourceElementCollection.cs b/src/TestFramework/TestFramework.Extensions/ConfigurationSettings/DataSourceElementCollection.cs index b2bd44da6f..fa3293b942 100644 --- a/src/TestFramework/TestFramework.Extensions/ConfigurationSettings/DataSourceElementCollection.cs +++ b/src/TestFramework/TestFramework.Extensions/ConfigurationSettings/DataSourceElementCollection.cs @@ -4,7 +4,6 @@ #if NETFRAMEWORK using System.Configuration; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/TestFramework/TestFramework.Extensions/Friends.cs b/src/TestFramework/TestFramework.Extensions/Friends.cs index a6f2073344..57566ec3fd 100644 --- a/src/TestFramework/TestFramework.Extensions/Friends.cs +++ b/src/TestFramework/TestFramework.Extensions/Friends.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. // Friend assemblies -using System.Runtime.CompilerServices; - [assembly: InternalsVisibleTo("Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("MSTestAdapter.PlatformServices.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] diff --git a/src/TestFramework/TestFramework.Extensions/PrivateObject.cs b/src/TestFramework/TestFramework.Extensions/PrivateObject.cs index ba97ebbbdd..0fc6b2fb91 100644 --- a/src/TestFramework/TestFramework.Extensions/PrivateObject.cs +++ b/src/TestFramework/TestFramework.Extensions/PrivateObject.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NETFRAMEWORK -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; namespace Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/TestFramework/TestFramework.Extensions/PrivateType.cs b/src/TestFramework/TestFramework.Extensions/PrivateType.cs index 9d188e76d8..0b696c7ca3 100644 --- a/src/TestFramework/TestFramework.Extensions/PrivateType.cs +++ b/src/TestFramework/TestFramework.Extensions/PrivateType.cs @@ -3,9 +3,6 @@ #if NETFRAMEWORK -using System.Globalization; -using System.Reflection; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework.Extensions/Properties/AssemblyInfo.cs b/src/TestFramework/TestFramework.Extensions/Properties/AssemblyInfo.cs index 9d2e4d8f12..e79fe7763d 100644 --- a/src/TestFramework/TestFramework.Extensions/Properties/AssemblyInfo.cs +++ b/src/TestFramework/TestFramework.Extensions/Properties/AssemblyInfo.cs @@ -1,12 +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. -#if !WIN_UI -using System.Runtime.InteropServices; -#else -using System.Runtime.Versioning; -#endif - #if !WIN_UI [assembly: CLSCompliant(true)] [assembly: ComVisible(false)] diff --git a/src/TestFramework/TestFramework.Extensions/RuntimeTypeHelper.cs b/src/TestFramework/TestFramework.Extensions/RuntimeTypeHelper.cs index 984319f536..ceca146b91 100644 --- a/src/TestFramework/TestFramework.Extensions/RuntimeTypeHelper.cs +++ b/src/TestFramework/TestFramework.Extensions/RuntimeTypeHelper.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NETFRAMEWORK -using System.Diagnostics.CodeAnalysis; -using System.Reflection; namespace Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/TestFramework/TestFramework.Extensions/TestContext.cs b/src/TestFramework/TestFramework.Extensions/TestContext.cs index 1d559cccd2..418a7007e0 100644 --- a/src/TestFramework/TestFramework.Extensions/TestContext.cs +++ b/src/TestFramework/TestFramework.Extensions/TestContext.cs @@ -1,13 +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 System.Collections; #if NETFRAMEWORK using System.Data; using System.Data.Common; #endif -using System.Diagnostics; -using System.Globalization; namespace Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs index d186f6721b..defca4bcc5 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs b/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs index 07115c97d1..b2fd9113d1 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Assertions/Assert.Fail.cs b/src/TestFramework/TestFramework/Assertions/Assert.Fail.cs index 280c261902..e86761c182 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.Fail.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.Fail.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Assertions/Assert.Inconclusive.cs b/src/TestFramework/TestFramework/Assertions/Assert.Inconclusive.cs index 7a53795dee..1124379a0c 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.Inconclusive.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.Inconclusive.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs index 81392a5742..84adbb12b5 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs index 5c6300c80e..96df80dd1d 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs index a28b3aa331..62e96b5470 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs b/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs index 39658439f9..e926389093 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.ComponentModel; -using System.Globalization; -using System.Runtime.CompilerServices; namespace Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/TestFramework/TestFramework/Assertions/Assert.cs b/src/TestFramework/TestFramework/Assertions/Assert.cs index a6ec288cf0..f630895073 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs b/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs index bf76e223d5..1ddbe5a731 100644 --- a/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs +++ b/src/TestFramework/TestFramework/Assertions/CollectionAssert.cs @@ -1,11 +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; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Assertions/StringAssert.cs b/src/TestFramework/TestFramework/Assertions/StringAssert.cs index 3f0de64de9..b4f88415d3 100644 --- a/src/TestFramework/TestFramework/Assertions/StringAssert.cs +++ b/src/TestFramework/TestFramework/Assertions/StringAssert.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text.RegularExpressions; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs index 270452d4db..4fdb946813 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestTools.UnitTesting.Internal; namespace Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs index ac30e26910..bd1f890128 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DataSourceAttribute.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs index 3361ea15d0..48825c992c 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.ComponentModel; -using System.Globalization; -using System.Reflection; using Microsoft.VisualStudio.TestTools.UnitTesting.Internal; diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataProvider.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataProvider.cs index 9cc9745589..6b04212aa6 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataProvider.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataProvider.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; internal static class DynamicDataProvider diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/IDynamicDataOperations.cs b/src/TestFramework/TestFramework/Attributes/DataSource/IDynamicDataOperations.cs index b54bef8ccc..e865440d94 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/IDynamicDataOperations.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/IDynamicDataOperations.cs @@ -1,8 +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.Reflection; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; internal interface IDynamicDataOperations diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionAttribute.cs index 5cd6c160b8..7ed4c41298 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionAttribute.cs @@ -1,8 +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.Globalization; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionBaseAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionBaseAttribute.cs index e15d9f4889..1ce1a23c30 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionBaseAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/ExpectedExceptionBaseAttribute.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Globalization; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TestCategoryAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TestCategoryAttribute.cs index c592252ee1..fd4633692e 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/TestCategoryAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TestCategoryAttribute.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TestTimeout.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TestTimeout.cs index 6258616497..3c5aab0c09 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/TestTimeout.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TestTimeout.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Friends.cs b/src/TestFramework/TestFramework/Friends.cs index 6d6ee74825..ebbc3313b8 100644 --- a/src/TestFramework/TestFramework/Friends.cs +++ b/src/TestFramework/TestFramework/Friends.cs @@ -1,8 +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.Runtime.CompilerServices; - [assembly: InternalsVisibleTo("Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] [assembly: InternalsVisibleTo("Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")] diff --git a/src/TestFramework/TestFramework/GenericParameterHelper.cs b/src/TestFramework/TestFramework/GenericParameterHelper.cs index 94e0308c15..a689fed725 100644 --- a/src/TestFramework/TestFramework/GenericParameterHelper.cs +++ b/src/TestFramework/TestFramework/GenericParameterHelper.cs @@ -1,9 +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; -using System.Diagnostics.CodeAnalysis; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Interfaces/EmptyDataSourceExceptionInfoExtensions.cs b/src/TestFramework/TestFramework/Interfaces/EmptyDataSourceExceptionInfoExtensions.cs index 6033eaa74f..b281bb829c 100644 --- a/src/TestFramework/TestFramework/Interfaces/EmptyDataSourceExceptionInfoExtensions.cs +++ b/src/TestFramework/TestFramework/Interfaces/EmptyDataSourceExceptionInfoExtensions.cs @@ -1,9 +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.Globalization; -using System.Reflection; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; internal static class EmptyDataSourceExceptionInfoExtensions diff --git a/src/TestFramework/TestFramework/Interfaces/ITestDataSource.cs b/src/TestFramework/TestFramework/Interfaces/ITestDataSource.cs index 55fe97f6e6..ea1d9dbc26 100644 --- a/src/TestFramework/TestFramework/Interfaces/ITestDataSource.cs +++ b/src/TestFramework/TestFramework/Interfaces/ITestDataSource.cs @@ -1,8 +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.Reflection; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Interfaces/ITestDataSourceEmptyDataSourceExceptionInfo.cs b/src/TestFramework/TestFramework/Interfaces/ITestDataSourceEmptyDataSourceExceptionInfo.cs index e704a2f5ee..17aaece396 100644 --- a/src/TestFramework/TestFramework/Interfaces/ITestDataSourceEmptyDataSourceExceptionInfo.cs +++ b/src/TestFramework/TestFramework/Interfaces/ITestDataSourceEmptyDataSourceExceptionInfo.cs @@ -1,8 +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.Reflection; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; internal interface ITestDataSourceEmptyDataSourceExceptionInfo diff --git a/src/TestFramework/TestFramework/Interfaces/ITestMethod.cs b/src/TestFramework/TestFramework/Interfaces/ITestMethod.cs index 7075480d95..3f406901e8 100644 --- a/src/TestFramework/TestFramework/Interfaces/ITestMethod.cs +++ b/src/TestFramework/TestFramework/Interfaces/ITestMethod.cs @@ -1,8 +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.Reflection; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Internal/DebugEx.cs b/src/TestFramework/TestFramework/Internal/DebugEx.cs index 2f988ea9b1..8ce56c4b86 100644 --- a/src/TestFramework/TestFramework/Internal/DebugEx.cs +++ b/src/TestFramework/TestFramework/Internal/DebugEx.cs @@ -1,9 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; [SuppressMessage("ApiDesign", "RS0030:Do not used banned APIs", Justification = "Replacement API to allow nullable hints for compiler")] diff --git a/src/TestFramework/TestFramework/Internal/ReflectionTestMethodInfo.cs b/src/TestFramework/TestFramework/Internal/ReflectionTestMethodInfo.cs index a3ce7ea801..6eee7ba64e 100644 --- a/src/TestFramework/TestFramework/Internal/ReflectionTestMethodInfo.cs +++ b/src/TestFramework/TestFramework/Internal/ReflectionTestMethodInfo.cs @@ -1,9 +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.Globalization; -using System.Reflection; - namespace Microsoft.VisualStudio.TestTools.UnitTesting.Internal; internal sealed class ReflectionTestMethodInfo : MethodInfo diff --git a/src/TestFramework/TestFramework/Internal/StringEx.cs b/src/TestFramework/TestFramework/Internal/StringEx.cs index ac7c314feb..27a38704bc 100644 --- a/src/TestFramework/TestFramework/Internal/StringEx.cs +++ b/src/TestFramework/TestFramework/Internal/StringEx.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; internal static class StringEx diff --git a/src/TestFramework/TestFramework/Internal/TestDataSourceUtilities.cs b/src/TestFramework/TestFramework/Internal/TestDataSourceUtilities.cs index 4a5efebcb5..525f25fda2 100644 --- a/src/TestFramework/TestFramework/Internal/TestDataSourceUtilities.cs +++ b/src/TestFramework/TestFramework/Internal/TestDataSourceUtilities.cs @@ -1,10 +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; -using System.Globalization; -using System.Reflection; - namespace Microsoft.VisualStudio.TestTools.UnitTesting.Internal; internal static class TestDataSourceUtilities diff --git a/src/TestFramework/TestFramework/Internal/UtfHelper.cs b/src/TestFramework/TestFramework/Internal/UtfHelper.cs index 73ebb2c873..63356e0cb7 100644 --- a/src/TestFramework/TestFramework/Internal/UtfHelper.cs +++ b/src/TestFramework/TestFramework/Internal/UtfHelper.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; - namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// diff --git a/src/TestFramework/TestFramework/Logger.cs b/src/TestFramework/TestFramework/Logger.cs index c12dcae50f..46c4bbd224 100644 --- a/src/TestFramework/TestFramework/Logger.cs +++ b/src/TestFramework/TestFramework/Logger.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - namespace Microsoft.VisualStudio.TestTools.UnitTesting.Logging; /// diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AbortionTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AbortionTests.cs index e8130111cc..d2fd2c24e5 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AbortionTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AbortionTests.cs @@ -1,8 +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.Runtime.InteropServices; - using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; using Microsoft.Testing.Platform.Helpers; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs index ef0053229a..4eb3aaeb1b 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/GenericTestMethodTests.cs @@ -1,8 +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.Text.RegularExpressions; - using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; using Microsoft.Testing.Platform.Helpers; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs index 49216055dd..feccbd7bbd 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs @@ -1,8 +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.Diagnostics; - using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs index fe3753fae4..6d11054c28 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/MaxFailedTestsExtensionTests.cs @@ -1,9 +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.Globalization; -using System.Text.RegularExpressions; - using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; using Microsoft.Testing.Platform.Helpers; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs index 996d1c683e..6aefda6e22 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs @@ -1,8 +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.Runtime.InteropServices; - using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs index 8234276d1a..116b5bef8d 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/Program.cs @@ -1,9 +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.Diagnostics; -using System.Reflection; - using Microsoft.Testing.Extensions; [assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs index 09bcd2b58a..1f2cc307aa 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/RunsettingsTests.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; using Microsoft.Testing.Platform.Helpers; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestClassTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestClassTests.cs index 02f884fb7a..c6bfcd7ef7 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestClassTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestClassTests.cs @@ -1,8 +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.Runtime.InteropServices; - using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestMethodTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestMethodTests.cs index 031b6858c3..82875503c0 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestMethodTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/STATestMethodTests.cs @@ -1,8 +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.Runtime.InteropServices; - using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs index 540b214800..ef332f3e8c 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs @@ -1,8 +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.Runtime.InteropServices; - using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; using Microsoft.Testing.Platform.Helpers; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/LogsCollector.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/LogsCollector.cs index b4846a5370..a8a38b1ac9 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/LogsCollector.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/LogsCollector.cs @@ -1,8 +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.Concurrent; - using static Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100.TestingPlatformClient; namespace Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/ServerModeTestsBase.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/ServerModeTestsBase.cs index 00f2a47feb..581925c1ab 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/ServerModeTestsBase.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/ServerModeTestsBase.cs @@ -1,12 +1,8 @@ // 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; -using System.Globalization; using System.Net; using System.Net.Sockets; -using System.Text; -using System.Text.RegularExpressions; using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/TelemetryCollector.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/TelemetryCollector.cs index ac621b10fd..7b48806dc5 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/TelemetryCollector.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/TelemetryCollector.cs @@ -1,8 +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.Concurrent; - using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; namespace MSTest.Acceptance.IntegrationTests.Messages.V100; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/TestNodeUpdateCollector.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/TestNodeUpdateCollector.cs index b669a13e9b..b49b001157 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/TestNodeUpdateCollector.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/TestNodeUpdateCollector.cs @@ -1,8 +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.Concurrent; - using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; namespace MSTest.Acceptance.IntegrationTests.Messages.V100; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/ClientInfo.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/ClientInfo.cs index a4548d891f..5acc6821ed 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/ClientInfo.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/ClientInfo.cs @@ -1,8 +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.Text.Json; - using Newtonsoft.Json; namespace Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/InitializeRequest.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/InitializeRequest.cs index abf5adb281..f15e94ab37 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/InitializeRequest.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/InitializeRequest.cs @@ -1,8 +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.Text.Json; - using Newtonsoft.Json; namespace Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/RpcListener.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/RpcListener.cs index 6bed732b68..e4eca6facb 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/RpcListener.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/RpcListener.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; internal sealed class ConsoleRpcListener : TraceListener diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/ServerInfo.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/ServerInfo.cs index ccab026462..e2b0e4a49f 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/ServerInfo.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/ServerInfo.cs @@ -1,8 +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.Text.Json; - using Newtonsoft.Json; namespace Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/TestingPlatformClient.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/TestingPlatformClient.cs index 9e9c68f311..a2585481e5 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/TestingPlatformClient.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerMode/v1.0.0/TestingPlatformClient.cs @@ -1,10 +1,7 @@ // 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.Concurrent; -using System.Diagnostics; using System.Net.Sockets; -using System.Text; using MSTest.Acceptance.IntegrationTests.Messages.V100; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadingTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadingTests.cs index 393791acf7..b9e91f090c 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadingTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadingTests.cs @@ -1,8 +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.Runtime.InteropServices; - using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; diff --git a/test/IntegrationTests/MSTest.IntegrationTests/OutputTests.cs b/test/IntegrationTests/MSTest.IntegrationTests/OutputTests.cs index fcb07b4ed8..2ab4ae7562 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/OutputTests.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/OutputTests.cs @@ -1,8 +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.Globalization; - using FluentAssertions; using Microsoft.MSTestV2.CLIAutomation; diff --git a/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs b/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs index 12e2592fd6..a3b9b49872 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs @@ -1,9 +1,7 @@ // 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.Concurrent; using System.Collections.Immutable; -using System.Diagnostics; using DiscoveryAndExecutionTests.Utilities; diff --git a/test/IntegrationTests/MSTest.IntegrationTests/Utilities/TestCaseFilterFactory.cs b/test/IntegrationTests/MSTest.IntegrationTests/Utilities/TestCaseFilterFactory.cs index a662bb0f00..61976debed 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/Utilities/TestCaseFilterFactory.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/Utilities/TestCaseFilterFactory.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Linq.Expressions; -using System.Reflection; -using System.Text; -using System.Text.RegularExpressions; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; diff --git a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/DeploymentTests.cs b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/DeploymentTests.cs index 0125ea0206..4ef5aaf14c 100644 --- a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/DeploymentTests.cs +++ b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/DeploymentTests.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.MSTestV2.CLIAutomation; namespace MSTest.VstestConsoleWrapper.IntegrationTests; diff --git a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DataSourceTests.cs b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DataSourceTests.cs index 71ca40fa64..31a41e6d4a 100644 --- a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DataSourceTests.cs +++ b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DataSourceTests.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.MSTestV2.CLIAutomation; namespace MSTest.VstestConsoleWrapper.IntegrationTests; diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AbortionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AbortionTests.cs index 80d9cfb1a0..e35a768106 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AbortionTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/AbortionTests.cs @@ -1,8 +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.Runtime.InteropServices; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs index 5805981732..6dd94e88c1 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashDumpTests.cs @@ -1,8 +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.Runtime.InteropServices; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs index 56ad9445d5..2b2da26c79 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/CrashPlusHangDumpTests.cs @@ -1,8 +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.Runtime.InteropServices; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs index 2bf2316c5b..2dd83c8e23 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs @@ -1,8 +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.Text.RegularExpressions; - using Microsoft.Testing.Platform.Configurations; namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs index 55fdea8a53..3ea7ab3952 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExecutionTests.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExitOnProcessExitTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExitOnProcessExitTests.cs index d7382cc3b0..b1cdf270aa 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExitOnProcessExitTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ExitOnProcessExitTests.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs index a46fd94340..c373ae6ccf 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpOutputTests.cs @@ -1,8 +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.Runtime.InteropServices; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs index 15d4bfe244..d00609c269 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HangDumpTests.cs @@ -1,8 +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.Runtime.InteropServices; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs index 737af51263..4831e0ae1e 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceAssert.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; -using System.Text.RegularExpressions; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; internal static class AcceptanceAssert diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs index 5ccb4afda2..ea57006ec2 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Helpers/AcceptanceTestBase.cs @@ -1,11 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Runtime.InteropServices; -using System.Xml.Linq; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; public abstract class AcceptanceTestBase diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs index 12f1a09318..976b275f43 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.ConfigurationFile.cs @@ -1,8 +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.Text.RegularExpressions; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs index 796bcfffe2..e403fdfbe4 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs @@ -1,10 +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.Reflection; -using System.Runtime.InteropServices; -using System.Text.RegularExpressions; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs index 4514fbbfd0..5463488c7f 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/Program.cs @@ -1,9 +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.Diagnostics; -using System.Reflection; - using Microsoft.Testing.Extensions; [assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/RetryFailedTestsTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/RetryFailedTestsTests.cs index cadb19ce16..9a3440cf71 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/RetryFailedTestsTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/RetryFailedTestsTests.cs @@ -3,8 +3,6 @@ // Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. #pragma warning restore IDE0073 // The file header does not match the required text -using System.Runtime.InteropServices; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs index 3215b5ad54..5327fd60e3 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs @@ -1,8 +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.Text.RegularExpressions; - using Microsoft.Testing.Platform.ServerMode.IntegrationTests.Messages.V100; using MSTest.Acceptance.IntegrationTests.Messages.V100; diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs index 4c8706a742..919edc355b 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs @@ -1,8 +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.Text.RegularExpressions; - using Microsoft.Testing.Platform.Configurations; namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs index 979364b7e4..1a47db5bac 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs @@ -1,9 +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.Runtime.InteropServices; -using System.Text.RegularExpressions; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/UnhandledExceptionPolicyTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/UnhandledExceptionPolicyTests.cs index 004d1aeb94..bf567aee73 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/UnhandledExceptionPolicyTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/UnhandledExceptionPolicyTests.cs @@ -1,8 +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.Runtime.InteropServices; - namespace Microsoft.Testing.Platform.Acceptance.IntegrationTests; [TestClass] diff --git a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs index b49d6d337b..6421f15162 100644 --- a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs +++ b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs @@ -1,9 +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.Reflection; -using System.Xml; - using FluentAssertions; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; diff --git a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs index a77daa42fd..227e25def8 100644 --- a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs +++ b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs @@ -1,9 +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; -using System.Reflection; - using FluentAssertions; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; diff --git a/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_DerivedClass.cs b/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_DerivedClass.cs index 08cbb82f2e..3bb8e29f39 100644 --- a/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_DerivedClass.cs +++ b/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_DerivedClass.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace DataRowTestProject; diff --git a/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_Enums.cs b/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_Enums.cs index b3ce205f65..24cdff7f1e 100644 --- a/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_Enums.cs +++ b/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_Enums.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace DataRowTestProject; diff --git a/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_OverriddenGetDisplayName.cs b/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_OverriddenGetDisplayName.cs index b26bc5a3a3..ac37d83d00 100644 --- a/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_OverriddenGetDisplayName.cs +++ b/test/IntegrationTests/TestAssets/DataRowTestProject/DataRowTests_OverriddenGetDisplayName.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace DataRowAttributeTestProject; diff --git a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DataProvider.cs b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DataProvider.cs index 98eda7ca9a..555530f5c6 100644 --- a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DataProvider.cs +++ b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DataProvider.cs @@ -1,8 +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.Reflection; - using LibProjectReferencedByDataSourceTest; namespace DynamicDataTestProject; diff --git a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs index 03635ebb52..88668e8b42 100644 --- a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs +++ b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs @@ -1,8 +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.Reflection; - using DynamicDataTestProject; using LibProjectReferencedByDataSourceTest; diff --git a/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/AssertExTest.cs b/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/AssertExTest.cs index d48bd50e3d..37e0f8709f 100644 --- a/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/AssertExTest.cs +++ b/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/AssertExTest.cs @@ -1,8 +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.Runtime.CompilerServices; - using Microsoft.VisualStudio.TestTools.UnitTesting; using MSTest.Extensibility.Samples; diff --git a/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/TestDataSourceExTests.cs b/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/TestDataSourceExTests.cs index a040957911..17e0c80ab6 100644 --- a/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/TestDataSourceExTests.cs +++ b/test/IntegrationTests/TestAssets/FxExtensibilityTestProject/TestDataSourceExTests.cs @@ -1,9 +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.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace FxExtensibilityTestProject; diff --git a/test/IntegrationTests/TestAssets/HierarchyProject/ClassWithNoNamespace.cs b/test/IntegrationTests/TestAssets/HierarchyProject/ClassWithNoNamespace.cs index 0e6cf14e52..c83e67d045 100644 --- a/test/IntegrationTests/TestAssets/HierarchyProject/ClassWithNoNamespace.cs +++ b/test/IntegrationTests/TestAssets/HierarchyProject/ClassWithNoNamespace.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] diff --git a/test/IntegrationTests/TestAssets/OutputTestProject/Assembly.cs b/test/IntegrationTests/TestAssets/OutputTestProject/Assembly.cs index 5a096fb3d6..1b0e0b0cb6 100644 --- a/test/IntegrationTests/TestAssets/OutputTestProject/Assembly.cs +++ b/test/IntegrationTests/TestAssets/OutputTestProject/Assembly.cs @@ -3,5 +3,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; +using ExecutionScope = Microsoft.VisualStudio.TestTools.UnitTesting.ExecutionScope; + [assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] [assembly: ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] diff --git a/test/IntegrationTests/TestAssets/OutputTestProject/OutputTestProject.csproj b/test/IntegrationTests/TestAssets/OutputTestProject/OutputTestProject.csproj index a7ac324043..fd8f8d9281 100644 --- a/test/IntegrationTests/TestAssets/OutputTestProject/OutputTestProject.csproj +++ b/test/IntegrationTests/TestAssets/OutputTestProject/OutputTestProject.csproj @@ -7,4 +7,5 @@ + diff --git a/test/IntegrationTests/TestAssets/OutputTestProject/UnitTest1.cs b/test/IntegrationTests/TestAssets/OutputTestProject/UnitTest1.cs index 247876bdea..db917d4c97 100644 --- a/test/IntegrationTests/TestAssets/OutputTestProject/UnitTest1.cs +++ b/test/IntegrationTests/TestAssets/OutputTestProject/UnitTest1.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace OutputTestProject; diff --git a/test/IntegrationTests/TestAssets/OutputTestProject/UnitTest2.cs b/test/IntegrationTests/TestAssets/OutputTestProject/UnitTest2.cs index 3d7198907a..2d3d87ed80 100644 --- a/test/IntegrationTests/TestAssets/OutputTestProject/UnitTest2.cs +++ b/test/IntegrationTests/TestAssets/OutputTestProject/UnitTest2.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace OutputTestProject; diff --git a/test/IntegrationTests/TestAssets/ParallelTestClass/Constants.cs b/test/IntegrationTests/TestAssets/ParallelTestClass/Constants.cs index 8f7f36363f..25055c42e0 100644 --- a/test/IntegrationTests/TestAssets/ParallelTestClass/Constants.cs +++ b/test/IntegrationTests/TestAssets/ParallelTestClass/Constants.cs @@ -4,6 +4,8 @@ // Parallel configuration using Microsoft.VisualStudio.TestTools.UnitTesting; +using ExecutionScope = Microsoft.VisualStudio.TestTools.UnitTesting.ExecutionScope; + [assembly: Parallelize(Workers = 2, Scope = ExecutionScope.ClassLevel)] namespace ParallelClassesTestProject; diff --git a/test/IntegrationTests/TestAssets/ParallelTestMethods/Constants.cs b/test/IntegrationTests/TestAssets/ParallelTestMethods/Constants.cs index b14568538e..8aa87bbf69 100644 --- a/test/IntegrationTests/TestAssets/ParallelTestMethods/Constants.cs +++ b/test/IntegrationTests/TestAssets/ParallelTestMethods/Constants.cs @@ -4,6 +4,8 @@ // Parallel configuration using Microsoft.VisualStudio.TestTools.UnitTesting; +using ExecutionScope = Microsoft.VisualStudio.TestTools.UnitTesting.ExecutionScope; + [assembly: Parallelize(Workers = 2, Scope = ExecutionScope.MethodLevel)] namespace ParallelMethodsTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleAssemblyInitializeAndCleanup.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleAssemblyInitializeAndCleanup.cs index 072bcf6331..c2a6b40a74 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleAssemblyInitializeAndCleanup.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleAssemblyInitializeAndCleanup.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanup.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanup.cs index a9cada8692..b191f7c8d1 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanup.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanup.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssembly.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssembly.cs index ee640bb493..6d584cdb5a 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssembly.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssembly.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssemblyAndBeforeEachDerivedClass.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssemblyAndBeforeEachDerivedClass.cs index ae8988aeef..0e45d85674 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssemblyAndBeforeEachDerivedClass.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssemblyAndBeforeEachDerivedClass.cs @@ -1,9 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssemblyAndNone.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssemblyAndNone.cs index 504b64beec..98055d013c 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssemblyAndNone.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfAssemblyAndNone.cs @@ -1,9 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClass.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClass.cs index 20f9522f73..eb43aa7ac3 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClass.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClass.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClassAndBeforeEachDerivedClass.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClassAndBeforeEachDerivedClass.cs index d806abf283..5d9bff160e 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClassAndBeforeEachDerivedClass.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClassAndBeforeEachDerivedClass.cs @@ -1,9 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClassAndNone.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClassAndNone.cs index fb41374bd0..3962444cde 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClassAndNone.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassCleanupEndOfClassAndNone.cs @@ -1,9 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeAndCleanupBeforeEachDerivedClass.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeAndCleanupBeforeEachDerivedClass.cs index be26e3774a..3027b699ce 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeAndCleanupBeforeEachDerivedClass.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeAndCleanupBeforeEachDerivedClass.cs @@ -1,9 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeAndCleanupNone.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeAndCleanupNone.cs index c3d5f362da..98db71eb24 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeAndCleanupNone.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeAndCleanupNone.cs @@ -1,9 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeBeforeEachDerivedClassAndClassCleanupNone.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeBeforeEachDerivedClassAndClassCleanupNone.cs index 228a1fbe5d..e72ec2729d 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeBeforeEachDerivedClassAndClassCleanupNone.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeBeforeEachDerivedClassAndClassCleanupNone.cs @@ -1,9 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeNoneAndClassCleanupBeforeEachDerivedClass.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeNoneAndClassCleanupBeforeEachDerivedClass.cs index 17c99946f9..dbbd039655 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeNoneAndClassCleanupBeforeEachDerivedClass.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleClassInitializeNoneAndClassCleanupBeforeEachDerivedClass.cs @@ -1,9 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfAssemblyAndBeforeEachDerivedClass.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfAssemblyAndBeforeEachDerivedClass.cs index efe957ff83..7e1a4d3eed 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfAssemblyAndBeforeEachDerivedClass.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfAssemblyAndBeforeEachDerivedClass.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfAssemblyAndNone.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfAssemblyAndNone.cs index 591159cb6c..7d99058862 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfAssemblyAndNone.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfAssemblyAndNone.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfClassAndBeforeEachDerivedClass.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfClassAndBeforeEachDerivedClass.cs index 2c621aea2e..b4147a157c 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfClassAndBeforeEachDerivedClass.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfClassAndBeforeEachDerivedClass.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfClassAndNone.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfClassAndNone.cs index 9767ec81d6..12648249fc 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfClassAndNone.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassCleanupEndOfClassAndNone.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeAndCleanupBeforeEachDerivedClass.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeAndCleanupBeforeEachDerivedClass.cs index e239ea472e..5669769de1 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeAndCleanupBeforeEachDerivedClass.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeAndCleanupBeforeEachDerivedClass.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeAndCleanupNone.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeAndCleanupNone.cs index c4c53901fa..11749707a8 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeAndCleanupNone.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeAndCleanupNone.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeBeforeEachDerivedClassAndClassCleanupNone.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeBeforeEachDerivedClassAndClassCleanupNone.cs index c97009c8be..3f83272a39 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeBeforeEachDerivedClassAndClassCleanupNone.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeBeforeEachDerivedClassAndClassCleanupNone.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeNoneAndClassCleanupBeforeEachDerivedClass.cs b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeNoneAndClassCleanupBeforeEachDerivedClass.cs index 9087f8b2f0..fcb2b08bed 100644 --- a/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeNoneAndClassCleanupBeforeEachDerivedClass.cs +++ b/test/IntegrationTests/TestAssets/SuiteLifeCycleTestProject/LifeCycleDerivedClassInitializeNoneAndClassCleanupBeforeEachDerivedClass.cs @@ -1,8 +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.Diagnostics; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace SuiteLifeCycleTestProject; diff --git a/test/IntegrationTests/TestAssets/TestIdProject.DefaultStrategy/TestIdCases.cs b/test/IntegrationTests/TestAssets/TestIdProject.DefaultStrategy/TestIdCases.cs index 7ef1d44620..351e04be54 100644 --- a/test/IntegrationTests/TestAssets/TestIdProject.DefaultStrategy/TestIdCases.cs +++ b/test/IntegrationTests/TestAssets/TestIdProject.DefaultStrategy/TestIdCases.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestTools.UnitTesting; #if LEGACY_TEST_ID diff --git a/test/IntegrationTests/TestAssets/TestProject/Properties/AssemblyInfo.cs b/test/IntegrationTests/TestAssets/TestProject/Properties/AssemblyInfo.cs index d413c515f1..e73e5926fa 100644 --- a/test/IntegrationTests/TestAssets/TestProject/Properties/AssemblyInfo.cs +++ b/test/IntegrationTests/TestAssets/TestProject/Properties/AssemblyInfo.cs @@ -1,8 +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.Runtime.InteropServices; - using Microsoft.VisualStudio.TestTools.UnitTesting; [assembly: TestCategory("a1")] diff --git a/test/Performance/MSTest.Performance.Runner/PipelinesRunner.cs b/test/Performance/MSTest.Performance.Runner/PipelinesRunner.cs index de01ee3219..c9d7214780 100644 --- a/test/Performance/MSTest.Performance.Runner/PipelinesRunner.cs +++ b/test/Performance/MSTest.Performance.Runner/PipelinesRunner.cs @@ -1,8 +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.Runtime.InteropServices; - using Microsoft.Extensions.FileSystemGlobbing; namespace MSTest.Performance.Runner; diff --git a/test/Performance/MSTest.Performance.Runner/Program.cs b/test/Performance/MSTest.Performance.Runner/Program.cs index b615f7baf5..3237deeb73 100644 --- a/test/Performance/MSTest.Performance.Runner/Program.cs +++ b/test/Performance/MSTest.Performance.Runner/Program.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.CommandLine; -using System.Runtime.InteropServices; using Microsoft.Testing.TestInfrastructure; diff --git a/test/Performance/MSTest.Performance.Runner/Scenarios/Scenario1.cs b/test/Performance/MSTest.Performance.Runner/Scenarios/Scenario1.cs index c9c4662bcf..749bfe6c3c 100644 --- a/test/Performance/MSTest.Performance.Runner/Scenarios/Scenario1.cs +++ b/test/Performance/MSTest.Performance.Runner/Scenarios/Scenario1.cs @@ -1,10 +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.Globalization; -using System.Text; -using System.Xml.Linq; - using Microsoft.Testing.TestInfrastructure; namespace MSTest.Performance.Runner.Steps; diff --git a/test/Performance/MSTest.Performance.Runner/Steps/ConcurrencyVisualizer.cs b/test/Performance/MSTest.Performance.Runner/Steps/ConcurrencyVisualizer.cs index 5d0b04ed23..f92666e68f 100644 --- a/test/Performance/MSTest.Performance.Runner/Steps/ConcurrencyVisualizer.cs +++ b/test/Performance/MSTest.Performance.Runner/Steps/ConcurrencyVisualizer.cs @@ -1,11 +1,7 @@ // 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.Diagnostics; -using System.Globalization; using System.IO.Compression; -using System.Runtime.InteropServices; -using System.Text; namespace MSTest.Performance.Runner.Steps; diff --git a/test/Performance/MSTest.Performance.Runner/Steps/DotnetTrace.cs b/test/Performance/MSTest.Performance.Runner/Steps/DotnetTrace.cs index 70d7b95ceb..5742d70b20 100644 --- a/test/Performance/MSTest.Performance.Runner/Steps/DotnetTrace.cs +++ b/test/Performance/MSTest.Performance.Runner/Steps/DotnetTrace.cs @@ -1,9 +1,7 @@ // 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.Diagnostics; using System.IO.Compression; -using System.Runtime.InteropServices; using Microsoft.Testing.TestInfrastructure; diff --git a/test/Performance/MSTest.Performance.Runner/Steps/PerfviewRunner.cs b/test/Performance/MSTest.Performance.Runner/Steps/PerfviewRunner.cs index d45e8b6d17..f83747c6c2 100644 --- a/test/Performance/MSTest.Performance.Runner/Steps/PerfviewRunner.cs +++ b/test/Performance/MSTest.Performance.Runner/Steps/PerfviewRunner.cs @@ -1,11 +1,7 @@ // 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.Diagnostics; -using System.Globalization; using System.IO.Compression; -using System.Runtime.InteropServices; -using System.Text; namespace MSTest.Performance.Runner.Steps; diff --git a/test/Performance/MSTest.Performance.Runner/Steps/PlainProcess.cs b/test/Performance/MSTest.Performance.Runner/Steps/PlainProcess.cs index 6589d9f0d0..98c3708508 100644 --- a/test/Performance/MSTest.Performance.Runner/Steps/PlainProcess.cs +++ b/test/Performance/MSTest.Performance.Runner/Steps/PlainProcess.cs @@ -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.Diagnostics; using System.IO.Compression; using System.Text.Json; diff --git a/test/Performance/MSTest.Performance.Runner/Steps/VSDiagnostics.cs b/test/Performance/MSTest.Performance.Runner/Steps/VSDiagnostics.cs index ea821ecd39..6eb5ee9441 100644 --- a/test/Performance/MSTest.Performance.Runner/Steps/VSDiagnostics.cs +++ b/test/Performance/MSTest.Performance.Runner/Steps/VSDiagnostics.cs @@ -1,9 +1,7 @@ // 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.Diagnostics; using System.IO.Compression; -using System.Runtime.InteropServices; namespace MSTest.Performance.Runner.Steps; diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/NonNullableReferenceNotInitializedSuppressorTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/NonNullableReferenceNotInitializedSuppressorTests.cs index 32cff434a9..23d263569a 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/NonNullableReferenceNotInitializedSuppressorTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/NonNullableReferenceNotInitializedSuppressorTests.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs index f5a6c5807a..6ad08378a2 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/Program.cs @@ -1,8 +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.Reflection; - using Microsoft.Testing.Extensions; [assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs index e55bdf9e1a..eddebfd38a 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs index f5bced8a52..e40a874a3e 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2.cs index 7d98b387cf..16ff04edf8 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/Verifiers/CSharpCodeFixVerifier`2.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp.Testing; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/AssemblyResolverTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/AssemblyResolverTests.cs index 7846e846d7..dea7166c83 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/AssemblyResolverTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/AssemblyResolverTests.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NET462 -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Deployment/AssemblyLoadWorkerTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Deployment/AssemblyLoadWorkerTests.cs index 2776f4c331..508a713858 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Deployment/AssemblyLoadWorkerTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Deployment/AssemblyLoadWorkerTests.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NET462 -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Deployment/DeploymentItemTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Deployment/DeploymentItemTests.cs index 89d7fd16d8..34b48cb028 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Deployment/DeploymentItemTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Deployment/DeploymentItemTests.cs @@ -1,8 +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.Globalization; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Properties/AssemblyInfo.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Properties/AssemblyInfo.cs index 612ad5f14c..9c4a2e3eb1 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Properties/AssemblyInfo.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Properties/AssemblyInfo.cs @@ -1,8 +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.Runtime.InteropServices; - #if NET462 using MSTestAdapter.PlatformServices.UnitTests.Utilities; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopFileOperationsTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopFileOperationsTests.cs index 37f25a76f5..5870fb2ee9 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopFileOperationsTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopFileOperationsTests.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NET462 -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopReflectionOperationsTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopReflectionOperationsTests.cs index 877075b280..c6edd36a0a 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopReflectionOperationsTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopReflectionOperationsTests.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NET462 - -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using MSTestAdapter.PlatformServices.UnitTests.Utilities; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestDeploymentTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestDeploymentTests.cs index 2da4d888eb..269952ba91 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestDeploymentTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestDeploymentTests.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NET462 -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs index 2fbaf9315a..278cdfde1f 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NET462 -using System.Reflection; using System.Security.Policy; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceTests.cs index 310a7d7e07..b9ec70e054 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceTests.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NET462 -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs index 787e96b51a..d08d236425 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs @@ -1,8 +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.Xml; - using Microsoft.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestSettingsProviderTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestSettingsProviderTests.cs index 5eb74aa7cf..b7257bdea3 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestSettingsProviderTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestSettingsProviderTests.cs @@ -1,8 +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.Xml; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/ReflectionOperationsTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/ReflectionOperationsTests.cs index 6ea1f07e05..64a5aefc89 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/ReflectionOperationsTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/ReflectionOperationsTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestDeploymentTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestDeploymentTests.cs index f77edd4e1b..cba32d6214 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestDeploymentTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestDeploymentTests.cs @@ -1,9 +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.Reflection; -using System.Xml; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/ThreadSafeStringWriterTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/ThreadSafeStringWriterTests.cs index 69ae52a851..b7d18b5576 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/ThreadSafeStringWriterTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/ThreadSafeStringWriterTests.cs @@ -1,9 +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.Diagnostics; -using System.Globalization; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TraceListenerManagerTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TraceListenerManagerTests.cs index d95cadf0fa..50334027ac 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TraceListenerManagerTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TraceListenerManagerTests.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WIN_UI -using System.Diagnostics; -using System.Text; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TraceListenerTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TraceListenerTests.cs index f97695a13a..1e93748a6f 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TraceListenerTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TraceListenerTests.cs @@ -3,8 +3,6 @@ #if !WIN_UI -using System.Text; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/AppDomainUtilitiesTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/AppDomainUtilitiesTests.cs index 0456a3cba3..1f91b2374a 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/AppDomainUtilitiesTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/AppDomainUtilitiesTests.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NET462 - -using System.Xml; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/DeploymentUtilityTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/DeploymentUtilityTests.cs index ae47587921..09fcd7bd52 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/DeploymentUtilityTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/DeploymentUtilityTests.cs @@ -1,9 +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.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/DesktopReflectionUtilityTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/DesktopReflectionUtilityTests.cs index fe8a664887..c5819693df 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/DesktopReflectionUtilityTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/DesktopReflectionUtilityTests.cs @@ -2,9 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NET462 -using System.Collections; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/VSInstallationUtilitiesTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/VSInstallationUtilitiesTests.cs index 31909ed3e4..57bf7763de 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/VSInstallationUtilitiesTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/VSInstallationUtilitiesTests.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if NET462 -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/XmlUtilitiesTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/XmlUtilitiesTests.cs index f6f2d13165..42c9135a83 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/XmlUtilitiesTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/XmlUtilitiesTests.cs @@ -3,9 +3,6 @@ #if NET462 -using System.Reflection; -using System.Xml; - using TestFramework.ForTestingMSTest; using static MSTestAdapter.PlatformServices.UnitTests.Utilities.AppDomainUtilitiesTests; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13DeploymentItemUtilityTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13DeploymentItemUtilityTests.cs index dea08157df..ef07e223fd 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13DeploymentItemUtilityTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13DeploymentItemUtilityTests.cs @@ -1,9 +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.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Deployment; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13ReflectionUtilityTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13ReflectionUtilityTests.cs index 027e30af77..3174bf5115 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13ReflectionUtilityTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/ns13ReflectionUtilityTests.cs @@ -1,9 +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; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Utilities; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/ns10TestSourceTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/ns10TestSourceTests.cs index 9884032ded..95ceea6783 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/ns10TestSourceTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/ns10TestSourceTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs index b98e465b0c..61ea77d64a 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorTests.cs @@ -2,10 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.ObjectModel; -using System.Globalization; -using System.Reflection; -using System.Text; -using System.Xml; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorWrapperTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorWrapperTests.cs index 2fef0edc25..13e34b7e83 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorWrapperTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/AssemblyEnumeratorWrapperTests.cs @@ -1,9 +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.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.TestableImplementations; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TestMethodValidatorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TestMethodValidatorTests.cs index 5d0b135572..ef2d8b35b7 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TestMethodValidatorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TestMethodValidatorTests.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.MockedMethodInfoWithExtraAttributes.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.MockedMethodInfoWithExtraAttributes.cs index d8a24c8b88..99d9772523 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.MockedMethodInfoWithExtraAttributes.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.MockedMethodInfoWithExtraAttributes.cs @@ -1,9 +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.Globalization; -using System.Reflection; - #if !NET6_0_OR_GREATER using Polyfills; #endif diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs index 12ef295dc1..60f85dff0e 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs @@ -1,9 +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.Reflection; -using System.Runtime.CompilerServices; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeValidatorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeValidatorTests.cs index c08376ec22..68687c1bd7 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeValidatorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeValidatorTests.cs @@ -1,9 +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.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/UnitTestDiscovererTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/UnitTestDiscovererTests.cs index 2941a271e0..ecc7419286 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/UnitTestDiscovererTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/UnitTestDiscovererTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs index 037ee46cae..5993212f62 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/DynamicDataAttributeTests.cs @@ -1,11 +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; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/ClassCleanupManagerTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/ClassCleanupManagerTests.cs index 223668be9e..2bad83bade 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/ClassCleanupManagerTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/ClassCleanupManagerTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblyInfoTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblyInfoTests.cs index 31f33aca5e..792eaf50e1 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblyInfoTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblyInfoTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblySettingsProviderTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblySettingsProviderTests.cs index 9abcca60a1..854ebb489c 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblySettingsProviderTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblySettingsProviderTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.TestableImplementations; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs index 356bd5a972..2c2bfa50dd 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestExecutionManagerTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestExecutionManagerTests.cs index 046f7d8ed8..bd6cf90af7 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestExecutionManagerTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestExecutionManagerTests.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodFilterTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodFilterTests.cs index 91cce933f9..0d32323d07 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodFilterTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodFilterTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs index 70b8453cac..d9b7d08a8e 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs @@ -1,10 +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.Globalization; -using System.Reflection; -using System.Runtime.CompilerServices; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs index 7041365e7d..ff5fb70d82 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs @@ -1,11 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; -using System.Text; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs index 1e0af49510..9ee66388d7 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs @@ -1,9 +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.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestResultTest.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestResultTest.cs index 387ac1ebad..8e02319239 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestResultTest.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestResultTest.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestRunnerTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestRunnerTests.cs index d5d08b00ee..52524eabf9 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestRunnerTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/UnitTestRunnerTests.cs @@ -1,10 +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.Globalization; -using System.Reflection; -using System.Xml; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Extensions/ExceptionExtensionsTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Extensions/ExceptionExtensionsTests.cs index 79391029ec..4c37529ebf 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Extensions/ExceptionExtensionsTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Extensions/ExceptionExtensionsTests.cs @@ -1,9 +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.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Extensions/MethodInfoExtensionsTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Extensions/MethodInfoExtensionsTests.cs index 9a0fe37271..254f7e0e35 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Extensions/MethodInfoExtensionsTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Extensions/MethodInfoExtensionsTests.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Extensions/TestCaseExtensionsTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Extensions/TestCaseExtensionsTests.cs index 35d5e51709..9e2843c535 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Extensions/TestCaseExtensionsTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Extensions/TestCaseExtensionsTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; using Microsoft.VisualStudio.TestPlatform.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs index 9f22447a8c..f4efd9a523 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/MSTestAdapter.UnitTests.csproj b/test/UnitTests/MSTestAdapter.UnitTests/MSTestAdapter.UnitTests.csproj index 41e859407b..0b11261be0 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/MSTestAdapter.UnitTests.csproj +++ b/test/UnitTests/MSTestAdapter.UnitTests/MSTestAdapter.UnitTests.csproj @@ -33,4 +33,8 @@ + + + + diff --git a/test/UnitTests/MSTestAdapter.UnitTests/MSTestDiscovererTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/MSTestDiscovererTests.cs index de5c7be8bc..70a1335c79 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/MSTestDiscovererTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/MSTestDiscovererTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Discovery; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.TestableImplementations; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/MSTestExecutorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/MSTestExecutorTests.cs index 4407e86d75..2d5d5b8d4c 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/MSTestExecutorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/MSTestExecutorTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs index 7e0eab35dc..59fff453aa 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs @@ -1,8 +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.Xml; - using Microsoft.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/ObjectModel/UnitTestResultTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/ObjectModel/UnitTestResultTests.cs index 7f80016c8e..2261c73862 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/ObjectModel/UnitTestResultTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/ObjectModel/UnitTestResultTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs b/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs index 8c6355c3e8..80dae5ce83 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.cs index 065485ff10..4f2b1640f2 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/CrashDumpTests.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.Diagnostics; using Microsoft.Testing.Extensions.Diagnostics.Resources; using Microsoft.Testing.Extensions.UnitTests.Helpers; diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/HangDumpTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/HangDumpTests.cs index 7c78930cef..461e4a861d 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/HangDumpTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/HangDumpTests.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.Diagnostics; using Microsoft.Testing.Extensions.Diagnostics.Resources; using Microsoft.Testing.Extensions.UnitTests.Helpers; diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Helpers/TestCommandLineOptions.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Helpers/TestCommandLineOptions.cs index d999659995..00fabfa6d4 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Helpers/TestCommandLineOptions.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Helpers/TestCommandLineOptions.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Platform.CommandLine; namespace Microsoft.Testing.Extensions.UnitTests.Helpers; diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs index 5464028d18..c731857d74 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/Program.cs @@ -1,10 +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 System.Reflection; - using Microsoft.Testing.Extensions; +using ExecutionScope = Microsoft.VisualStudio.TestTools.UnitTesting.ExecutionScope; + [assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] [assembly: ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/RetryTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/RetryTests.cs index 5fe152714f..53f3b8f3d3 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/RetryTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/RetryTests.cs @@ -3,8 +3,6 @@ // Licensed under dual-license. See LICENSE.PLATFORMTOOLS.txt file in the project root for full license information. #pragma warning restore IDE0073 // The file header does not match the required text -using System.Globalization; - using Microsoft.Testing.Extensions.Policy; using Microsoft.Testing.Extensions.UnitTests.Helpers; using Microsoft.Testing.Platform.Extensions.CommandLine; diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxCompareToolCommandLineTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxCompareToolCommandLineTests.cs index e8e3005358..1a4160d843 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxCompareToolCommandLineTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxCompareToolCommandLineTests.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.TrxReport.Abstractions; using Microsoft.Testing.Extensions.UnitTests.Helpers; using Microsoft.Testing.Platform.Extensions.CommandLine; diff --git a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxTests.cs index 9ba22507da..23b29e8e5a 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.UnitTests/TrxTests.cs @@ -1,9 +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.Text.RegularExpressions; -using System.Xml.Linq; - using Microsoft.Testing.Extensions.TrxReport.Abstractions; using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/RunSettingsCommandLineOptionsProviderTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/RunSettingsCommandLineOptionsProviderTests.cs index b4e782d03f..1609ade663 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/RunSettingsCommandLineOptionsProviderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/RunSettingsCommandLineOptionsProviderTests.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.VSTestBridge.CommandLine; using Microsoft.Testing.Extensions.VSTestBridge.Resources; using Microsoft.Testing.Extensions.VSTestBridge.UnitTests.Helpers; diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/TestRunParameterCommandLineOptionsProviderTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/TestRunParameterCommandLineOptionsProviderTests.cs index 06225f002d..c97d84f8ae 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/TestRunParameterCommandLineOptionsProviderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/CommandLine/TestRunParameterCommandLineOptionsProviderTests.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Extensions.VSTestBridge.CommandLine; using Microsoft.Testing.Extensions.VSTestBridge.Resources; using Microsoft.Testing.Extensions.VSTestBridge.UnitTests.Helpers; diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs index 409834e19e..1020128690 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs @@ -1,9 +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.Xml.Linq; -using System.Xml.XPath; - using Microsoft.Testing.Extensions.VSTestBridge.CommandLine; using Microsoft.Testing.Extensions.VSTestBridge.ObjectModel; using Microsoft.Testing.Platform.CommandLine; diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs index 8c64d561f7..5af7b8a583 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/Program.cs @@ -1,10 +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 System.Reflection; - using Microsoft.Testing.Extensions; +using ExecutionScope = Microsoft.VisualStudio.TestTools.UnitTesting.ExecutionScope; + [assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] [assembly: ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] diff --git a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/MSBuildTests.cs b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/MSBuildTests.cs index 79a669510d..5bc558d71c 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/MSBuildTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/MSBuildTests.cs @@ -1,8 +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; - using Microsoft.Build.Framework; using Moq; diff --git a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs index 2057080ba4..c05ca317bd 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.MSBuild.UnitTests/Program.cs @@ -1,8 +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.Reflection; - using Microsoft.Testing.Extensions; [assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineTests.cs index 7f426c4ef5..07468dc56c 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/CommandLineTests.cs @@ -1,8 +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.Reflection; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions.CommandLine; using Microsoft.Testing.Platform.Helpers; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs index bc1fb5ee9b..4ea02fad22 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/CommandLine/PlatformCommandLineProviderTests.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Extensions.CommandLine; using Microsoft.Testing.Platform.Resources; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/AggregatedConfigurationTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/AggregatedConfigurationTests.cs index 925ef3073f..77373844a9 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/AggregatedConfigurationTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/AggregatedConfigurationTests.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; using Microsoft.Testing.Platform.Helpers; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationManagerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationManagerTests.cs index 18faf51a91..5d73e93c9b 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationManagerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationManagerTests.cs @@ -1,8 +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.Text; - using Microsoft.Testing.Platform.CommandLine; using Microsoft.Testing.Platform.Configurations; using Microsoft.Testing.Platform.Helpers; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/SystemAsyncMonitorTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/SystemAsyncMonitorTests.cs index a62f3bb5ed..d6d0daaa03 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/SystemAsyncMonitorTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/SystemAsyncMonitorTests.cs @@ -1,8 +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.Diagnostics; - using Microsoft.Testing.Platform.Helpers; namespace Microsoft.Testing.Platform.UnitTests; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/TestCommandLineOptions.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/TestCommandLineOptions.cs index 2020e0fbd4..f58fedb461 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/TestCommandLineOptions.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Helpers/TestCommandLineOptions.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Platform.CommandLine; namespace Microsoft.Testing.Platform.UnitTests.Helpers; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs index 53b2d03ecc..aaeb9dc6d0 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/FileLoggerTests.cs @@ -1,10 +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.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Text; - using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.Logging; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerTests.cs index 97852718f0..5818e30477 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Logging/LoggerTests.cs @@ -1,8 +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.Globalization; - using Microsoft.Testing.Platform.Logging; using Moq; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs index 221fb03524..b73e359482 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs @@ -1,9 +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.Runtime.InteropServices; -using System.Text; - using Microsoft.Testing.Platform.Helpers; using Microsoft.Testing.Platform.OutputDevice.Terminal; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs index ee46862285..f8a7bf63f0 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Program.cs @@ -1,10 +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 System.Reflection; - using Microsoft.Testing.Extensions; +using ExecutionScope = Microsoft.VisualStudio.TestTools.UnitTesting.ExecutionScope; + [assembly: Parallelize(Scope = ExecutionScope.MethodLevel, Workers = 0)] [assembly: ClassCleanupExecution(ClassCleanupBehavior.EndOfClass)] diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs index 5f7440bc80..dc2fef3b58 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs @@ -3,8 +3,6 @@ #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. -using System.Reflection; - using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.ServerMode; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs index 36f0db185d..5eae561595 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs @@ -3,7 +3,6 @@ using System.Net; using System.Net.Sockets; -using System.Text; using Microsoft.Testing.Platform.Capabilities; using Microsoft.Testing.Platform.Capabilities.TestFramework; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs index 547f65e403..27fde2ee59 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/TestApplicationBuilderTests.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.Testing.Platform.Configurations; using Microsoft.Testing.Platform.Extensions.Messages; using Microsoft.Testing.Platform.Extensions.TestHost; diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs index 1f2be37f6d..e059628875 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs @@ -3,9 +3,6 @@ #nullable enable -using System.Diagnostics.CodeAnalysis; -using System.Globalization; - using Microsoft.VisualStudio.TestTools.UnitTesting; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.InconclusiveTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.InconclusiveTests.cs index cde2af40ff..d03c7555c6 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.InconclusiveTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.InconclusiveTests.cs @@ -1,8 +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.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests; diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs index b532333130..fc2d51bf56 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs @@ -3,8 +3,6 @@ #nullable enable -using System.Diagnostics.CodeAnalysis; - using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests; diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/CollectionAssertTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/CollectionAssertTests.cs index 908a0d6ec4..9c96249a35 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/CollectionAssertTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/CollectionAssertTests.cs @@ -3,7 +3,6 @@ #nullable enable -using System.Collections; using System.Collections.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/StringAssertTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/StringAssertTests.cs index 21ef26548d..f910b5acd1 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/StringAssertTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/StringAssertTests.cs @@ -3,9 +3,6 @@ #nullable enable -using System.Diagnostics.CodeAnalysis; -using System.Text.RegularExpressions; - using Microsoft.VisualStudio.TestTools.UnitTesting; using TestFramework.ForTestingMSTest; diff --git a/test/UnitTests/TestFramework.UnitTests/Attributes/DataRowAttributeTests.cs b/test/UnitTests/TestFramework.UnitTests/Attributes/DataRowAttributeTests.cs index b585158ef6..26657b16c4 100644 --- a/test/UnitTests/TestFramework.UnitTests/Attributes/DataRowAttributeTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Attributes/DataRowAttributeTests.cs @@ -1,8 +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.Reflection; - using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; diff --git a/test/Utilities/Automation.CLI/CLITestBase.common.cs b/test/Utilities/Automation.CLI/CLITestBase.common.cs index 35426ea724..6f307a30c4 100644 --- a/test/Utilities/Automation.CLI/CLITestBase.common.cs +++ b/test/Utilities/Automation.CLI/CLITestBase.common.cs @@ -1,8 +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.Xml; - using FluentAssertions; using TestFramework.ForTestingMSTest; diff --git a/test/Utilities/Automation.CLI/CLITestBase.e2e.cs b/test/Utilities/Automation.CLI/CLITestBase.e2e.cs index c1a92af1cb..e6cf592d12 100644 --- a/test/Utilities/Automation.CLI/CLITestBase.e2e.cs +++ b/test/Utilities/Automation.CLI/CLITestBase.e2e.cs @@ -1,8 +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.Runtime.CompilerServices; - using FluentAssertions; using Microsoft.TestPlatform.VsTestConsole.TranslationLayer; diff --git a/test/Utilities/Automation.CLI/DiscoveryEventsHandler.cs b/test/Utilities/Automation.CLI/DiscoveryEventsHandler.cs index e21e5553ec..6c1b1a7cbf 100644 --- a/test/Utilities/Automation.CLI/DiscoveryEventsHandler.cs +++ b/test/Utilities/Automation.CLI/DiscoveryEventsHandler.cs @@ -4,7 +4,6 @@ #nullable enable using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client; diff --git a/test/Utilities/Automation.CLI/Properties/AssemblyInfo.cs b/test/Utilities/Automation.CLI/Properties/AssemblyInfo.cs index a730c9f39e..918aafdae2 100644 --- a/test/Utilities/Automation.CLI/Properties/AssemblyInfo.cs +++ b/test/Utilities/Automation.CLI/Properties/AssemblyInfo.cs @@ -1,8 +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.Runtime.InteropServices; - // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. diff --git a/test/Utilities/Automation.CLI/RunConfiguration.cs b/test/Utilities/Automation.CLI/RunConfiguration.cs index edde844f5d..9bb1c434cf 100644 --- a/test/Utilities/Automation.CLI/RunConfiguration.cs +++ b/test/Utilities/Automation.CLI/RunConfiguration.cs @@ -1,8 +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.Xml; - namespace Microsoft.MSTestV2.CLIAutomation; /// diff --git a/test/Utilities/Automation.CLI/XmlRunSettingsUtilities.cs b/test/Utilities/Automation.CLI/XmlRunSettingsUtilities.cs index 2fd036c6c8..857fead94a 100644 --- a/test/Utilities/Automation.CLI/XmlRunSettingsUtilities.cs +++ b/test/Utilities/Automation.CLI/XmlRunSettingsUtilities.cs @@ -1,8 +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.Xml; - namespace Microsoft.MSTestV2.CLIAutomation; public static class XmlRunSettingsUtilities diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/CommandLine.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/CommandLine.cs index 73693a1896..baad841ddc 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/CommandLine.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/CommandLine.cs @@ -2,7 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.ObjectModel; -using System.Diagnostics.CodeAnalysis; namespace Microsoft.Testing.TestInfrastructure; diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs index a4489f8b11..67b83f1b4f 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/Constants.cs @@ -1,8 +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.Runtime.InteropServices; - namespace Microsoft.Testing.TestInfrastructure; public static class Constants diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/DebuggerUtility.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/DebuggerUtility.cs index ddb5ed161b..93f4111b29 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/DebuggerUtility.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/DebuggerUtility.cs @@ -4,12 +4,6 @@ #pragma warning disable CA1837 // Use 'Environment.ProcessId' #pragma warning disable CA1416 // Validate platform compatibility -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Globalization; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; namespace Microsoft.Testing.TestInfrastructure; diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetCli.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetCli.cs index be08498905..0ab1e70ec0 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetCli.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetCli.cs @@ -1,9 +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; -using System.Diagnostics.CodeAnalysis; - using Polly; using Polly.Contrib.WaitAndRetry; diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxerResult.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxerResult.cs index 589972d538..a02d2ba47a 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxerResult.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxerResult.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.ObjectModel; -using System.Globalization; -using System.Text; namespace Microsoft.Testing.TestInfrastructure; diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessFactory.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessFactory.cs index 4b8d554e4d..4b2e600823 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessFactory.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessFactory.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.TestInfrastructure; public static class ProcessFactory diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessHandle.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessHandle.cs index f6d4d5c172..fb32b027b3 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessHandle.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessHandle.cs @@ -1,8 +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.Diagnostics; - namespace Microsoft.Testing.TestInfrastructure; public sealed class ProcessHandle : IProcessHandle, IDisposable diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/ProjectSystem.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/ProjectSystem.cs index a15bbf5485..91deff4f72 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/ProjectSystem.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/ProjectSystem.cs @@ -1,10 +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.Globalization; -using System.Text; -using System.Xml.Linq; - namespace Microsoft.Testing.TestInfrastructure; public class VSSolution : Folder diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs index 58ec8a7d21..3d4b2ffb33 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/TargetFrameworks.cs @@ -1,8 +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.Runtime.InteropServices; - namespace Microsoft.Testing.TestInfrastructure; public static class TargetFrameworks diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TempDirectory.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TempDirectory.cs index 95da03bbb7..437e2fc070 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TempDirectory.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/TempDirectory.cs @@ -1,8 +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.Text; - namespace Microsoft.Testing.TestInfrastructure; public class TempDirectory : IDisposable diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestAssetFixtureBase.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestAssetFixtureBase.cs index 0f25e2993b..e2eff19a9b 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestAssetFixtureBase.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestAssetFixtureBase.cs @@ -1,8 +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.Concurrent; - namespace Microsoft.Testing.TestInfrastructure; public interface ITestAssetFixture : IDisposable diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHost.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHost.cs index 60676a556a..32352b750b 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHost.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHost.cs @@ -1,10 +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; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; - using Polly; using Polly.Contrib.WaitAndRetry; diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHostResult.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHostResult.cs index 31f86f2d16..6cdb8a76da 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHostResult.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHostResult.cs @@ -2,8 +2,6 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. using System.Collections.ObjectModel; -using System.Globalization; -using System.Text; namespace Microsoft.Testing.TestInfrastructure; diff --git a/test/Utilities/TestFramework.ForTestingMSTest/AdapterToTestPlatform.cs b/test/Utilities/TestFramework.ForTestingMSTest/AdapterToTestPlatform.cs index 16b511b637..82f19d1675 100644 --- a/test/Utilities/TestFramework.ForTestingMSTest/AdapterToTestPlatform.cs +++ b/test/Utilities/TestFramework.ForTestingMSTest/AdapterToTestPlatform.cs @@ -1,10 +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.Diagnostics; -using System.Diagnostics.CodeAnalysis; -using System.Reflection; - using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; diff --git a/test/Utilities/TestFramework.ForTestingMSTest/TestContainer.cs b/test/Utilities/TestFramework.ForTestingMSTest/TestContainer.cs index c242c4a119..0c85b5f063 100644 --- a/test/Utilities/TestFramework.ForTestingMSTest/TestContainer.cs +++ b/test/Utilities/TestFramework.ForTestingMSTest/TestContainer.cs @@ -1,9 +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.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; - namespace TestFramework.ForTestingMSTest; /// From 2564c52733fde212f367e5869abdc12046c6c8e5 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 23 Dec 2024 19:23:05 +0100 Subject: [PATCH 169/273] Fix analyzer messages not localized (#4434) --- eng/verify-nupkgs.ps1 | 2 +- .../MSTest.Analyzers.Package.csproj | 10 ++-- .../AnalyzersTests.cs | 49 +++++++++++++++++++ .../DotnetCli.cs | 6 ++- 4 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AnalyzersTests.cs diff --git a/eng/verify-nupkgs.ps1 b/eng/verify-nupkgs.ps1 index bef6bb99db..d39c6437ba 100644 --- a/eng/verify-nupkgs.ps1 +++ b/eng/verify-nupkgs.ps1 @@ -24,7 +24,7 @@ function Confirm-NugetPackages { "MSTest.TestFramework" = 148; "MSTest.TestAdapter" = 74; "MSTest" = 6; - "MSTest.Analyzers" = 10; + "MSTest.Analyzers" = 50; } $packageDirectory = Resolve-Path "$PSScriptRoot/../artifacts/packages/$configuration" diff --git a/src/Analyzers/MSTest.Analyzers.Package/MSTest.Analyzers.Package.csproj b/src/Analyzers/MSTest.Analyzers.Package/MSTest.Analyzers.Package.csproj index 36f7766c50..21b9ba6b27 100644 --- a/src/Analyzers/MSTest.Analyzers.Package/MSTest.Analyzers.Package.csproj +++ b/src/Analyzers/MSTest.Analyzers.Package/MSTest.Analyzers.Package.csproj @@ -34,10 +34,14 @@ - - - + + + + + + + diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AnalyzersTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AnalyzersTests.cs new file mode 100644 index 0000000000..95f24f5b3c --- /dev/null +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AnalyzersTests.cs @@ -0,0 +1,49 @@ +// 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.Testing.Platform.Acceptance.IntegrationTests; +using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; + +namespace MSTest.Acceptance.IntegrationTests; + +[TestClass] +public sealed class AnalyzersTests : AcceptanceTestBase +{ + [TestMethod] + public async Task AnalyzerMessagesShouldBeLocalized() + { + string code = """ +#file Analyzers.csproj + + + + $TargetFrameworks$ + true + + + + +#file UnitTest1.cs +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[TestClass] +public class UnitTest1 +{ + [DataRow(0)] + public void TestMethod() + { + } +} +""".PatchTargetFrameworks(TargetFrameworks.NetCurrent) + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion); + + using TestAsset testAsset = await TestAsset.GenerateAssetAsync("Analyzers", code); + DotnetMuxerResult result = await DotnetCli.RunAsync($"build {testAsset.TargetAssetPath}", AcceptanceFixture.NuGetGlobalPackagesFolder.Path, environmentVariables: new() + { + ["DOTNET_CLI_UI_LANGUAGE"] = "it-IT", + ["PreferredUILang"] = "it-IT", + ["VSLang"] = "1040", + }, warnAsError: false); + result.AssertOutputContains("DataRow deve essere impostato solo su un metodo di test"); + } +} diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetCli.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetCli.cs index 0ab1e70ec0..7e41079af4 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetCli.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetCli.cs @@ -80,7 +80,11 @@ public static async Task RunAsync( } } - environmentVariables.Add(key!, entry.Value!.ToString()!); + // We use TryAdd to let tests "overwrite" existing environment variables. + // Consider that the given dictionary has "TESTINGPLATFORM_UI_LANGUAGE" as a key. + // And also Environment.GetEnvironmentVariables() is returning TESTINGPLATFORM_UI_LANGUAGE. + // In that case, we do a "TryAdd" which effectively means the value from the original dictionary wins. + environmentVariables.TryAdd(key!, entry.Value!.ToString()!); } if (disableTelemetry) From db7191df6596341563abc73065c43f7244aa478c Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 24 Dec 2024 05:32:12 +1100 Subject: [PATCH 170/273] remove redundant requestedName != null check (#4433) --- src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs index d28be18d55..2d1a1946f2 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs @@ -356,7 +356,7 @@ protected virtual return null; } - DebugEx.Assert(requestedName != null && !StringEx.IsNullOrEmpty(requestedName.Name), "MSTest.AssemblyResolver.OnResolve: requested is null or name is empty!"); + DebugEx.Assert(!StringEx.IsNullOrEmpty(requestedName.Name), "MSTest.AssemblyResolver.OnResolve: requested name is empty!"); foreach (string dir in searchDirectorypaths) { From 9cdc9fa2336ef9c91f9a001c393e29bb4fa9862a Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 24 Dec 2024 05:36:06 +1100 Subject: [PATCH 171/273] remove redundant bodies (#4437) --- .../SourceGeneratedDynamicDataOperations.cs | 4 +--- .../OutputDevice/Terminal/IProgressMessage.cs | 4 +--- .../ServerMode/IPushOnlyProtocolConsumer.cs | 4 +--- .../Attributes/TestMethod/STATestClassAttribute.cs | 4 +--- 4 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/SourceGeneratedDynamicDataOperations.cs b/src/Adapter/MSTest.TestAdapter/SourceGeneratedDynamicDataOperations.cs index 79ec0ea968..9ea21161d0 100644 --- a/src/Adapter/MSTest.TestAdapter/SourceGeneratedDynamicDataOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/SourceGeneratedDynamicDataOperations.cs @@ -3,6 +3,4 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; -internal sealed class SourceGeneratedDynamicDataOperations : DynamicDataOperations -{ -} +internal sealed class SourceGeneratedDynamicDataOperations : DynamicDataOperations; diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/IProgressMessage.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/IProgressMessage.cs index ae77f9d53c..f8f331ab23 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/IProgressMessage.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/IProgressMessage.cs @@ -6,6 +6,4 @@ namespace Microsoft.Testing.Platform.OutputDevice.Terminal; /// /// Error or warning message that was sent to screen during the test run. /// -internal interface IProgressMessage -{ -} +internal interface IProgressMessage; diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/IPushOnlyProtocolConsumer.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/IPushOnlyProtocolConsumer.cs index b479afef2d..8ad796cc5c 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/IPushOnlyProtocolConsumer.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/IPushOnlyProtocolConsumer.cs @@ -5,6 +5,4 @@ namespace Microsoft.Testing.Platform.ServerMode; -internal interface IPushOnlyProtocolConsumer : IDataConsumer, ITestSessionLifetimeHandler -{ -} +internal interface IPushOnlyProtocolConsumer : IDataConsumer, ITestSessionLifetimeHandler; diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/STATestClassAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/STATestClassAttribute.cs index c78a974fbd..a82ef52330 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/STATestClassAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/STATestClassAttribute.cs @@ -7,6 +7,4 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// The test class attribute. /// [AttributeUsage(AttributeTargets.Class, Inherited = false)] -public class STATestClassAttribute : TestClassAttribute -{ -} +public class STATestClassAttribute : TestClassAttribute; From ccf922f2d5fc1999e2cc4c7e73aebd2122691edd Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 24 Dec 2024 05:37:10 +1100 Subject: [PATCH 172/273] merge some conditional expressions (#4436) --- .../Tasks/DotnetMuxerLocator.cs | 2 +- .../CommandLine/CommandLineOptionsProxy.cs | 5 ++--- .../OutputDevice/TerminalOutputDevice.cs | 4 +--- .../AssemblyResolverTests.cs | 4 ++-- .../Services/MSTestAdapterSettingsTests.cs | 2 +- .../ServerMode/FormatterUtilitiesTests.cs | 4 +--- 6 files changed, 8 insertions(+), 13 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs index 5f6d7e4bb0..11a28f280b 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs @@ -369,7 +369,7 @@ public bool TryGetDotnetPathByArchitecture( } } - return archType is null ? throw new InvalidOperationException("Invalid image") : archType; + return archType ?? throw new InvalidOperationException("Invalid image"); } // See https://opensource.apple.com/source/xnu/xnu-2050.18.24/EXTERNAL_HEADERS/mach-o/loader.h diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsProxy.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsProxy.cs index ee83a5664e..fd5d11df3d 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsProxy.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/CommandLineOptionsProxy.cs @@ -8,9 +8,8 @@ internal sealed class CommandLineOptionsProxy : ICommandLineOptions private ICommandLineOptions? _commandLineOptions; public bool IsOptionSet(string optionName) - => _commandLineOptions is null - ? throw new InvalidOperationException(Resources.PlatformResources.CommandLineOptionsNotReady) - : _commandLineOptions.IsOptionSet(optionName); + => _commandLineOptions?.IsOptionSet(optionName) ?? + throw new InvalidOperationException(Resources.PlatformResources.CommandLineOptionsNotReady); public bool TryGetOptionArgumentList(string optionName, [NotNullWhen(true)] out string[]? arguments) => _commandLineOptions is null diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs index a82729dc54..f5424d4ede 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs @@ -151,9 +151,7 @@ await _policiesService.RegisterOnAbortCallbackAsync( // func. : () => _isVSTestMode || _isListTests || _isServerMode ? false - : _testHostControllerInfo.IsCurrentProcessTestHostController == null - ? null - : !_testHostControllerInfo.IsCurrentProcessTestHostController; + : !_testHostControllerInfo.IsCurrentProcessTestHostController; // This is single exe run, don't show all the details of assemblies and their summaries. _terminalTestReporter = new TerminalTestReporter(_console, new() diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/AssemblyResolverTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/AssemblyResolverTests.cs index dea7166c83..d721d4c831 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/AssemblyResolverTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/AssemblyResolverTests.cs @@ -204,7 +204,7 @@ public TestableAssemblyResolver(IList directories) public Func, string, bool, Assembly> SearchAssemblySetter { get; internal set; } - protected override bool DoesDirectoryExist(string path) => DoesDirectoryExistSetter == null ? base.DoesDirectoryExist(path) : DoesDirectoryExistSetter(path); + protected override bool DoesDirectoryExist(string path) => DoesDirectoryExistSetter?.Invoke(path) ?? base.DoesDirectoryExist(path); protected override string[] GetDirectories(string path) => GetDirectoriesSetter == null ? base.GetDirectories(path) : GetDirectoriesSetter(path); @@ -212,7 +212,7 @@ protected override Assembly SearchAssembly(List searchDirectorypaths, st ? base.SearchAssembly(searchDirectorypaths, name, isReflectionOnly) : SearchAssemblySetter(searchDirectorypaths, name, isReflectionOnly); - protected override bool DoesFileExist(string filePath) => DoesFileExistSetter == null ? base.DoesFileExist(filePath) : DoesFileExistSetter(filePath); + protected override bool DoesFileExist(string filePath) => DoesFileExistSetter?.Invoke(filePath) ?? base.DoesFileExist(filePath); protected override Assembly LoadAssemblyFrom(string path) => LoadAssemblyFromSetter == null ? base.LoadAssemblyFrom(path) : LoadAssemblyFromSetter(path); diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs index d08d236425..b39f3966d3 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs @@ -383,7 +383,7 @@ public TestableMSTestAdapterSettings() public Func ExpandEnvironmentVariablesSetter { get; set; } - protected override bool DoesDirectoryExist(string path) => DoesDirectoryExistSetter == null ? base.DoesDirectoryExist(path) : DoesDirectoryExistSetter(path); + protected override bool DoesDirectoryExist(string path) => DoesDirectoryExistSetter?.Invoke(path) ?? base.DoesDirectoryExist(path); protected override string ExpandEnvironmentVariables(string path) => ExpandEnvironmentVariablesSetter == null ? base.ExpandEnvironmentVariables(path) : ExpandEnvironmentVariablesSetter(path); } diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs index dc2fef3b58..1e99ae1ed8 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs @@ -133,9 +133,7 @@ private static void CustomAssert(Type type, object instanceDeserialized, object } public static string? FormatSerializerTypes(MethodInfo methodInfo, object?[]? data) - => data is not null - ? (data[0] as Type)?.Name - : null; + => (data?[0] as Type)?.Name; private static void AssertSerialize(Type type, string instanceSerialized) { From fdf27d2e2682eb4645272bf2a6828ce9fe28a0bb Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 23 Dec 2024 21:11:58 +0100 Subject: [PATCH 173/273] Test coverage for TestContext analyzer for case sensitivity (#4438) --- .../TestContextShouldBeValidAnalyzerTests.cs | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs index e2965c8523..d3c26caea7 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs @@ -342,6 +342,35 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenTestContextPropertyIsNotCasedCorrectly_Diagnostic() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + public TestContext {|#0:testContext|} { get; set; } + } + """; + string fixedCode = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + public TestContext TestContext { get; set; } + } + """; + + await VerifyCS.VerifyCodeFixAsync( + code, + VerifyCS.Diagnostic(TestContextShouldBeValidAnalyzer.TestContextShouldBeValidRule) + .WithLocation(0), + fixedCode); + } + [TestMethod] public async Task WhenTestContextPropertyIsReadonly_AssignedInConstructor_NoDiagnostic() { From 49594fbe3c9c4c5131a7d2d32aa682927d3136c9 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 24 Dec 2024 07:12:48 +1100 Subject: [PATCH 174/273] invoke methods as extension methods (#4423) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../MSTest.TestAdapter/Execution/TestMethodInfo.cs | 2 +- .../MSTest.TestAdapter/Execution/TestMethodRunner.cs | 2 +- .../TestingPlatformBuilderHook.cs | 2 +- .../Extensions/UnitTestOutcomeExtensionsTests.cs | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs index 5a2152f2be..966eb13863 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs @@ -646,7 +646,7 @@ private bool RunTestInitializeMethod(object classInstance, TestResult result) // Prefix the exception message with the exception type name as prefix when exception is not assert exception. string exceptionMessage = realException is UnitTestAssertException ? realException.TryGetMessage() - : ExceptionHelper.GetFormattedExceptionMessage(realException); + : realException.GetFormattedExceptionMessage(); string errorMessage = string.Format( CultureInfo.CurrentCulture, Resource.UTA_InitMethodThrows, diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs index e7fadf8759..a3ee59fa98 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs @@ -443,7 +443,7 @@ private static UTF.UnitTestOutcome GetAggregateOutcome(List results) UTF.UnitTestOutcome aggregateOutcome = results[0].Outcome; foreach (TestResult result in results) { - aggregateOutcome = UnitTestOutcomeExtensions.GetMoreImportantOutcome(aggregateOutcome, result.Outcome); + aggregateOutcome = aggregateOutcome.GetMoreImportantOutcome(result.Outcome); } return aggregateOutcome; diff --git a/src/Platform/Microsoft.Testing.Extensions.MSBuild/TestingPlatformBuilderHook.cs b/src/Platform/Microsoft.Testing.Extensions.MSBuild/TestingPlatformBuilderHook.cs index 53e32087d3..badb923f0d 100644 --- a/src/Platform/Microsoft.Testing.Extensions.MSBuild/TestingPlatformBuilderHook.cs +++ b/src/Platform/Microsoft.Testing.Extensions.MSBuild/TestingPlatformBuilderHook.cs @@ -8,5 +8,5 @@ namespace Microsoft.Testing.Platform.MSBuild; public static class TestingPlatformBuilderHook { public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, string[] _) - => MSBuildExtensions.AddMSBuild(testApplicationBuilder); + => testApplicationBuilder.AddMSBuild(); } diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Extensions/UnitTestOutcomeExtensionsTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Extensions/UnitTestOutcomeExtensionsTests.cs index 852811883e..77c056e763 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Extensions/UnitTestOutcomeExtensionsTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Extensions/UnitTestOutcomeExtensionsTests.cs @@ -62,25 +62,25 @@ public void ToUnitTestResultsForUnknownTestResultsConvertsToErrorUnitTestResults public void GetMoreImportantOutcomeShouldReturnFailIfTwoOutcomesAreFailedAndInconclusive() { - UTF.UnitTestOutcome resultOutcome = UnitTestOutcomeExtensions.GetMoreImportantOutcome(UTF.UnitTestOutcome.Failed, UTF.UnitTestOutcome.Inconclusive); + UTF.UnitTestOutcome resultOutcome = UTF.UnitTestOutcome.Failed.GetMoreImportantOutcome(UTF.UnitTestOutcome.Inconclusive); Verify(resultOutcome == UTF.UnitTestOutcome.Failed); } public void GetMoreImportantOutcomeShouldReturnInconclusiveIfTwoOutcomesArePassedAndInconclusive() { - UTF.UnitTestOutcome resultOutcome = UnitTestOutcomeExtensions.GetMoreImportantOutcome(UTF.UnitTestOutcome.Passed, UTF.UnitTestOutcome.Inconclusive); + UTF.UnitTestOutcome resultOutcome = UTF.UnitTestOutcome.Passed.GetMoreImportantOutcome(UTF.UnitTestOutcome.Inconclusive); Verify(resultOutcome == UTF.UnitTestOutcome.Inconclusive); } public void GetMoreImportantOutcomeShouldReturnFailedIfTwoOutcomesArePassedAndFailed() { - UTF.UnitTestOutcome resultOutcome = UnitTestOutcomeExtensions.GetMoreImportantOutcome(UTF.UnitTestOutcome.Passed, UTF.UnitTestOutcome.Failed); + UTF.UnitTestOutcome resultOutcome = UTF.UnitTestOutcome.Passed.GetMoreImportantOutcome(UTF.UnitTestOutcome.Failed); Verify(resultOutcome == UTF.UnitTestOutcome.Failed); } public void GetMoreImportantOutcomeShouldReturnFailedIfBothOutcomesAreFailed() { - UTF.UnitTestOutcome resultOutcome = UnitTestOutcomeExtensions.GetMoreImportantOutcome(UTF.UnitTestOutcome.Failed, UTF.UnitTestOutcome.Failed); + UTF.UnitTestOutcome resultOutcome = UTF.UnitTestOutcome.Failed.GetMoreImportantOutcome(UTF.UnitTestOutcome.Failed); Verify(resultOutcome == UTF.UnitTestOutcome.Failed); } } From 61aaa2de9f4fd387a0da7c8a5e1ffe172efd3651 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 23 Dec 2024 22:12:44 +0100 Subject: [PATCH 175/273] [main] Update dependencies from devdiv/DevDiv/vs-code-coverage, microsoft/testanywhere (#4416) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5a85febd43..fce8d0341e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,13 +13,13 @@ https://github.com/dotnet/arcade 45d845e04c05fbe5da9838c454bbc3af1df6be81 - + https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage - eb105201ff904a7d5c6fac39de838a4bb6966a93 + 8ec298cce46b78be7e9ceb9e7403ad555b51f12b - + https://github.com/microsoft/testanywhere - 2346f405dcb5150b567970995dc978feb26b2db0 + 0381237a1a7c06d5e36523400235d2bc013ad058 diff --git a/eng/Versions.props b/eng/Versions.props index 0e7161ac55..d38cff4451 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,8 +8,8 @@ 10.0.0-beta.24604.4 - 17.13.2-preview.24606.2 + 17.14.0-preview.24620.2 - 1.0.0-alpha.24473.2 + 1.0.0-alpha.24619.2 From b3ac84939ecfa88b3afa0202ad8f77cdee976e76 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Tue, 24 Dec 2024 19:02:21 +1100 Subject: [PATCH 176/273] method scope fix (#4415) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../MSTest.TestAdapter/MSTestSettings.cs | 2 +- .../MSTestSettingsTests.cs | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs index a4041e8345..dd2320c4d7 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs +++ b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs @@ -1006,7 +1006,7 @@ internal static void SetSettingsFromConfig(IConfiguration configuration, IMessag if (configuration["mstest:parallelism:scope"] is string value) { value = value.Equals("class", StringComparison.OrdinalIgnoreCase) ? "ClassLevel" - : value.Equals("methood", StringComparison.OrdinalIgnoreCase) ? "MethodLevel" : value; + : value.Equals("method", StringComparison.OrdinalIgnoreCase) ? "MethodLevel" : value; if (!TryParseEnum(value, out ExecutionScope scope)) { throw new AdapterSettingsException(string.Format( diff --git a/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs index 59fff453aa..16a33f2e27 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs @@ -1372,5 +1372,25 @@ public void ConfigJson_WithValidValues_ValuesAreSetCorrectly() Verify(settings.ParallelizationWorkers == 4); Verify(settings.ParallelizationScope == ExecutionScope.ClassLevel); } + + [TestMethod] + public void ConfigJson_WithValidValues_MethodScope() + { + // Arrange - setting up valid configuration values + var configDictionary = new Dictionary { { "mstest:parallelism:scope", "method" } }; + + var mockConfig = new Mock(); + mockConfig.Setup(config => config[It.IsAny()]) + .Returns((string key) => configDictionary.TryGetValue(key, out string value) ? value : null); + + var settings = new MSTestSettings(); + + // Act + MSTestSettings.SetSettingsFromConfig(mockConfig.Object, _mockMessageLogger.Object, settings); + + // Assert + Verify(settings.ParallelizationScope == ExecutionScope.MethodLevel); + } + #endregion } From 88bfc954016037732a071b5c8086bae134d093a1 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 24 Dec 2024 17:03:48 +0100 Subject: [PATCH 177/273] Best effort tracking for properties assigned indirectly via fields for TestContext analyzer (#4439) --- .../TestContextShouldBeValidAnalyzer.cs | 98 ++++++++++++++++++- .../TestContextShouldBeValidAnalyzerTests.cs | 23 +++++ 2 files changed, 117 insertions(+), 4 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs index fa3b7aed4b..1b470e263b 100644 --- a/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs @@ -1,6 +1,7 @@ // 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.Concurrent; using System.Collections.Immutable; using Analyzer.Utilities.Extensions; @@ -37,6 +38,35 @@ public sealed class TestContextShouldBeValidAnalyzer : DiagnosticAnalyzer public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(TestContextShouldBeValidRule); + private static IFieldSymbol? TryGetReturnedField(ImmutableArray operations) + { + foreach (IOperation operation in operations) + { + if (TryGetReturnedField(operation) is { } returnedMember) + { + return returnedMember; + } + } + + return null; + } + + private static IFieldSymbol? TryGetReturnedField(IOperation operation) + { + if (operation is IBlockOperation blockOperation) + { + return TryGetReturnedField(blockOperation.Operations); + } + + if (operation is IReturnOperation { ReturnedValue: IFieldReferenceOperation { Field: { } returnedField } }) + { + return returnedField; + } + + // We can't figure out exactly the field returned by this property. + return null; + } + private static bool AssignsParameterToMember(IParameterSymbol parameter, ISymbol member, ImmutableArray operations) { foreach (IOperation operation in operations) @@ -69,6 +99,46 @@ assignmentOperation.Value is IParameterReferenceOperation parameterReference && SymbolEqualityComparer.Default.Equals(parameterReference.Parameter, parameter); } + private static void CollectTestContextFieldsAssignedInConstructor( + IParameterSymbol testContextParameter, + ImmutableArray operations, + ConcurrentBag fieldsAssignedInConstructor) + { + foreach (IOperation operation in operations) + { + CollectTestContextFieldsAssignedInConstructor(testContextParameter, operation, fieldsAssignedInConstructor); + } + } + + private static void CollectTestContextFieldsAssignedInConstructor( + IParameterSymbol testContextParameter, + IOperation operation, + ConcurrentBag fieldsAssignedInConstructor) + { + if (operation is IBlockOperation blockOperation) + { + CollectTestContextFieldsAssignedInConstructor(testContextParameter, blockOperation.Operations, fieldsAssignedInConstructor); + } + else if (operation is IExpressionStatementOperation expressionStatementOperation) + { + operation = expressionStatementOperation.Operation; + } + + if (operation is ISimpleAssignmentOperation assignmentOperation && + assignmentOperation.Target is IMemberReferenceOperation { Member: IFieldSymbol { } candidateField } targetMemberReference && + assignmentOperation.Value is IParameterReferenceOperation parameterReference && + SymbolEqualityComparer.Default.Equals(parameterReference.Parameter, testContextParameter)) + { + fieldsAssignedInConstructor.Add(candidateField); + } + } + + private static IParameterSymbol? TryGetTestContextParameterIfValidConstructor(ISymbol candidate, INamedTypeSymbol testContextSymbol) + => candidate is IMethodSymbol { MethodKind: MethodKind.Constructor, Parameters: [{ } parameter] } && + SymbolEqualityComparer.Default.Equals(parameter.Type, testContextSymbol) + ? parameter + : null; + public override void Initialize(AnalysisContext context) { context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); @@ -90,6 +160,8 @@ public override void Initialize(AnalysisContext context) var namedType = (INamedTypeSymbol)context.Symbol; foreach (ISymbol member in namedType.GetMembers()) { + IFieldSymbol? fieldReturnedByProperty = null; + ConcurrentBag? fieldsAssignedInConstructor = null; switch (member.Kind) { case SymbolKind.Property: @@ -113,6 +185,20 @@ public override void Initialize(AnalysisContext context) { return; } + + fieldsAssignedInConstructor = new(); + + context.RegisterOperationBlockAction(context => + { + if (context.OwningSymbol.Equals(propertySymbol.GetMethod, SymbolEqualityComparer.Default)) + { + fieldReturnedByProperty = TryGetReturnedField(context.OperationBlocks); + } + else if (TryGetTestContextParameterIfValidConstructor(context.OwningSymbol, testContextSymbol) is { } parameter) + { + CollectTestContextFieldsAssignedInConstructor(parameter, context.OperationBlocks, fieldsAssignedInConstructor); + } + }); } else if (member is IFieldSymbol fieldSymbol) { @@ -145,14 +231,12 @@ public override void Initialize(AnalysisContext context) context.RegisterOperationBlockAction( context => { - if (context.OwningSymbol is not IMethodSymbol { MethodKind: MethodKind.Constructor } constructor || - constructor.Parameters.Length != 1 || - !SymbolEqualityComparer.Default.Equals(constructor.Parameters[0].Type, testContextSymbol)) + if (TryGetTestContextParameterIfValidConstructor(context.OwningSymbol, testContextSymbol) is not { } parameter) { return; } - if (AssignsParameterToMember(constructor.Parameters[0], member, context.OperationBlocks)) + if (AssignsParameterToMember(parameter, member, context.OperationBlocks)) { isAssigned = true; } @@ -161,6 +245,12 @@ public override void Initialize(AnalysisContext context) context.RegisterSymbolEndAction( context => { + if (!isAssigned) + { + isAssigned = fieldReturnedByProperty is not null && + fieldsAssignedInConstructor?.Contains(fieldReturnedByProperty, SymbolEqualityComparer.Default) == true; + } + if (!isAssigned) { context.ReportDiagnostic(member.CreateDiagnostic(TestContextShouldBeValidRule)); diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs index d3c26caea7..bba42a6e1e 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs @@ -392,6 +392,29 @@ public MyTestClass(TestContext testContext) await VerifyCS.VerifyCodeFixAsync(code, code); } + [TestMethod] + public async Task WhenTestContextPropertyIsReadonly_AssignedInConstructorViaField_NoDiagnostic() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + private readonly TestContext _testContext; + + public MyTestClass(TestContext testContext) + { + _testContext = testContext; + } + + public TestContext TestContext => _testContext; + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [DataRow("TestContext", "private")] [DataRow("TestContext", "public")] [DataRow("TestContext", "internal")] From 5e179b102958a5397176ff9f2855e25540912461 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 25 Dec 2024 08:35:05 +0100 Subject: [PATCH 178/273] Fix main build (#4446) --- .../MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs index 1b470e263b..f0d1e3a689 100644 --- a/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs @@ -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.Concurrent; using System.Collections.Immutable; using Analyzer.Utilities.Extensions; From d109b63ef1679cdb90b2dbd3f7362912e4ee85f2 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 25 Dec 2024 10:14:15 +0100 Subject: [PATCH 179/273] Fix main build (#4447) --- .../MSTest.Acceptance.IntegrationTests/AnalyzersTests.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AnalyzersTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AnalyzersTests.cs index 95f24f5b3c..43fcdcea3a 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AnalyzersTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/AnalyzersTests.cs @@ -17,6 +17,12 @@ public async Task AnalyzerMessagesShouldBeLocalized() + + true $TargetFrameworks$ true From 83f6a6304cae6657ba0397032714989405fbe933 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 26 Dec 2024 20:34:59 +1100 Subject: [PATCH 180/273] Avoid tail recursion in IsAsyncDisposeImplementation (#4432) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../IMethodSymbolExtensions.cs | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs index e308c35b21..617e8e255c 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/IMethodSymbolExtensions.cs @@ -68,20 +68,24 @@ public static bool IsDisposeImplementation([NotNullWhen(returnValue: true)] this /// public static bool IsAsyncDisposeImplementation([NotNullWhen(returnValue: true)] this IMethodSymbol? method, [NotNullWhen(returnValue: true)] INamedTypeSymbol? iAsyncDisposable, [NotNullWhen(returnValue: true)] INamedTypeSymbol? valueTaskType) { - if (method == null) + while (true) { - return false; - } + if (method == null) + { + return false; + } - if (method.IsOverride) - { - return method.OverriddenMethod.IsAsyncDisposeImplementation(iAsyncDisposable, valueTaskType); - } + if (method.IsOverride) + { + method = method.OverriddenMethod; + continue; + } - // Identify the implementor of IAsyncDisposable.Dispose in the given method's containing type and check - // if it is the given method. - return SymbolEqualityComparer.Default.Equals(method.ReturnType, valueTaskType) && - method.Parameters.IsEmpty && - method.IsImplementationOfInterfaceMethod(null, iAsyncDisposable, "DisposeAsync"); + // Identify the implementor of IAsyncDisposable.Dispose in the given method's containing type and check + // if it is the given method. + return SymbolEqualityComparer.Default.Equals(method.ReturnType, valueTaskType) && + method.Parameters.IsEmpty && + method.IsImplementationOfInterfaceMethod(null, iAsyncDisposable, "DisposeAsync"); + } } } From 40c2ae4c49fe36a8d4d7732e09c018bf85b53d51 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 26 Dec 2024 20:35:14 +1100 Subject: [PATCH 181/273] Avoid Immutable.Add (#4442) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../UseProperAssertMethodsAnalyzer.cs | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs index c82f67fc1d..cfa77db522 100644 --- a/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs @@ -297,12 +297,14 @@ private static void AnalyzeIsTrueOrIsFalseInvocation(OperationAnalysisContext co // The message is: Use 'Assert.{0}' instead of 'Assert.{1}'. string properAssertMethod = shouldUseIsNull ? "IsNull" : "IsNotNull"; + + ImmutableDictionary.Builder properties = ImmutableDictionary.CreateBuilder(); + properties.Add(ProperAssertMethodNameKey, properAssertMethod); + properties.Add(CodeFixModeKey, CodeFixModeSimple); context.ReportDiagnostic(context.Operation.CreateDiagnostic( Rule, additionalLocations: ImmutableArray.Create(conditionArgument.Syntax.GetLocation(), expressionUnderTest.GetLocation()), - properties: ImmutableDictionary.Empty - .Add(ProperAssertMethodNameKey, properAssertMethod) - .Add(CodeFixModeKey, CodeFixModeSimple), + properties: properties.ToImmutable(), properAssertMethod, isTrueInvocation ? "IsTrue" : "IsFalse")); return; @@ -323,12 +325,13 @@ private static void AnalyzeIsTrueOrIsFalseInvocation(OperationAnalysisContext co // The message is: Use 'Assert.{0}' instead of 'Assert.{1}'. string properAssertMethod = shouldUseAreEqual ? "AreEqual" : "AreNotEqual"; + ImmutableDictionary.Builder properties = ImmutableDictionary.CreateBuilder(); + properties.Add(ProperAssertMethodNameKey, properAssertMethod); + properties.Add(CodeFixModeKey, CodeFixModeAddArgument); context.ReportDiagnostic(context.Operation.CreateDiagnostic( Rule, additionalLocations: ImmutableArray.Create(conditionArgument.Syntax.GetLocation(), toBecomeExpected.GetLocation(), toBecomeActual.GetLocation()), - properties: ImmutableDictionary.Empty - .Add(ProperAssertMethodNameKey, properAssertMethod) - .Add(CodeFixModeKey, CodeFixModeAddArgument), + properties: properties.ToImmutable(), properAssertMethod, isTrueInvocation ? "IsTrue" : "IsFalse")); return; @@ -354,19 +357,19 @@ actualArgumentValue.Type is { } actualType && actualType.SpecialType != SpecialType.System_Boolean && !actualType.IsNullableOfBoolean(); - ImmutableDictionary properties = ImmutableDictionary.Empty - .Add(ProperAssertMethodNameKey, properAssertMethod) - .Add(CodeFixModeKey, CodeFixModeRemoveArgument); + ImmutableDictionary.Builder properties = ImmutableDictionary.CreateBuilder(); + properties.Add(ProperAssertMethodNameKey, properAssertMethod); + properties.Add(CodeFixModeKey, CodeFixModeRemoveArgument); if (codeFixShouldAddCast) { - properties = properties.Add(NeedsNullableBooleanCastKey, null); + properties.Add(NeedsNullableBooleanCastKey, null); } context.ReportDiagnostic(context.Operation.CreateDiagnostic( Rule, additionalLocations: ImmutableArray.Create(expectedArgument.Syntax.GetLocation(), actualArgumentValue?.Syntax.GetLocation() ?? Location.None), - properties: properties, + properties: properties.ToImmutable(), properAssertMethod, isAreEqualInvocation ? "AreEqual" : "AreNotEqual")); } @@ -379,12 +382,14 @@ actualArgumentValue.Type is { } actualType && // The message is: Use 'Assert.{0}' instead of 'Assert.{1}'. string properAssertMethod = shouldUseIsNull ? "IsNull" : "IsNotNull"; + ImmutableDictionary.Builder properties = ImmutableDictionary.CreateBuilder(); + properties.Add(ProperAssertMethodNameKey, properAssertMethod); + properties.Add(CodeFixModeKey, CodeFixModeRemoveArgument); context.ReportDiagnostic(context.Operation.CreateDiagnostic( Rule, additionalLocations: ImmutableArray.Create(expectedArgument.Syntax.GetLocation()), - properties: ImmutableDictionary.Empty - .Add(ProperAssertMethodNameKey, properAssertMethod) - .Add(CodeFixModeKey, CodeFixModeRemoveArgument), properAssertMethod, + properties: properties.ToImmutable(), + properAssertMethod, isAreEqualInvocation ? "AreEqual" : "AreNotEqual")); } } From 55c7e47048bf460b7e2285c1cd640965c83ac6f2 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 26 Dec 2024 14:15:18 +0100 Subject: [PATCH 182/273] Fix typo in analyzer message (#4452) --- src/Analyzers/MSTest.Analyzers/Resources.Designer.cs | 2 +- src/Analyzers/MSTest.Analyzers/Resources.resx | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf | 4 ++-- 15 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs index 1857d588fb..7ebb84e567 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs @@ -529,7 +529,7 @@ internal static string DynamicDataShouldBeValidMessageFormat_SourceTypeProperty } /// - /// Looks up a localized string similar to '[DynamicDta]' member '{0}.{1}' is found more than once. + /// Looks up a localized string similar to '[DynamicData]' member '{0}.{1}' is found more than once. /// internal static string DynamicDataShouldBeValidMessageFormat_TooManyMembers { get { diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx index 8f8bdb3481..064eb11cd9 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.resx +++ b/src/Analyzers/MSTest.Analyzers/Resources.resx @@ -490,7 +490,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' cannot be found - '[DynamicDta]' member '{0}.{1}' is found more than once + '[DynamicData]' member '{0}.{1}' is found more than once '[DynamicData]' member '{0}.{1}' is a property so you should use 'DynamicDataSourceType.AutoDetect' or 'DynamicDataSourceType.Property' (auto detect is the default when not specified explicitly, and is recommended) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index 36b7df5ccb..dfc1bf2837 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -378,8 +378,8 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: - '[DynamicDta]' member '{0}.{1}' is found more than once - Člen [DynamicDta] {0}.{1} byl nalezen více než jednou. + '[DynamicData]' member '{0}.{1}' is found more than once + Člen [DynamicDta] {0}.{1} byl nalezen více než jednou. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index cae9cbbd09..22dba2e28a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -379,8 +379,8 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte - '[DynamicDta]' member '{0}.{1}' is found more than once - "[DynamicDta]"-Element "{0}.{1}" wurde mehrmals gefunden. + '[DynamicData]' member '{0}.{1}' is found more than once + "[DynamicDta]"-Element "{0}.{1}" wurde mehrmals gefunden. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 8f749d02b8..ebc0dce615 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -378,8 +378,8 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: - '[DynamicDta]' member '{0}.{1}' is found more than once - El miembro '{0}.{1}' de '[DynamicData]' se encuentra más de una vez + '[DynamicData]' member '{0}.{1}' is found more than once + El miembro '{0}.{1}' de '[DynamicData]' se encuentra más de una vez diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 224d7f41e6..7ae6d2b559 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -378,8 +378,8 @@ Le type doit être une classe - '[DynamicDta]' member '{0}.{1}' is found more than once - Membre « [DynamicDta] »{0}.{1}' est trouvé plusieurs fois + '[DynamicData]' member '{0}.{1}' is found more than once + Membre « [DynamicDta] »{0}.{1}' est trouvé plusieurs fois diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index df5871d21a..e90e4c519d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -378,8 +378,8 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: - '[DynamicDta]' member '{0}.{1}' is found more than once - Il membro '[DynamicData]' '{0}.{1}' è stato trovato più di una volta + '[DynamicData]' member '{0}.{1}' is found more than once + Il membro '[DynamicData]' '{0}.{1}' è stato trovato più di una volta diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index e0b22196c5..04186874b4 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -378,8 +378,8 @@ The type declaring these methods should also respect the following rules: - '[DynamicDta]' member '{0}.{1}' is found more than once - '[DynamicDta]' メンバー '{0}.{1}' が複数回見つかりました + '[DynamicData]' member '{0}.{1}' is found more than once + '[DynamicDta]' メンバー '{0}.{1}' が複数回見つかりました diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index c7fa02f674..f6c2971da4 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -378,8 +378,8 @@ The type declaring these methods should also respect the following rules: - '[DynamicDta]' member '{0}.{1}' is found more than once - '[DynamicDta]' 멤버 '{0}.{1}'을(를) 두 번 이상 찾았습니다. + '[DynamicData]' member '{0}.{1}' is found more than once + '[DynamicDta]' 멤버 '{0}.{1}'을(를) 두 번 이상 찾았습니다. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index ee53e58591..7743699b6e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -378,8 +378,8 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu - '[DynamicDta]' member '{0}.{1}' is found more than once - Element członkowski „{0}.{1}” „[DynamicData]” został znaleziony więcej niż raz + '[DynamicData]' member '{0}.{1}' is found more than once + Element członkowski „{0}.{1}” „[DynamicData]” został znaleziony więcej niż raz diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index c4845babbe..f0109b427c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -378,8 +378,8 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: - '[DynamicDta]' member '{0}.{1}' is found more than once - O membro "{0}.{1}" de "[DynamicDta]" foi encontrado mais de uma vez + '[DynamicData]' member '{0}.{1}' is found more than once + O membro "{0}.{1}" de "[DynamicDta]" foi encontrado mais de uma vez diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index 4a189c8b80..0db90381fc 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -380,8 +380,8 @@ The type declaring these methods should also respect the following rules: - '[DynamicDta]' member '{0}.{1}' is found more than once - Элемент "[DynamicDta]" "{0}.{1}" обнаружен несколько раз + '[DynamicData]' member '{0}.{1}' is found more than once + Элемент "[DynamicDta]" "{0}.{1}" обнаружен несколько раз diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index 01aac6dd4e..650244147a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -378,8 +378,8 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: - '[DynamicDta]' member '{0}.{1}' is found more than once - '[DynamicDta]' üyesi '{0}.{1}' birden çok kez bulundu + '[DynamicData]' member '{0}.{1}' is found more than once + '[DynamicDta]' üyesi '{0}.{1}' birden çok kez bulundu diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 34e20fdb8d..1ac752005c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -378,8 +378,8 @@ The type declaring these methods should also respect the following rules: - '[DynamicDta]' member '{0}.{1}' is found more than once - 多次找到 "[DynamicDta]" 成员 "{0}.{1}" + '[DynamicData]' member '{0}.{1}' is found more than once + 多次找到 "[DynamicDta]" 成员 "{0}.{1}" diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index f42c4d2bdf..c4f0cf7de7 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -378,8 +378,8 @@ The type declaring these methods should also respect the following rules: - '[DynamicDta]' member '{0}.{1}' is found more than once - 多次發現 '[DynamicDta]' 成員 '{0}.{1}' + '[DynamicData]' member '{0}.{1}' is found more than once + 多次發現 '[DynamicDta]' 成員 '{0}.{1}' From 5d40843b2819f1d5e5d960c13f1515d422038243 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Thu, 26 Dec 2024 06:24:01 -0800 Subject: [PATCH 183/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2608429 (#4454) --- src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf | 2 +- 13 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index dfc1bf2837..c79e88f0d6 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -379,7 +379,7 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: '[DynamicData]' member '{0}.{1}' is found more than once - Člen [DynamicDta] {0}.{1} byl nalezen více než jednou. + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 22dba2e28a..7aaa0f678d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -380,7 +380,7 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte '[DynamicData]' member '{0}.{1}' is found more than once - "[DynamicDta]"-Element "{0}.{1}" wurde mehrmals gefunden. + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index ebc0dce615..6fbe5e76f5 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -379,7 +379,7 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: '[DynamicData]' member '{0}.{1}' is found more than once - El miembro '{0}.{1}' de '[DynamicData]' se encuentra más de una vez + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 7ae6d2b559..d31fd65b76 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -379,7 +379,7 @@ Le type doit être une classe '[DynamicData]' member '{0}.{1}' is found more than once - Membre « [DynamicDta] »{0}.{1}' est trouvé plusieurs fois + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index e90e4c519d..ab85a55c21 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -379,7 +379,7 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: '[DynamicData]' member '{0}.{1}' is found more than once - Il membro '[DynamicData]' '{0}.{1}' è stato trovato più di una volta + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 04186874b4..7b9f8b38db 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -379,7 +379,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicDta]' メンバー '{0}.{1}' が複数回見つかりました + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index f6c2971da4..b191882072 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -379,7 +379,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicDta]' 멤버 '{0}.{1}'을(를) 두 번 이상 찾았습니다. + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 7743699b6e..076f2f56d1 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -379,7 +379,7 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu '[DynamicData]' member '{0}.{1}' is found more than once - Element członkowski „{0}.{1}” „[DynamicData]” został znaleziony więcej niż raz + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index f0109b427c..55e17fd899 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -379,7 +379,7 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: '[DynamicData]' member '{0}.{1}' is found more than once - O membro "{0}.{1}" de "[DynamicDta]" foi encontrado mais de uma vez + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index 0db90381fc..ee59f488cf 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -381,7 +381,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is found more than once - Элемент "[DynamicDta]" "{0}.{1}" обнаружен несколько раз + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index 650244147a..3791c4e8ad 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -379,7 +379,7 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicDta]' üyesi '{0}.{1}' birden çok kez bulundu + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 1ac752005c..ad6f1bbac2 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -379,7 +379,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is found more than once - 多次找到 "[DynamicDta]" 成员 "{0}.{1}" + '[DynamicData]' member '{0}.{1}' is found more than once diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index c4f0cf7de7..954e70c12b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -379,7 +379,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is found more than once - 多次發現 '[DynamicDta]' 成員 '{0}.{1}' + '[DynamicData]' member '{0}.{1}' is found more than once From c0b675c7ae038591dda6a0689ba6b00560d85662 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 26 Dec 2024 16:26:18 +0100 Subject: [PATCH 184/273] Rename runSettingXml into runSettingsXml (#4451) --- .../Utilities/CLITestBase.discovery.cs | 4 +- .../DesktopTestSourceHostTests.cs | 14 +- .../Services/DesktopTestSourceHostTests.cs | 12 +- .../Services/MSTestSettingsProviderTests.cs | 8 +- .../Services/TestDeploymentTests.cs | 20 +- .../Helpers/UnitTestOutcomeHelperTests.cs | 4 +- .../MSTestExecutorTests.cs | 24 +-- .../MSTestSettingsTests.cs | 204 +++++++++--------- .../RunConfigurationSettingsTests.cs | 16 +- .../Automation.CLI/CLITestBase.common.cs | 11 +- .../Automation.CLI/CLITestBase.e2e.cs | 8 +- 11 files changed, 160 insertions(+), 165 deletions(-) diff --git a/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs b/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs index a3b9b49872..05665bf625 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs @@ -25,8 +25,8 @@ internal ImmutableArray DiscoverTests(string assemblyPath, string test var logger = new InternalLogger(); var sink = new InternalSink(); - string runSettingXml = GetRunSettingXml(string.Empty); - var context = new InternalDiscoveryContext(runSettingXml, testCaseFilter); + string runSettingsXml = GetRunSettingsXml(string.Empty); + var context = new InternalDiscoveryContext(runSettingsXml, testCaseFilter); unitTestDiscoverer.DiscoverTestsInSource(assemblyPath, logger, sink, context); diff --git a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs index 6421f15162..6544bb12c0 100644 --- a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs +++ b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs @@ -21,7 +21,7 @@ public class DesktopTestSourceHostTests : TestContainer public void ParentDomainShouldHonorSearchDirectoriesSpecifiedInRunsettings() { string sampleProjectDirPath = Path.GetDirectoryName(GetTestAssemblyPath("SampleProjectForAssemblyResolution")); - string runSettingXml = + string runSettingsXml = $""" @@ -39,7 +39,7 @@ public void ParentDomainShouldHonorSearchDirectoriesSpecifiedInRunsettings() _testSourceHost = new TestSourceHost( GetTestAssemblyPath("DesktopTestProjectx86Debug"), - GetMockedIRunSettings(runSettingXml).Object, + GetMockedIRunSettings(runSettingsXml).Object, null); _testSourceHost.SetupHost(); @@ -52,7 +52,7 @@ public void ChildDomainResolutionPathsShouldHaveSearchDirectoriesSpecifiedInRuns { string sampleProjectPath = GetTestAssemblyPath("SampleProjectForAssemblyResolution"); string sampleProjectDirPath = Path.GetDirectoryName(sampleProjectPath); - string runSettingXml = + string runSettingsXml = $""" @@ -70,7 +70,7 @@ public void ChildDomainResolutionPathsShouldHaveSearchDirectoriesSpecifiedInRuns _testSourceHost = new TestSourceHost( GetTestAssemblyPath("DesktopTestProjectx86Debug"), - GetMockedIRunSettings(runSettingXml).Object, + GetMockedIRunSettings(runSettingsXml).Object, null); _testSourceHost.SetupHost(); @@ -127,12 +127,12 @@ private static string GetTestAssemblyPath(string assetName) return testAssetPath; } - private static Mock GetMockedIRunSettings(string runSettingXml) + private static Mock GetMockedIRunSettings(string runSettingsXml) { var mockRunSettings = new Mock(); - mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingXml); + mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); - StringReader stringReader = new(runSettingXml); + StringReader stringReader = new(runSettingsXml); var reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); MSTestSettingsProvider mstestSettingsProvider = new(); reader.ReadToFollowing("MSTestV2"); diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs index 278cdfde1f..32463c805f 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/DesktopTestSourceHostTests.cs @@ -123,7 +123,7 @@ public void SetupHostShouldHaveParentDomainsAppBaseSetToTestSourceLocation() { // Arrange DummyClass dummyClass = new(); - string runSettingxml = + string runSettingsXml = """ @@ -134,7 +134,7 @@ public void SetupHostShouldHaveParentDomainsAppBaseSetToTestSourceLocation() string location = typeof(TestSourceHost).Assembly.Location; var mockRunSettings = new Mock(); - mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); TestSourceHost sourceHost = new(location, mockRunSettings.Object, null); @@ -197,7 +197,7 @@ public void NoAppDomainShouldGetCreatedWhenDisableAppDomainIsSetToTrue() { // Arrange DummyClass dummyClass = new(); - string runSettingxml = + string runSettingsXml = @" True @@ -206,7 +206,7 @@ public void NoAppDomainShouldGetCreatedWhenDisableAppDomainIsSetToTrue() string location = typeof(TestSourceHost).Assembly.Location; var mockRunSettings = new Mock(); - mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); Mock testSourceHost = new(location, mockRunSettings.Object, null) { CallBase = true }; @@ -226,7 +226,7 @@ public void AppDomainShouldGetCreatedWhenDisableAppDomainIsSetToFalse() { // Arrange DummyClass dummyClass = new(); - string runSettingxml = + string runSettingsXml = """ @@ -237,7 +237,7 @@ public void AppDomainShouldGetCreatedWhenDisableAppDomainIsSetToFalse() string location = typeof(TestSourceHost).Assembly.Location; var mockRunSettings = new Mock(); - mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); Mock testSourceHost = new(location, mockRunSettings.Object, null) { CallBase = true }; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestSettingsProviderTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestSettingsProviderTests.cs index b7257bdea3..44397350b5 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestSettingsProviderTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestSettingsProviderTests.cs @@ -40,13 +40,13 @@ public void SettingsShouldReturnDefaultSettingsIfNotInitialized() public void SettingsShouldReturnInitializedSettings() { - string runSettingxml = + string runSettingsXml = """ False """; - StringReader stringReader = new(runSettingxml); + StringReader stringReader = new(runSettingsXml); var reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); reader.Read(); _settingsProvider.Load(reader); @@ -58,13 +58,13 @@ public void LoadShouldThrowIfReaderIsNull() => public void LoadShouldReadAndFillInSettings() { - string runSettingxml = + string runSettingsXml = """ False """; - StringReader stringReader = new(runSettingxml); + StringReader stringReader = new(runSettingsXml); var reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); reader.Read(); _settingsProvider.Load(reader); diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestDeploymentTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestDeploymentTests.cs index cba32d6214..5615c73684 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestDeploymentTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/TestDeploymentTests.cs @@ -106,9 +106,9 @@ public void CleanupShouldNotDeleteDirectoriesIfRunDirectoriesIsNull() public void CleanupShouldNotDeleteDirectoriesIfRunSettingsSpecifiesSo() { - string runSettingXml = + string runSettingsXml = "False"; - StringReader stringReader = new(runSettingXml); + StringReader stringReader = new(runSettingsXml); var reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); MSTestSettingsProvider mstestSettingsProvider = new(); mstestSettingsProvider.Load(reader); @@ -188,9 +188,9 @@ public void DeployShouldReturnFalseWhenDeploymentEnabledSetToFalseButHasDeployme new DeploymentUtility(), _mockFileUtility.Object); - string runSettingXml = + string runSettingsXml = "False"; - StringReader stringReader = new(runSettingXml); + StringReader stringReader = new(runSettingsXml); var reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); MSTestSettingsProvider mstestSettingsProvider = new(); mstestSettingsProvider.Load(reader); @@ -211,9 +211,9 @@ public void DeployShouldReturnFalseWhenDeploymentEnabledSetToFalseAndHasNoDeploy new DeploymentUtility(), _mockFileUtility.Object); - string runSettingXml = + string runSettingsXml = "False"; - StringReader stringReader = new(runSettingXml); + StringReader stringReader = new(runSettingsXml); var reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); MSTestSettingsProvider mstestSettingsProvider = new(); mstestSettingsProvider.Load(reader); @@ -234,9 +234,9 @@ public void DeployShouldReturnFalseWhenDeploymentEnabledSetToTrueButHasNoDeploym new DeploymentUtility(), _mockFileUtility.Object); - string runSettingXml = + string runSettingsXml = "True"; - StringReader stringReader = new(runSettingXml); + StringReader stringReader = new(runSettingsXml); var reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); MSTestSettingsProvider mstestSettingsProvider = new(); mstestSettingsProvider.Load(reader); @@ -264,9 +264,9 @@ internal void DeployShouldReturnTrueWhenDeploymentEnabledSetToTrueAndHasDeployme new DeploymentUtility(), _mockFileUtility.Object); - string runSettingXml = + string runSettingsXml = "True"; - StringReader stringReader = new(runSettingXml); + StringReader stringReader = new(runSettingsXml); var reader = XmlReader.Create(stringReader, XmlRunSettingsUtilities.ReaderSettings); MSTestSettingsProvider mstestSettingsProvider = new(); mstestSettingsProvider.Load(reader); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/UnitTestOutcomeHelperTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/UnitTestOutcomeHelperTests.cs index 7be7fa6d9a..6c4ff49376 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/UnitTestOutcomeHelperTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/UnitTestOutcomeHelperTests.cs @@ -19,7 +19,7 @@ public class UnitTestOutcomeHelperTests : TestContainer public UnitTestOutcomeHelperTests() { - string runSettingxml = + string runSettingsXml = """ @@ -27,7 +27,7 @@ public UnitTestOutcomeHelperTests() """; var mockMessageLogger = new Mock(); - _adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, mockMessageLogger.Object); + _adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, mockMessageLogger.Object); } public void UniTestHelperToTestOutcomeForUnitTestOutcomePassedShouldReturnTestOutcomePassed() diff --git a/test/UnitTests/MSTestAdapter.UnitTests/MSTestExecutorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/MSTestExecutorTests.cs index 2d5d5b8d4c..68628e0119 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/MSTestExecutorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/MSTestExecutorTests.cs @@ -41,7 +41,7 @@ public void RunTestsShouldNotExecuteTestsIfTestSettingsIsGiven() { var testCase = new TestCase("DummyName", new Uri("executor://MSTestAdapter/v2"), Assembly.GetExecutingAssembly().Location); TestCase[] tests = [testCase]; - string runSettingxml = + string runSettingsXml = """ @@ -52,7 +52,7 @@ public void RunTestsShouldNotExecuteTestsIfTestSettingsIsGiven() """; _mockRunContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); _mstestExecutor.RunTests(tests, _mockRunContext.Object, _mockFrameworkHandle.Object); // Test should not start if TestSettings is given. @@ -63,7 +63,7 @@ public void RunTestsShouldReportErrorAndBailOutOnSettingsException() { var testCase = new TestCase("DummyName", new Uri("executor://MSTestAdapter/v2"), Assembly.GetExecutingAssembly().Location); TestCase[] tests = [testCase]; - string runSettingxml = + string runSettingsXml = """ @@ -74,7 +74,7 @@ public void RunTestsShouldReportErrorAndBailOutOnSettingsException() """; _mockRunContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); // Act. _mstestExecutor.RunTests(tests, _mockRunContext.Object, _mockFrameworkHandle.Object); @@ -87,7 +87,7 @@ public void RunTestsShouldReportErrorAndBailOutOnSettingsException() public void RunTestsWithSourcesShouldNotExecuteTestsIfTestSettingsIsGiven() { var sources = new List { Assembly.GetExecutingAssembly().Location }; - string runSettingxml = + string runSettingsXml = """ @@ -98,7 +98,7 @@ public void RunTestsWithSourcesShouldNotExecuteTestsIfTestSettingsIsGiven() """; _mockRunContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); _mstestExecutor.RunTests(sources, _mockRunContext.Object, _mockFrameworkHandle.Object); // Test should not start if TestSettings is given. @@ -108,7 +108,7 @@ public void RunTestsWithSourcesShouldNotExecuteTestsIfTestSettingsIsGiven() public void RunTestsWithSourcesShouldReportErrorAndBailOutOnSettingsException() { var sources = new List { Assembly.GetExecutingAssembly().Location }; - string runSettingxml = + string runSettingsXml = """ @@ -119,7 +119,7 @@ public void RunTestsWithSourcesShouldReportErrorAndBailOutOnSettingsException() """; _mockRunContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); // Act. _mstestExecutor.RunTests(sources, _mockRunContext.Object, _mockFrameworkHandle.Object); @@ -132,13 +132,13 @@ public void RunTestsWithSourcesShouldReportErrorAndBailOutOnSettingsException() public void RunTestsWithSourcesShouldSetDefaultCollectSourceInformationAsTrue() { var sources = new List { Assembly.GetExecutingAssembly().Location }; - string runSettingxml = + string runSettingsXml = """ """; _mockRunContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); _mstestExecutor.RunTests(sources, _mockRunContext.Object, _mockFrameworkHandle.Object); Verify(MSTestSettings.RunConfigurationSettings.CollectSourceInformation); @@ -147,7 +147,7 @@ public void RunTestsWithSourcesShouldSetDefaultCollectSourceInformationAsTrue() public void RunTestsWithSourcesShouldSetCollectSourceInformationAsFalseIfSpecifiedInRunSettings() { var sources = new List { Assembly.GetExecutingAssembly().Location }; - string runSettingxml = + string runSettingsXml = """ @@ -156,7 +156,7 @@ public void RunTestsWithSourcesShouldSetCollectSourceInformationAsFalseIfSpecifi """; _mockRunContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); _mstestExecutor.RunTests(sources, _mockRunContext.Object, _mockFrameworkHandle.Object); Verify(!MSTestSettings.RunConfigurationSettings.CollectSourceInformation); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs index 16a33f2e27..5a9d24f439 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs @@ -46,7 +46,7 @@ protected override void Dispose(bool disposing) public void MapInconclusiveToFailedIsByDefaultFalseWhenNotSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -54,14 +54,14 @@ public void MapInconclusiveToFailedIsByDefaultFalseWhenNotSpecified() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(!adapterSettings.MapInconclusiveToFailed); } public void MapNotRunnableToFailedIsByDefaultTrueWhenNotSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -69,14 +69,14 @@ public void MapNotRunnableToFailedIsByDefaultTrueWhenNotSpecified() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.MapNotRunnableToFailed); } public void MapInconclusiveToFailedShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -85,14 +85,14 @@ public void MapInconclusiveToFailedShouldBeConsumedFromRunSettingsWhenSpecified( """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.MapInconclusiveToFailed); } public void RunSettings_WithInvalidValues_GettingAWarningForEachInvalidSetting() { - string runSettingxml = + string runSettingsXml = """ @@ -118,7 +118,7 @@ public void RunSettings_WithInvalidValues_GettingAWarningForEachInvalidSetting() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); _mockMessageLogger.Verify(lm => lm.SendMessage(TestMessageLevel.Warning, It.IsAny()), Times.Exactly(18)); _mockMessageLogger.Verify(lm => lm.SendMessage(TestMessageLevel.Warning, "Invalid value '3' for runsettings entry 'CooperativeCancellationTimeout', setting will be ignored."), Times.Once); @@ -143,7 +143,7 @@ public void RunSettings_WithInvalidValues_GettingAWarningForEachInvalidSetting() public void MapNotRunnableToFailedShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -152,14 +152,14 @@ public void MapNotRunnableToFailedShouldBeConsumedFromRunSettingsWhenSpecified() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.MapNotRunnableToFailed); } public void ForcedLegacyModeIsByDefaultFalseWhenNotSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -167,14 +167,14 @@ public void ForcedLegacyModeIsByDefaultFalseWhenNotSpecified() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsName, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object); Verify(!adapterSettings.ForcedLegacyMode); } public void ForcedLegacyModeShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -183,14 +183,14 @@ public void ForcedLegacyModeShouldBeConsumedFromRunSettingsWhenSpecified() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsName, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object); Verify(adapterSettings.ForcedLegacyMode); } public void TestSettingsFileIsByDefaultNullWhenNotSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -198,14 +198,14 @@ public void TestSettingsFileIsByDefaultNullWhenNotSpecified() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsName, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object); Verify(adapterSettings.TestSettingsFile is null); } public void TestSettingsFileShouldNotBeNullWhenSpecifiedInRunSettings() { - string runSettingxml = + string runSettingsXml = """ @@ -214,14 +214,14 @@ public void TestSettingsFileShouldNotBeNullWhenSpecifiedInRunSettings() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsName, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object); Verify(adapterSettings.TestSettingsFile is not null); } public void EnableBaseClassTestMethodsFromOtherAssembliesIsByDefaulTrueWhenNotSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -229,14 +229,14 @@ public void EnableBaseClassTestMethodsFromOtherAssembliesIsByDefaulTrueWhenNotSp """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.EnableBaseClassTestMethodsFromOtherAssemblies); } public void EnableBaseClassTestMethodsFromOtherAssembliesShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -245,14 +245,14 @@ public void EnableBaseClassTestMethodsFromOtherAssembliesShouldBeConsumedFromRun """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.EnableBaseClassTestMethodsFromOtherAssemblies); } public void CaptureDebugTracesShouldBeTrueByDefault() { - string runSettingxml = + string runSettingsXml = """ @@ -260,14 +260,14 @@ public void CaptureDebugTracesShouldBeTrueByDefault() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.CaptureDebugTraces); } public void CaptureDebugTracesShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -276,14 +276,14 @@ public void CaptureDebugTracesShouldBeConsumedFromRunSettingsWhenSpecified() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(!adapterSettings.CaptureDebugTraces); } public void TestTimeoutShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -292,14 +292,14 @@ public void TestTimeoutShouldBeConsumedFromRunSettingsWhenSpecified() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.TestTimeout == 4000); } public void TestTimeoutShouldBeSetToZeroIfNotSpecifiedInRunSettings() { - string runSettingxml = + string runSettingsXml = """ @@ -307,14 +307,14 @@ public void TestTimeoutShouldBeSetToZeroIfNotSpecifiedInRunSettings() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.TestTimeout == 0); } public void TreatClassCleanupWarningsAsErrorsShouldBeFalseByDefault() { - string runSettingxml = + string runSettingsXml = """ @@ -322,14 +322,14 @@ public void TreatClassCleanupWarningsAsErrorsShouldBeFalseByDefault() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(!adapterSettings.TreatClassAndAssemblyCleanupWarningsAsErrors); } public void TreatClassCleanupWarningsAsErrorsShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -338,14 +338,14 @@ public void TreatClassCleanupWarningsAsErrorsShouldBeConsumedFromRunSettingsWhen """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.TreatClassAndAssemblyCleanupWarningsAsErrors); } public void TreatDiscoveryWarningsAsErrorsShouldBeFalseByDefault() { - string runSettingxml = + string runSettingsXml = """ @@ -353,14 +353,14 @@ public void TreatDiscoveryWarningsAsErrorsShouldBeFalseByDefault() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(!adapterSettings.TreatDiscoveryWarningsAsErrors); } public void TreatDiscoveryWarningsAsErrorsShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -369,14 +369,14 @@ public void TreatDiscoveryWarningsAsErrorsShouldBeConsumedFromRunSettingsWhenSpe """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.TreatDiscoveryWarningsAsErrors); } public void ParallelizationSettingsShouldNotBeSetByDefault() { - string runSettingxml = + string runSettingsXml = """ @@ -384,7 +384,7 @@ public void ParallelizationSettingsShouldNotBeSetByDefault() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(!adapterSettings.ParallelizationWorkers.HasValue); Verify(!adapterSettings.ParallelizationScope.HasValue); @@ -392,7 +392,7 @@ public void ParallelizationSettingsShouldNotBeSetByDefault() public void GetSettingsShouldThrowIfParallelizationWorkersIsNotInt() { - string runSettingxml = + string runSettingsXml = """ @@ -403,14 +403,14 @@ public void GetSettingsShouldThrowIfParallelizationWorkersIsNotInt() """; - AdapterSettingsException exception = VerifyThrows(() => MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object)); + AdapterSettingsException exception = VerifyThrows(() => MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object)); Verify(exception.Message.Contains("Invalid value 'GoneFishing' specified for 'Workers'. The value should be a non-negative integer.")); } public void GetSettingsShouldThrowIfParallelizationWorkersIsNegative() { - string runSettingxml = + string runSettingsXml = """ @@ -421,13 +421,13 @@ public void GetSettingsShouldThrowIfParallelizationWorkersIsNegative() """; - AdapterSettingsException exception = VerifyThrows(() => MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object)); + AdapterSettingsException exception = VerifyThrows(() => MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object)); Verify(exception.Message.Contains("Invalid value '-1' specified for 'Workers'. The value should be a non-negative integer.")); } public void ParallelizationWorkersShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -438,14 +438,14 @@ public void ParallelizationWorkersShouldBeConsumedFromRunSettingsWhenSpecified() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.ParallelizationWorkers == 2); } public void ParallelizationWorkersShouldBeSetToProcessorCountWhenSetToZero() { - string runSettingxml = + string runSettingsXml = """ @@ -456,14 +456,14 @@ public void ParallelizationWorkersShouldBeSetToProcessorCountWhenSetToZero() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(Environment.ProcessorCount == adapterSettings.ParallelizationWorkers); } public void ParallelizationSettingsShouldBeSetToDefaultsWhenNotSet() { - string runSettingxml = + string runSettingsXml = """ @@ -473,7 +473,7 @@ public void ParallelizationSettingsShouldBeSetToDefaultsWhenNotSet() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(Environment.ProcessorCount == adapterSettings.ParallelizationWorkers); Verify(adapterSettings.ParallelizationScope == UTF.ExecutionScope.ClassLevel); @@ -481,7 +481,7 @@ public void ParallelizationSettingsShouldBeSetToDefaultsWhenNotSet() public void ParallelizationSettingsShouldBeSetToDefaultsOnAnEmptyParalleizeSetting() { - string runSettingxml = + string runSettingsXml = """ @@ -490,7 +490,7 @@ public void ParallelizationSettingsShouldBeSetToDefaultsOnAnEmptyParalleizeSetti """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(Environment.ProcessorCount == adapterSettings.ParallelizationWorkers); Verify(adapterSettings.ParallelizationScope == UTF.ExecutionScope.ClassLevel); @@ -498,7 +498,7 @@ public void ParallelizationSettingsShouldBeSetToDefaultsOnAnEmptyParalleizeSetti public void ParallelizationSettingsShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -510,7 +510,7 @@ public void ParallelizationSettingsShouldBeConsumedFromRunSettingsWhenSpecified( """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.ParallelizationWorkers == 127); Verify(adapterSettings.ParallelizationScope == UTF.ExecutionScope.MethodLevel); @@ -518,7 +518,7 @@ public void ParallelizationSettingsShouldBeConsumedFromRunSettingsWhenSpecified( public void GetSettingsShouldThrowIfParallelizationScopeIsNotValid() { - string runSettingxml = + string runSettingsXml = """ @@ -529,13 +529,13 @@ public void GetSettingsShouldThrowIfParallelizationScopeIsNotValid() """; - AdapterSettingsException exception = VerifyThrows(() => MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object)); + AdapterSettingsException exception = VerifyThrows(() => MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object)); Verify(exception.Message.Contains("Invalid value 'JustParallelizeWillYou' specified for 'Scope'. Supported scopes are ClassLevel, MethodLevel.")); } public void ParallelizationScopeShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -546,14 +546,14 @@ public void ParallelizationScopeShouldBeConsumedFromRunSettingsWhenSpecified() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.ParallelizationScope == UTF.ExecutionScope.MethodLevel); } public void GetSettingsShouldThrowWhenParallelizeHasInvalidElements() { - string runSettingxml = + string runSettingsXml = """ @@ -564,13 +564,13 @@ public void GetSettingsShouldThrowWhenParallelizeHasInvalidElements() """; - AdapterSettingsException exception = VerifyThrows(() => MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object)); + AdapterSettingsException exception = VerifyThrows(() => MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object)); Verify(exception.Message.Contains("Invalid settings 'Parallelize'. Unexpected XmlElement: 'Hola'.")); } public void GetSettingsShouldBeAbleToReadAfterParallelizationSettings() { - string runSettingxml = + string runSettingsXml = """ @@ -581,14 +581,14 @@ public void GetSettingsShouldBeAbleToReadAfterParallelizationSettings() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.TestSettingsFile is not null); } public void GetSettingsShouldBeAbleToReadAfterParallelizationSettingsWithData() { - string runSettingxml = + string runSettingsXml = """ @@ -601,7 +601,7 @@ public void GetSettingsShouldBeAbleToReadAfterParallelizationSettingsWithData() """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.TestSettingsFile is not null); Verify(adapterSettings.ParallelizationWorkers == 127); @@ -610,7 +610,7 @@ public void GetSettingsShouldBeAbleToReadAfterParallelizationSettingsWithData() public void GetSettingsShouldBeAbleToReadAfterParallelizationSettingsOnEmptyParallelizationNode() { - string runSettingxml = + string runSettingsXml = """ @@ -620,21 +620,21 @@ public void GetSettingsShouldBeAbleToReadAfterParallelizationSettingsOnEmptyPara """; - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.TestSettingsFile is not null); } public void DisableParallelizationShouldBeFalseByDefault() { - string runSettingxml = + string runSettingsXml = """ """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); Verify(!MSTestSettings.CurrentSettings.DisableParallelization); @@ -643,7 +643,7 @@ public void DisableParallelizationShouldBeFalseByDefault() public void DisableParallelizationShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -653,7 +653,7 @@ public void DisableParallelizationShouldBeConsumedFromRunSettingsWhenSpecified() """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); Verify(MSTestSettings.CurrentSettings.DisableParallelization); @@ -661,7 +661,7 @@ public void DisableParallelizationShouldBeConsumedFromRunSettingsWhenSpecified() public void DisableParallelization_WithInvalidValue_GettingAWarning() { - string runSettingxml = + string runSettingsXml = """ @@ -671,7 +671,7 @@ public void DisableParallelization_WithInvalidValue_GettingAWarning() """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); _mockMessageLogger.Verify(lm => lm.SendMessage(TestMessageLevel.Warning, "Invalid value '3' for runsettings entry 'DisableParallelization', setting will be ignored."), Times.Once); } @@ -682,7 +682,7 @@ public void DisableParallelization_WithInvalidValue_GettingAWarning() public void GetSettingsShouldProbePlatformSpecificSettingsAlso() { - string runSettingxml = + string runSettingsXml = """ @@ -701,13 +701,13 @@ public void GetSettingsShouldProbePlatformSpecificSettingsAlso() } }); - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsName, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object); _testablePlatformServiceProvider.MockSettingsProvider.Verify(sp => sp.Load(It.IsAny()), Times.Once); } public void GetSettingsShouldOnlyPassTheElementSubTreeToPlatformService() { - string runSettingxml = + string runSettingsXml = """ @@ -730,13 +730,13 @@ public void GetSettingsShouldOnlyPassTheElementSubTreeToPlatformService() } }); - MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsName, _mockMessageLogger.Object); + MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object); Verify(expectedrunSettingxml == observedxml); } public void GetSettingsShouldBeAbleToReadSettingsAfterThePlatformServiceReadsItsSettings() { - string runSettingxml = + string runSettingsXml = """ @@ -780,7 +780,7 @@ public void GetSettingsShouldBeAbleToReadSettingsAfterThePlatformServiceReadsIts } }); - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsName, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object); // Assert. Verify(dummyPlatformSpecificSetting); @@ -791,7 +791,7 @@ public void GetSettingsShouldBeAbleToReadSettingsAfterThePlatformServiceReadsIts public void GetSettingsShouldBeAbleToReadSettingsIfThePlatformServiceDoesNotUnderstandASetting() { - string runSettingxml = + string runSettingsXml = """ @@ -838,7 +838,7 @@ public void GetSettingsShouldBeAbleToReadSettingsIfThePlatformServiceDoesNotUnde } }); - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsName, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object); // Assert. Verify(dummyPlatformSpecificSetting); @@ -851,7 +851,7 @@ public void GetSettingsShouldBeAbleToReadSettingsIfThePlatformServiceDoesNotUnde public void GetSettingsShouldOnlyReadTheAdapterSection() { - string runSettingxml = + string runSettingsXml = """ @@ -892,7 +892,7 @@ public void GetSettingsShouldOnlyReadTheAdapterSection() } }); - MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsName, _mockMessageLogger.Object); + MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object); // Assert. Verify(!outOfScopeCall); @@ -900,7 +900,7 @@ public void GetSettingsShouldOnlyReadTheAdapterSection() public void GetSettingsShouldWorkIfThereAreCommentsInTheXML() { - string runSettingxml = + string runSettingsXml = """ @@ -950,7 +950,7 @@ public void GetSettingsShouldWorkIfThereAreCommentsInTheXML() } }); - var adapterSettings = MSTestSettings.GetSettings(runSettingxml, MSTestSettings.SettingsName, _mockMessageLogger.Object); + var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsName, _mockMessageLogger.Object); // Assert. Verify(dummyPlatformSpecificSetting); @@ -977,7 +977,7 @@ public void CurrentSettingShouldReturnDefaultSettingsIfNotSet() public void CurrentSettingShouldReturnCachedLoadedSettings() { - string runSettingxml = + string runSettingsXml = """ @@ -987,7 +987,7 @@ public void CurrentSettingShouldReturnCachedLoadedSettings() """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); MSTestSettings adapterSettings = MSTestSettings.CurrentSettings; @@ -1072,7 +1072,7 @@ public void PopulateSettingsShouldInitializeDefaultSettingsWhenRunSettingsXmlIsE public void PopulateSettingsShouldInitializeSettingsToDefaultIfNotSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -1082,7 +1082,7 @@ public void PopulateSettingsShouldInitializeSettingsToDefaultIfNotSpecified() """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); MSTestSettings adapterSettings = MSTestSettings.CurrentSettings; @@ -1095,7 +1095,7 @@ public void PopulateSettingsShouldInitializeSettingsToDefaultIfNotSpecified() public void PopulateSettingsShouldInitializeSettingsFromMSTestSection() { - string runSettingxml = + string runSettingsXml = """ @@ -1109,7 +1109,7 @@ public void PopulateSettingsShouldInitializeSettingsFromMSTestSection() """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); MSTestSettings adapterSettings = MSTestSettings.CurrentSettings; @@ -1125,7 +1125,7 @@ public void PopulateSettingsShouldInitializeSettingsFromMSTestSection() public void PopulateSettingsShouldInitializeSettingsFromMSTestV2Section() { - string runSettingxml = + string runSettingsXml = """ @@ -1139,7 +1139,7 @@ public void PopulateSettingsShouldInitializeSettingsFromMSTestV2Section() """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); MSTestSettings adapterSettings = MSTestSettings.CurrentSettings; @@ -1155,7 +1155,7 @@ public void PopulateSettingsShouldInitializeSettingsFromMSTestV2Section() public void PopulateSettingsShouldInitializeSettingsFromMSTestV2OverMSTestV1Section() { - string runSettingxml = + string runSettingsXml = """ @@ -1172,7 +1172,7 @@ public void PopulateSettingsShouldInitializeSettingsFromMSTestV2OverMSTestV1Sect """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); MSTestSettings adapterSettings = MSTestSettings.CurrentSettings; @@ -1199,7 +1199,7 @@ public void IsLegacyScenarioReturnsFalseWhenDiscoveryContextIsNull() public void IsLegacyScenarioReturnsFalseWhenForcedLegacyModeIsSetToFalse() { - string runSettingxml = + string runSettingsXml = """ @@ -1209,14 +1209,14 @@ public void IsLegacyScenarioReturnsFalseWhenForcedLegacyModeIsSetToFalse() """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); Verify(!MSTestSettings.IsLegacyScenario(_mockMessageLogger.Object)); } public void IsLegacyScenarioReturnsFalseWhenForcedLegacyModeIsSetToTrue() { - string runSettingxml = + string runSettingsXml = """ @@ -1225,14 +1225,14 @@ public void IsLegacyScenarioReturnsFalseWhenForcedLegacyModeIsSetToTrue() """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); Verify(!MSTestSettings.IsLegacyScenario(_mockMessageLogger.Object)); } public void IsLegacyScenarioReturnsTrueWhenTestSettingsFileIsGiven() { - string runSettingxml = + string runSettingsXml = """ @@ -1241,14 +1241,14 @@ public void IsLegacyScenarioReturnsTrueWhenTestSettingsFileIsGiven() """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); Verify(MSTestSettings.IsLegacyScenario(_mockMessageLogger.Object)); } public void LegacyScenariosNotSupportedWarningIsPrintedWhenVsmdiFileIsGiven() { - string runSettingxml = + string runSettingsXml = """ @@ -1257,7 +1257,7 @@ public void LegacyScenariosNotSupportedWarningIsPrintedWhenVsmdiFileIsGiven() """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); Verify(MSTestSettings.IsLegacyScenario(_mockMessageLogger.Object)); _mockMessageLogger.Verify(logger => logger.SendMessage(TestMessageLevel.Warning, Resource.LegacyScenariosNotSupportedWarning), Times.Once); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/RunConfigurationSettingsTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/RunConfigurationSettingsTests.cs index 355ee93e9d..ada116e3a0 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/RunConfigurationSettingsTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/RunConfigurationSettingsTests.cs @@ -42,7 +42,7 @@ protected override void Dispose(bool disposing) public void CollectSourceInformationIsByDefaultTrueWhenNotSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -50,13 +50,13 @@ public void CollectSourceInformationIsByDefaultTrueWhenNotSpecified() """; - var configurationSettings = RunConfigurationSettings.GetSettings(runSettingxml, RunConfigurationSettings.SettingsName); + var configurationSettings = RunConfigurationSettings.GetSettings(runSettingsXml, RunConfigurationSettings.SettingsName); Verify(configurationSettings.CollectSourceInformation); } public void CollectSourceInformationShouldBeConsumedFromRunSettingsWhenSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -67,7 +67,7 @@ public void CollectSourceInformationShouldBeConsumedFromRunSettingsWhenSpecified """; - var configurationSettings = RunConfigurationSettings.GetSettings(runSettingxml, RunConfigurationSettings.SettingsName); + var configurationSettings = RunConfigurationSettings.GetSettings(runSettingsXml, RunConfigurationSettings.SettingsName); Verify(!configurationSettings.CollectSourceInformation); } @@ -117,7 +117,7 @@ public void PopulateSettingsShouldInitializeDefaultSettingsWhenRunSettingsXmlIsE public void PopulateSettingsShouldInitializeSettingsToDefaultIfNotSpecified() { - string runSettingxml = + string runSettingsXml = """ @@ -127,7 +127,7 @@ public void PopulateSettingsShouldInitializeSettingsToDefaultIfNotSpecified() """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); RunConfigurationSettings settings = MSTestSettings.RunConfigurationSettings; @@ -139,7 +139,7 @@ public void PopulateSettingsShouldInitializeSettingsToDefaultIfNotSpecified() public void PopulateSettingsShouldInitializeSettingsFromRunConfigurationSection() { - string runSettingxml = + string runSettingsXml = """ @@ -150,7 +150,7 @@ public void PopulateSettingsShouldInitializeSettingsFromRunConfigurationSection( """; _mockDiscoveryContext.Setup(dc => dc.RunSettings).Returns(_mockRunSettings.Object); - _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingxml); + _mockRunSettings.Setup(rs => rs.SettingsXml).Returns(runSettingsXml); MSTestSettings.PopulateSettings(_mockDiscoveryContext.Object, _mockMessageLogger.Object, null); RunConfigurationSettings settings = MSTestSettings.RunConfigurationSettings; diff --git a/test/Utilities/Automation.CLI/CLITestBase.common.cs b/test/Utilities/Automation.CLI/CLITestBase.common.cs index 6f307a30c4..68aa8a4f1c 100644 --- a/test/Utilities/Automation.CLI/CLITestBase.common.cs +++ b/test/Utilities/Automation.CLI/CLITestBase.common.cs @@ -16,10 +16,8 @@ public partial class CLITestBase : TestContainer "Release"; #endif -#pragma warning disable IDE0051 // Remove unused private members - private const string TestPlatformCLIPackageName = "Microsoft.TestPlatform"; -#pragma warning restore IDE0051 // Remove unused private members private const string DefaultTargetFramework = "net462"; + internal const string TestPlatformCLIPackageName = "Microsoft.TestPlatform"; protected static XmlDocument ReadCPMFile() { @@ -76,13 +74,10 @@ protected static string GetAssetFullPath(string assetName, string configuration } /// - /// Gets the RunSettingXml having testadapterpath filled in specified by argument. - /// Inserts testAdapterPath in existing runSetting if not present already, + /// Gets the RunSettingXml with the TestAdapterPath inserted, /// or generates new runSettings with testAdapterPath if runSettings is Empty. /// - /// RunSettings provided for discovery/execution. - /// RunSettingXml as string. - protected static string GetRunSettingXml(string settingsXml) + protected static string GetRunSettingsXml(string settingsXml) { if (string.IsNullOrEmpty(settingsXml)) { diff --git a/test/Utilities/Automation.CLI/CLITestBase.e2e.cs b/test/Utilities/Automation.CLI/CLITestBase.e2e.cs index e6cf592d12..edb40bb821 100644 --- a/test/Utilities/Automation.CLI/CLITestBase.e2e.cs +++ b/test/Utilities/Automation.CLI/CLITestBase.e2e.cs @@ -33,9 +33,9 @@ public void InvokeVsTestForDiscovery(string[] sources, string runSettings = "", ExpandTestSourcePaths(sources, targetFramework); _discoveryEventsHandler = new DiscoveryEventsHandler(); - string runSettingXml = GetRunSettingXml(runSettings); + string runSettingsXml = GetRunSettingsXml(runSettings); - s_vsTestConsoleWrapper.DiscoverTests(sources, runSettingXml, _discoveryEventsHandler); + s_vsTestConsoleWrapper.DiscoverTests(sources, runSettingsXml, _discoveryEventsHandler); } /// @@ -49,9 +49,9 @@ public void InvokeVsTestForExecution(string[] sources, string runSettings = "", ExpandTestSourcePaths(sources, targetFramework); RunEventsHandler = new RunEventsHandler(); - string runSettingXml = GetRunSettingXml(runSettings); + string runSettingsXml = GetRunSettingsXml(runSettings); - s_vsTestConsoleWrapper.RunTests(sources, runSettingXml, new TestPlatformOptions { TestCaseFilter = testCaseFilter }, RunEventsHandler); + s_vsTestConsoleWrapper.RunTests(sources, runSettingsXml, new TestPlatformOptions { TestCaseFilter = testCaseFilter }, RunEventsHandler); if (RunEventsHandler.Errors.Count != 0) { throw new Exception($"Run failed with {RunEventsHandler.Errors.Count} errors:{Environment.NewLine}{string.Join(Environment.NewLine, RunEventsHandler.Errors)}"); From 06eb7e4dce9f4603c5a05877e86318e23484da71 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 27 Dec 2024 02:46:35 +1100 Subject: [PATCH 185/273] remove some redundant qualifiers (#4435) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../Execution/ExceptionHelper.cs | 2 +- .../Helpers/DataSerializationHelper.cs | 2 +- .../MSTest.TestAdapter/Helpers/FixtureKind.cs | 2 +- .../PlatformServiceProvider.cs | 4 +- .../MSTestBannerCapability.cs | 2 +- .../VSTestAdapter/MSTestDiscoverer.cs | 4 +- .../AssemblyResolver.cs | 8 +- .../Deployment/AssemblyLoadWorker.cs | 4 +- .../Services/ReflectionOperations2.cs | 2 +- .../Services/ThreadOperations.cs | 2 +- .../Utilities/DeploymentUtility.cs | 2 +- .../Utilities/VSInstallationUtilities.cs | 2 +- .../CrashDumpEnvironmentVariableProvider.cs | 2 +- ...JsonConfigurationFileParser.netstandard.cs | 6 +- .../Hosts/TestHostBuilder.cs | 22 +++--- .../OutputDevice/Terminal/NativeMethods.cs | 2 +- .../MSBuildTests.Test.cs | 2 +- .../Utilities/AppDomainUtilitiesTests.cs | 2 +- .../TestAssemblySettingsProviderTests.cs | 6 +- .../Execution/TestMethodRunnerTests.cs | 75 +++++++++---------- .../MSTestSettingsTests.cs | 12 ++- .../TestablePlatformServiceProvider.cs | 2 +- .../Assertions/AssertTests.cs | 2 +- .../Automation.CLI/CLITestBase.common.cs | 4 +- 24 files changed, 85 insertions(+), 88 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs b/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs index 90acd6cd0b..0c36b4e56f 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/ExceptionHelper.cs @@ -136,7 +136,7 @@ internal static string TrimStackTrace(string stackTrace) /// /// The aggregated exception message that considers inner exceptions. /// - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] internal static string GetFormattedExceptionMessage(this Exception ex) { DebugEx.Assert(ex != null, "exception should not be null."); diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/DataSerializationHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/DataSerializationHelper.cs index 4f1a9253fe..efafabaa74 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/DataSerializationHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/DataSerializationHelper.cs @@ -12,7 +12,7 @@ internal static class DataSerializationHelper { UseSimpleDictionaryFormat = true, EmitTypeInformation = System.Runtime.Serialization.EmitTypeInformation.Always, - DateTimeFormat = new System.Runtime.Serialization.DateTimeFormat("O", System.Globalization.CultureInfo.InvariantCulture), + DateTimeFormat = new System.Runtime.Serialization.DateTimeFormat("O", CultureInfo.InvariantCulture), }; /// diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/FixtureKind.cs b/src/Adapter/MSTest.TestAdapter/Helpers/FixtureKind.cs index c472b72d4b..7258055724 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/FixtureKind.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/FixtureKind.cs @@ -3,7 +3,7 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; -[System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1602:Enumeration items should be documented", Justification = "Internal and self-explanatory")] +[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1602:Enumeration items should be documented", Justification = "Internal and self-explanatory")] internal enum FixtureKind { AssemblyInitialize, diff --git a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs index 6bb7a3348f..90c8134b8c 100644 --- a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs @@ -27,11 +27,11 @@ private PlatformServiceProvider() => #if !WINDOWS_UWP // Set the provider that is used by DynamicDataAttribute when generating data, to allow substituting functionality // in TestFramework without having to put all the stuff in that library. - TestTools.UnitTesting.DynamicDataProvider.Instance = SourceGeneratorToggle.UseSourceGenerator + UTF.DynamicDataProvider.Instance = SourceGeneratorToggle.UseSourceGenerator ? new SourceGeneratedDynamicDataOperations() : new DynamicDataOperations(); #else - TestTools.UnitTesting.DynamicDataProvider.Instance = new DynamicDataOperations(); + UTF.DynamicDataProvider.Instance = new DynamicDataOperations(); #endif /// diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs index 22f3d64a18..46693dd8c3 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs @@ -28,7 +28,7 @@ internal sealed class MSTestBannerCapability : IBannerMessageOwnerCapability } #if NETCOREAPP - if (System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeCompiled) + if (RuntimeFeature.IsDynamicCodeCompiled) #endif { bannerMessage.Append(" ["); diff --git a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs index c61b73aaa3..1ba0d68d3f 100644 --- a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs +++ b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs @@ -33,8 +33,8 @@ public class MSTestDiscoverer : ITestDiscoverer /// Logger used to log messages. /// Used to send testcases and discovery related events back to Discoverer manager. [System.Security.SecurityCritical] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Discovery context can be null.")] - public void DiscoverTests(IEnumerable sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) => MSTestDiscoverer.DiscoverTests(sources, discoveryContext, logger, discoverySink, null); + [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods", MessageId = "0", Justification = "Discovery context can be null.")] + public void DiscoverTests(IEnumerable sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) => DiscoverTests(sources, discoveryContext, logger, discoverySink, null); internal static void DiscoverTests(IEnumerable sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink, IConfiguration? configuration) { diff --git a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs index 2d1a1946f2..8695ba0484 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/AssemblyResolver.cs @@ -483,8 +483,8 @@ private void WindowsRuntimeMetadataReflectionOnlyNamespaceResolve(object sender, /// The args. /// Indicates whether this is called under a Reflection Only Load context. /// The . - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "senderAppDomain", Justification = "This is an event handler.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "senderAppDomain", Justification = "This is an event handler.")] #pragma warning disable IDE0060 // Remove unused parameter private Assembly? OnResolveInternal(object? senderAppDomain, ResolveEventArgs args, bool isReflectionOnly) #pragma warning restore IDE0060 // Remove unused parameter @@ -686,8 +686,8 @@ private static void SafeLog(string? assemblyName, Action loggerAction) /// The requested Name. /// Indicates whether this is called under a Reflection Only Load context. /// The . - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Justification = "The assembly location is figured out from the configuration that the user passes in.")] - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] + [SuppressMessage("Microsoft.Reliability", "CA2001:AvoidCallingProblematicMethods", MessageId = "System.Reflection.Assembly.LoadFrom", Justification = "The assembly location is figured out from the configuration that the user passes in.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] private Assembly? SearchAndLoadAssembly(string assemblyPath, string assemblyName, AssemblyName requestedName, bool isReflectionOnly) { try diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs index 1d3850dec8..848a7bc96d 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Deployment/AssemblyLoadWorker.cs @@ -36,7 +36,7 @@ public AssemblyLoadWorker() /// Path to the assembly file to load from. /// The warnings. /// Full path to dependent assemblies. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] public IReadOnlyCollection GetFullPathToDependentAssemblies(string assemblyPath, out IList warnings) { DebugEx.Assert(!StringEx.IsNullOrEmpty(assemblyPath), "assemblyPath"); @@ -217,7 +217,7 @@ private void ProcessChildren(Assembly assembly, IList result, ISet The result. /// The visited Assemblies. /// The warnings. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] private void GetDependentAssembliesInternal(string assemblyString, IList result, ISet visitedAssemblies, IList warnings) { DebugEx.Assert(!StringEx.IsNullOrEmpty(assemblyString), "assemblyString"); diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs index cf7597438f..acce42de99 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs @@ -13,7 +13,7 @@ internal sealed class ReflectionOperations2 : ReflectionOperations, IReflectionO public ReflectionOperations2() { #if NET8_0_OR_GREATER - if (!System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported) + if (!RuntimeFeature.IsDynamicCodeSupported) { throw new NotSupportedException("ReflectionOperations2 are not allowed when dynamic code is not supported, use NativeReflectionOperations instead"); } diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs index 06f5b3a7ef..d4c8b4ee1b 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs @@ -55,7 +55,7 @@ private static bool ExecuteWithThreadPool(Action action, int timeout, Cancellati } #endif - [System.Runtime.Versioning.SupportedOSPlatform("windows")] + [SupportedOSPlatform("windows")] private static bool ExecuteWithCustomThread(Action action, int timeout, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs index e64336180e..af43490bde 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentUtility.cs @@ -99,7 +99,7 @@ protected override void AddDependenciesOfDeploymentItem(string deploymentItemFil } #if NETFRAMEWORK - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] public void ProcessNewStorage(string testSource, IList deploymentItems, IList warnings) { // Add deployment items and process .config files only for storages we have not processed before. diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs index 2e6ee4baaf..87f29d19a1 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/VSInstallationUtilities.cs @@ -37,7 +37,7 @@ public static class VSInstallationUtilities /// Gets the visual studio installation path on the local machine. /// /// VS install path. - [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Need to ignore failures to read the registry settings")] + [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Need to ignore failures to read the registry settings")] public static string? VSInstallPath { get diff --git a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs index 47dbe3465e..95c11353cc 100644 --- a/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.CrashDump/CrashDumpEnvironmentVariableProvider.cs @@ -201,7 +201,7 @@ public Task ValidateTestHostEnvironmentVariablesAsync(IReadOnl static void AddError(StringBuilder errors, string variableName, string? expectedValue, string? actualValue) { string actualValueString = actualValue ?? ""; - errors.AppendLine(string.Format(System.Globalization.CultureInfo.InvariantCulture, CrashDumpResources.CrashDumpInvalidEnvironmentVariableValueErrorMessage, variableName, expectedValue, actualValueString)); + errors.AppendLine(string.Format(CultureInfo.InvariantCulture, CrashDumpResources.CrashDumpInvalidEnvironmentVariableValueErrorMessage, variableName, expectedValue, actualValueString)); } #endif } diff --git a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.netstandard.cs b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.netstandard.cs index 3d21acc89f..338c563b07 100644 --- a/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.netstandard.cs +++ b/src/Platform/Microsoft.Testing.Platform/Configurations/JsonConfigurationFileParser.netstandard.cs @@ -31,7 +31,7 @@ public static (Dictionary SingleValueData, Dictionary SingleValueData, Dictionary PropertyToAllChildren) ParseStream(Stream input) { using StreamReader reader = new(input); - var doc = (JsonObject)Jsonite.Json.Deserialize(reader.ReadToEnd(), _settings); + var doc = (JsonObject)Json.Deserialize(reader.ReadToEnd(), _settings); if (doc is not null) { VisitObjectElement(doc); @@ -64,7 +64,7 @@ private void SavePropertyToAllChildren(object? property) throw new FormatException(string.Format(CultureInfo.InvariantCulture, PlatformResources.JsonConfigurationFileParserDuplicateKeyErrorMessage, key)); } - _propertyToAllChildren[key] = Jsonite.Json.Serialize(property, _settings); + _propertyToAllChildren[key] = Json.Serialize(property, _settings); } private void VisitArrayElement(JsonArray array) @@ -114,7 +114,7 @@ private void VisitValue(object? value) // Adapt to the System.Text.Json serialization outcome _singleValueData[key] = value is bool boolean ? CultureInfo.InvariantCulture.TextInfo.ToTitleCase(boolean.ToString()) - : value is string stringValue ? stringValue.Trim('\"') : Jsonite.Json.Serialize(value, _settings); + : value is string stringValue ? stringValue.Trim('\"') : Json.Serialize(value, _settings); break; } diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs index 06c93611dc..ca36e2af56 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs @@ -503,7 +503,7 @@ await LogTestHostCreatedAsync( } // Build the test host - ConsoleTestHost consoleHost = TestHostBuilder.CreateConsoleTestHost( + ConsoleTestHost consoleHost = CreateConsoleTestHost( serviceProvider, BuildTestFrameworkAsync, (TestFrameworkManager)TestFramework, @@ -648,10 +648,10 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD // creations and we could lose interesting diagnostic information. List dataConsumersBuilder = []; - await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.PlatformOutputDisplayService, serviceProvider, dataConsumersBuilder); - await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionRequestFactory, serviceProvider, dataConsumersBuilder); - await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionRequestInvoker, serviceProvider, dataConsumersBuilder); - await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionFilterFactory, serviceProvider, dataConsumersBuilder); + await RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.PlatformOutputDisplayService, serviceProvider, dataConsumersBuilder); + await RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionRequestFactory, serviceProvider, dataConsumersBuilder); + await RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionRequestInvoker, serviceProvider, dataConsumersBuilder); + await RegisterAsServiceOrConsumerOrBothAsync(testFrameworkBuilderData.TestExecutionFilterFactory, serviceProvider, dataConsumersBuilder); // Create the test framework adapter ITestFrameworkCapabilities testFrameworkCapabilities = serviceProvider.GetTestFrameworkCapabilities(); @@ -661,7 +661,7 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD serviceProvider.AllowTestAdapterFrameworkRegistration = true; try { - await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(new TestFrameworkProxy(testFramework), serviceProvider, dataConsumersBuilder); + await RegisterAsServiceOrConsumerOrBothAsync(new TestFrameworkProxy(testFramework), serviceProvider, dataConsumersBuilder); } finally { @@ -687,11 +687,11 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD { if (testhostExtension.Extension is IDataConsumer) { - await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testhostExtension.Extension, serviceProvider, dataConsumersBuilder); + await RegisterAsServiceOrConsumerOrBothAsync(testhostExtension.Extension, serviceProvider, dataConsumersBuilder); } else { - await TestHostBuilder.AddServiceIfNotSkippedAsync(testhostExtension.Extension, serviceProvider); + await AddServiceIfNotSkippedAsync(testhostExtension.Extension, serviceProvider); } } } @@ -705,7 +705,7 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD testSessionLifetimeHandlers.Add(handler); } - await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(consumerService, serviceProvider, dataConsumersBuilder); + await RegisterAsServiceOrConsumerOrBothAsync(consumerService, serviceProvider, dataConsumersBuilder); } // Register the test session lifetime handlers container @@ -721,7 +721,7 @@ private async Task BuildTestFrameworkAsync(TestFrameworkBuilderD // Allow the ITestApplicationProcessExitCode to subscribe as IDataConsumer ITestApplicationProcessExitCode testApplicationResult = serviceProvider.GetRequiredService(); - await TestHostBuilder.RegisterAsServiceOrConsumerOrBothAsync(testApplicationResult, serviceProvider, dataConsumersBuilder); + await RegisterAsServiceOrConsumerOrBothAsync(testApplicationResult, serviceProvider, dataConsumersBuilder); // We register the data consumer handler if we're connected to the dotnet test pipe if (pushOnlyProtocolDataConsumer is not null) @@ -817,7 +817,7 @@ private static async Task RegisterAsServiceOrConsumerOrBothAsync(object service, return; } - await TestHostBuilder.AddServiceIfNotSkippedAsync(service, serviceProvider); + await AddServiceIfNotSkippedAsync(service, serviceProvider); } private async Task DisplayBannerIfEnabledAsync(ApplicationLoggingState loggingState, ProxyOutputDevice outputDevice, diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NativeMethods.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NativeMethods.cs index 42935d3710..e887cbc622 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NativeMethods.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NativeMethods.cs @@ -27,7 +27,7 @@ internal static bool IsWindows internal static (bool AcceptAnsiColorCodes, bool OutputIsScreen, uint? OriginalConsoleMode) QueryIsScreenAndTryEnableAnsiColorCodes(StreamHandleType handleType = StreamHandleType.StdOut) { - if (System.Console.IsOutputRedirected) + if (Console.IsOutputRedirected) { // There's no ANSI terminal support if console output is redirected. return (AcceptAnsiColorCodes: false, OutputIsScreen: false, OriginalConsoleMode: null); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs index e403fdfbe4..fe1344af45 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs @@ -9,7 +9,7 @@ public class MSBuildTests_Test : AcceptanceTestBase private const string AssetName = "MSBuildTests"; public static string? FormatBuildMatrixEntry(MethodInfo method, object?[]? data) - => $"{data![0]},{(string.Equals(TargetFrameworks.All.ToMSBuildTargetFrameworks(), data[1]) ? "multitfm" : data[1])},{data[2]},{((bool)data[3]! ? "Succeeded" : "Failed")}"; + => $"{data![0]},{(Equals(TargetFrameworks.All.ToMSBuildTargetFrameworks(), data[1]) ? "multitfm" : data[1])},{data[2]},{((bool)data[3]! ? "Succeeded" : "Failed")}"; internal static IEnumerable<(string BuildCommand, string TargetFramework, BuildConfiguration BuildConfiguration, bool TestSucceeded)> GetBuildMatrix() { diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/AppDomainUtilitiesTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/AppDomainUtilitiesTests.cs index 1f91b2374a..20414f8607 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/AppDomainUtilitiesTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Utilities/AppDomainUtilitiesTests.cs @@ -51,7 +51,7 @@ public void SetConfigurationFileShouldSetOMRedirectionIfConfigFileIsPresent() """; byte[] observedConfigBytes = setup.GetConfigurationBytes(); - string observedXml = System.Text.Encoding.UTF8.GetString(observedConfigBytes); + string observedXml = Encoding.UTF8.GetString(observedConfigBytes); Verify(SanitizeString(observedXml).Contains(SanitizeString(expectedRedir)), "Config must have OM redirection"); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblySettingsProviderTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblySettingsProviderTests.cs index 854ebb489c..95afcb4469 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblySettingsProviderTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestAssemblySettingsProviderTests.cs @@ -99,7 +99,7 @@ public void GetSettingsShouldSetParallelScopeToClassLevelByDefault() MSTest.TestAdapter.ObjectModel.TestAssemblySettings settings = TestAssemblySettingsProvider.GetSettings("Foo"); // Assert. - Verify(settings.Scope == UTF.ExecutionScope.ClassLevel); + Verify(settings.Scope == ExecutionScope.ClassLevel); } public void GetSettingsShouldSetParallelScope() @@ -112,13 +112,13 @@ public void GetSettingsShouldSetParallelScope() _testablePlatformServiceProvider .MockReflectionOperations .Setup(ro => ro.GetCustomAttributes(It.IsAny(), typeof(UTF.ParallelizeAttribute))) - .Returns([new UTF.ParallelizeAttribute { Scope = UTF.ExecutionScope.MethodLevel }]); + .Returns([new UTF.ParallelizeAttribute { Scope = ExecutionScope.MethodLevel }]); // Act. MSTest.TestAdapter.ObjectModel.TestAssemblySettings settings = TestAssemblySettingsProvider.GetSettings("Foo"); // Assert. - Verify(settings.Scope == UTF.ExecutionScope.MethodLevel); + Verify(settings.Scope == ExecutionScope.MethodLevel); } public void GetSettingsShouldSetCanParallelizeAssemblyToTrueByDefault() diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs index ff5fb70d82..d5c4fe1939 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs @@ -15,7 +15,6 @@ using AdapterTestOutcome = Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestOutcome; using UTF = Microsoft.VisualStudio.TestTools.UnitTesting; -using UTFExtension = Microsoft.VisualStudio.TestTools.UnitTesting; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution; @@ -23,7 +22,7 @@ public class TestMethodRunnerTests : TestContainer { private readonly MethodInfo _methodInfo; - private readonly UTF.TestMethodAttribute _testMethodAttribute; + private readonly TestMethodAttribute _testMethodAttribute; private readonly TestContextImplementation _testContextImplementation; @@ -38,7 +37,7 @@ public class TestMethodRunnerTests : TestContainer public TestMethodRunnerTests() { _methodInfo = typeof(DummyTestClass).GetMethods().Single(m => m.Name.Equals("DummyTestMethod", StringComparison.Ordinal)); - _testMethodAttribute = new UTF.TestMethodAttribute(); + _testMethodAttribute = new TestMethodAttribute(); _testMethod = new TestMethod("dummyTestName", "dummyClassName", "dummyAssemblyName", false); _testContextImplementation = new TestContextImplementation(_testMethod, new ThreadSafeStringWriter(null, "test"), new Dictionary()); @@ -65,7 +64,7 @@ private static TestClassInfo GetTestClassInfo() { ConstructorInfo constructorInfo = typeof(T).GetConstructor([])!; PropertyInfo testContextProperty = typeof(T).GetProperty("TestContext"); - var classAttribute = new UTF.TestClassAttribute(); + var classAttribute = new TestClassAttribute(); var testAssemblyInfo = new TestAssemblyInfo(typeof(T).Assembly); return new TestClassInfo(typeof(T), constructorInfo, isParameterlessConstructor: true, testContextProperty, classAttribute, testAssemblyInfo); } @@ -91,7 +90,7 @@ public void ExecuteForTestThrowingExceptionShouldReturnUnitTestResultWithFailedO public void ExecuteForPassingTestShouldReturnUnitTestResultWithPassedOutcome() { - var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new UTF.TestResult() { Outcome = UTF.UnitTestOutcome.Passed }); + var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new TestResult() { Outcome = UTF.UnitTestOutcome.Passed }); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); UnitTestResult[] results = testMethodRunner.Execute(string.Empty, string.Empty, string.Empty, string.Empty); @@ -100,7 +99,7 @@ public void ExecuteForPassingTestShouldReturnUnitTestResultWithPassedOutcome() public void ExecuteShouldNotFillInDebugAndTraceLogsIfDebugTraceDisabled() { - var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new UTF.TestResult() { Outcome = UTF.UnitTestOutcome.Passed }); + var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new TestResult() { Outcome = UTF.UnitTestOutcome.Passed }); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); StringWriter writer = new(new StringBuilder("DummyTrace")); @@ -120,7 +119,7 @@ public void ExecuteShouldNotFillInDebugAndTraceLogsFromRunningTestMethod() () => { writer.Write("InTestMethod"); - return new UTF.TestResult() + return new TestResult() { Outcome = UTF.UnitTestOutcome.Passed, }; @@ -145,11 +144,11 @@ public void RunTestMethodForTestThrowingExceptionShouldReturnUnitTestResultWithF public void RunTestMethodForMultipleResultsReturnMultipleResults() { - var testMethodAttributeMock = new Mock(); - testMethodAttributeMock.Setup(_ => _.Execute(It.IsAny())).Returns( + var testMethodAttributeMock = new Mock(); + testMethodAttributeMock.Setup(_ => _.Execute(It.IsAny())).Returns( [ - new UTF.TestResult { Outcome = UTF.UnitTestOutcome.Passed }, - new UTF.TestResult { Outcome = UTF.UnitTestOutcome.Failed }, + new TestResult { Outcome = UTF.UnitTestOutcome.Passed }, + new TestResult { Outcome = UTF.UnitTestOutcome.Failed }, ]); var localTestMethodOptions = new TestMethodOptions(TimeoutInfo.FromTimeout(200), null, _testContextImplementation, false, testMethodAttributeMock.Object); @@ -166,7 +165,7 @@ public void RunTestMethodForMultipleResultsReturnMultipleResults() public void RunTestMethodForPassingTestThrowingExceptionShouldReturnUnitTestResultWithPassedOutcome() { - var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new UTF.TestResult() { Outcome = UTF.UnitTestOutcome.Passed }); + var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new TestResult() { Outcome = UTF.UnitTestOutcome.Passed }); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); UnitTestResult[] results = testMethodRunner.Execute(string.Empty, string.Empty, string.Empty, string.Empty); @@ -175,7 +174,7 @@ public void RunTestMethodForPassingTestThrowingExceptionShouldReturnUnitTestResu public void RunTestMethodForFailingTestThrowingExceptionShouldReturnUnitTestResultWithFailedOutcome() { - var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new UTF.TestResult() { Outcome = UTF.UnitTestOutcome.Failed }); + var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new TestResult() { Outcome = UTF.UnitTestOutcome.Failed }); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); UnitTestResult[] results = testMethodRunner.Execute(string.Empty, string.Empty, string.Empty, string.Empty); @@ -184,7 +183,7 @@ public void RunTestMethodForFailingTestThrowingExceptionShouldReturnUnitTestResu public void RunTestMethodShouldGiveTestResultAsPassedWhenTestMethodPasses() { - var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new UTF.TestResult() { Outcome = UTF.UnitTestOutcome.Passed }); + var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new TestResult() { Outcome = UTF.UnitTestOutcome.Passed }); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); UnitTestResult[] results = testMethodRunner.RunTestMethod(); @@ -195,7 +194,7 @@ public void RunTestMethodShouldGiveTestResultAsPassedWhenTestMethodPasses() public void RunTestMethodShouldGiveTestResultAsFailedWhenTestMethodFails() { - var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new UTF.TestResult() { Outcome = UTF.UnitTestOutcome.Failed }); + var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new TestResult() { Outcome = UTF.UnitTestOutcome.Failed }); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); UnitTestResult[] results = testMethodRunner.RunTestMethod(); @@ -206,10 +205,10 @@ public void RunTestMethodShouldGiveTestResultAsFailedWhenTestMethodFails() public void RunTestMethodShouldRunDataDrivenTestsWhenDataIsProvidedUsingDataSourceAttribute() { - var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new UTF.TestResult() { Outcome = UTF.UnitTestOutcome.Passed }); + var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new TestResult() { Outcome = UTF.UnitTestOutcome.Passed }); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); - UTF.DataSourceAttribute dataSourceAttribute = new("DummyConnectionString", "DummyTableName"); + DataSourceAttribute dataSourceAttribute = new("DummyConnectionString", "DummyTableName"); var attributes = new Attribute[] { dataSourceAttribute }; @@ -229,7 +228,7 @@ public void RunTestMethodShouldRunDataDrivenTestsWhenDataIsProvidedUsingDataSour public void RunTestMethodShouldRunDataDrivenTestsWhenDataIsProvidedUsingDataRowAttribute() { - UTF.TestResult testResult = new() + TestResult testResult = new() { Outcome = UTF.UnitTestOutcome.Inconclusive, }; @@ -239,7 +238,7 @@ public void RunTestMethodShouldRunDataDrivenTestsWhenDataIsProvidedUsingDataRowA int dummyIntData = 2; string dummyStringData = "DummyString"; - UTF.DataRowAttribute dataRowAttribute = new( + DataRowAttribute dataRowAttribute = new( dummyIntData, dummyStringData); @@ -257,7 +256,7 @@ public void RunTestMethodShouldSetDataRowIndexForDataDrivenTestsWhenDataIsProvid var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new UTF.TestResult()); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); - UTF.DataSourceAttribute dataSourceAttribute = new("DummyConnectionString", "DummyTableName"); + DataSourceAttribute dataSourceAttribute = new("DummyConnectionString", "DummyTableName"); var attributes = new Attribute[] { dataSourceAttribute }; @@ -278,10 +277,10 @@ public void RunTestMethodShouldRunOnlyDataSourceTestsWhenBothDataSourceAndDataRo var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => new UTF.TestResult()); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); - UTF.DataSourceAttribute dataSourceAttribute = new("DummyConnectionString", "DummyTableName"); + DataSourceAttribute dataSourceAttribute = new("DummyConnectionString", "DummyTableName"); int dummyIntData = 2; string dummyStringData = "DummyString"; - UTF.DataRowAttribute dataRowAttribute = new( + DataRowAttribute dataRowAttribute = new( dummyIntData, dummyStringData); @@ -301,13 +300,13 @@ public void RunTestMethodShouldRunOnlyDataSourceTestsWhenBothDataSourceAndDataRo public void RunTestMethodShouldFillInDisplayNameWithDataRowDisplayNameIfProvidedForDataDrivenTests() { - UTF.TestResult testResult = new(); + TestResult testResult = new(); var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => testResult); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); int dummyIntData = 2; string dummyStringData = "DummyString"; - UTF.DataRowAttribute dataRowAttribute = new(dummyIntData, dummyStringData) + DataRowAttribute dataRowAttribute = new(dummyIntData, dummyStringData) { DisplayName = "DataRowTestDisplayName", }; @@ -325,13 +324,13 @@ public void RunTestMethodShouldFillInDisplayNameWithDataRowDisplayNameIfProvided public void RunTestMethodShouldFillInDisplayNameWithDataRowArgumentsIfNoDisplayNameIsProvidedForDataDrivenTests() { - UTF.TestResult testResult = new(); + TestResult testResult = new(); var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions, () => testResult); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); int dummyIntData = 2; string dummyStringData = "DummyString"; - UTF.DataRowAttribute dataRowAttribute = new( + DataRowAttribute dataRowAttribute = new( dummyIntData, dummyStringData); @@ -348,7 +347,7 @@ public void RunTestMethodShouldFillInDisplayNameWithDataRowArgumentsIfNoDisplayN public void RunTestMethodShouldSetResultFilesIfPresentForDataDrivenTests() { - UTF.TestResult testResult = new() + TestResult testResult = new() { ResultFiles = new List() { "C:\\temp.txt" }, }; @@ -358,8 +357,8 @@ public void RunTestMethodShouldSetResultFilesIfPresentForDataDrivenTests() int dummyIntData1 = 1; int dummyIntData2 = 2; - UTF.DataRowAttribute dataRowAttribute1 = new(dummyIntData1); - UTF.DataRowAttribute dataRowAttribute2 = new(dummyIntData2); + DataRowAttribute dataRowAttribute1 = new(dummyIntData1); + DataRowAttribute dataRowAttribute2 = new(dummyIntData2); var attributes = new Attribute[] { dataRowAttribute1, dataRowAttribute2 }; @@ -424,7 +423,7 @@ private void RunTestMethodWithEmptyDataSourceShouldFailIfConsiderEmptyDataSource #region Test data [SuppressMessage("CodeQuality", "IDE0051:Remove unused private members", Justification = "Use through reflection")] - private static void InitMethodThrowingException(UTFExtension.TestContext tc) + private static void InitMethodThrowingException(TestContext tc) // TODO: Fix exception type #pragma warning disable CA2208 // Instantiate argument exceptions correctly => throw new ArgumentException(); @@ -432,12 +431,12 @@ private static void InitMethodThrowingException(UTFExtension.TestContext tc) public class TestableTestMethodInfo : TestMethodInfo { - private readonly Func _invokeTest; + private readonly Func _invokeTest; internal TestableTestMethodInfo(MethodInfo testMethod, TestClassInfo parent, TestMethodOptions testMethodOptions, Func invoke) : base(testMethod, parent, testMethodOptions) => _invokeTest = invoke; - public override UTF.TestResult Invoke(object[] arguments) => + public override TestResult Invoke(object[] arguments) => // Ignore args for now _invokeTest(); } @@ -465,20 +464,20 @@ public class DummyTestClass : DummyTestClassBase public static Func DummyAsyncTestMethodBody { get; set; } - public static Action AssemblyInitializeMethodBody { get; set; } + public static Action AssemblyInitializeMethodBody { get; set; } - public static Action ClassInitializeMethodBody { get; set; } + public static Action ClassInitializeMethodBody { get; set; } - public UTFExtension.TestContext TestContext + public TestContext TestContext { get => throw new NotImplementedException(); set => TestContextSetterBody(value); } - public static void DummyAssemblyInit(UTFExtension.TestContext tc) => AssemblyInitializeMethodBody(tc); + public static void DummyAssemblyInit(TestContext tc) => AssemblyInitializeMethodBody(tc); - public static void DummyClassInit(UTFExtension.TestContext tc) => ClassInitializeMethodBody(tc); + public static void DummyClassInit(TestContext tc) => ClassInitializeMethodBody(tc); public void DummyTestInitializeMethod() => TestInitializeMethodBody(this); @@ -500,7 +499,7 @@ public DummyTestClassWithParameterizedCtor(int x) public class DummyTestClassWithTestContextWithoutSetter { - public UTFExtension.TestContext TestContext { get; } + public TestContext TestContext { get; } } public class DummyTestClassEmptyDataSource diff --git a/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs index 5a9d24f439..fa447f29a2 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs @@ -13,8 +13,6 @@ using TestFramework.ForTestingMSTest; -using UTF = Microsoft.VisualStudio.TestTools.UnitTesting; - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests; public class MSTestSettingsTests : TestContainer @@ -476,7 +474,7 @@ public void ParallelizationSettingsShouldBeSetToDefaultsWhenNotSet() var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(Environment.ProcessorCount == adapterSettings.ParallelizationWorkers); - Verify(adapterSettings.ParallelizationScope == UTF.ExecutionScope.ClassLevel); + Verify(adapterSettings.ParallelizationScope == ExecutionScope.ClassLevel); } public void ParallelizationSettingsShouldBeSetToDefaultsOnAnEmptyParalleizeSetting() @@ -493,7 +491,7 @@ public void ParallelizationSettingsShouldBeSetToDefaultsOnAnEmptyParalleizeSetti var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(Environment.ProcessorCount == adapterSettings.ParallelizationWorkers); - Verify(adapterSettings.ParallelizationScope == UTF.ExecutionScope.ClassLevel); + Verify(adapterSettings.ParallelizationScope == ExecutionScope.ClassLevel); } public void ParallelizationSettingsShouldBeConsumedFromRunSettingsWhenSpecified() @@ -513,7 +511,7 @@ public void ParallelizationSettingsShouldBeConsumedFromRunSettingsWhenSpecified( var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); Verify(adapterSettings.ParallelizationWorkers == 127); - Verify(adapterSettings.ParallelizationScope == UTF.ExecutionScope.MethodLevel); + Verify(adapterSettings.ParallelizationScope == ExecutionScope.MethodLevel); } public void GetSettingsShouldThrowIfParallelizationScopeIsNotValid() @@ -548,7 +546,7 @@ public void ParallelizationScopeShouldBeConsumedFromRunSettingsWhenSpecified() var adapterSettings = MSTestSettings.GetSettings(runSettingsXml, MSTestSettings.SettingsNameAlias, _mockMessageLogger.Object); - Verify(adapterSettings.ParallelizationScope == UTF.ExecutionScope.MethodLevel); + Verify(adapterSettings.ParallelizationScope == ExecutionScope.MethodLevel); } public void GetSettingsShouldThrowWhenParallelizeHasInvalidElements() @@ -605,7 +603,7 @@ public void GetSettingsShouldBeAbleToReadAfterParallelizationSettingsWithData() Verify(adapterSettings.TestSettingsFile is not null); Verify(adapterSettings.ParallelizationWorkers == 127); - Verify(adapterSettings.ParallelizationScope == UTF.ExecutionScope.MethodLevel); + Verify(adapterSettings.ParallelizationScope == ExecutionScope.MethodLevel); } public void GetSettingsShouldBeAbleToReadAfterParallelizationSettingsOnEmptyParallelizationNode() diff --git a/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs b/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs index 80dae5ce83..f00c1b7411 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs @@ -27,7 +27,7 @@ public TestablePlatformServiceProvider() MockTraceListener = new Mock(); MockTraceListenerManager = new Mock(); MockThreadOperations = new Mock(); - TestTools.UnitTesting.DynamicDataProvider.Instance = SourceGeneratorToggle.UseSourceGenerator + UTF.DynamicDataProvider.Instance = SourceGeneratorToggle.UseSourceGenerator ? new SourceGeneratedDynamicDataOperations() : new DynamicDataOperations(); } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs index 4d1f5a12c3..8b3584fc46 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs @@ -10,7 +10,7 @@ public partial class AssertTests #region That tests public void ThatShouldReturnAnInstanceOfAssert() => Verify(Assert.That is not null); - public void ThatShouldCacheAssertInstance() => Verify(object.ReferenceEquals(Assert.That, Assert.That)); + public void ThatShouldCacheAssertInstance() => Verify(ReferenceEquals(Assert.That, Assert.That)); #endregion #region ReplaceNullChars tests diff --git a/test/Utilities/Automation.CLI/CLITestBase.common.cs b/test/Utilities/Automation.CLI/CLITestBase.common.cs index 68aa8a4f1c..2d6da22d70 100644 --- a/test/Utilities/Automation.CLI/CLITestBase.common.cs +++ b/test/Utilities/Automation.CLI/CLITestBase.common.cs @@ -42,7 +42,7 @@ protected static string GetTestPlatformVersion() protected static string GetArtifactsBinFolderPath() { - string assemblyLocation = System.Reflection.Assembly.GetExecutingAssembly().Location; + string assemblyLocation = Assembly.GetExecutingAssembly().Location; string artifactsBinFolder = Path.GetFullPath(Path.Combine(assemblyLocation, @"..\..\..\..")); Directory.Exists(artifactsBinFolder).Should().BeTrue(); @@ -52,7 +52,7 @@ protected static string GetArtifactsBinFolderPath() protected static string GetArtifactsTestResultsFolderPath() { - string assemblyLocation = System.Reflection.Assembly.GetExecutingAssembly().Location; + string assemblyLocation = Assembly.GetExecutingAssembly().Location; string artifactsFolder = Path.GetFullPath(Path.Combine(assemblyLocation, @"..\..\..\..\..")); Directory.Exists(artifactsFolder).Should().BeTrue(); From f70bdd9eb621c630104dc366f69f10930855833c Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 27 Dec 2024 15:28:38 +0100 Subject: [PATCH 186/273] MSTEST0037 (proper assert analyzer): Don't report for user defined equality operators (#4456) --- .../UseProperAssertMethodsAnalyzer.cs | 8 +- .../UseProperAssertMethodsAnalyzerTests.cs | 372 ++++++++++++++++++ 2 files changed, 378 insertions(+), 2 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs index cfa77db522..dac84bcaaa 100644 --- a/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/UseProperAssertMethodsAnalyzer.cs @@ -207,6 +207,7 @@ private static bool IsIsNotNullPattern(IOperation operation, [NotNullWhen(true)] private static bool IsEqualsNullBinaryOperator(IOperation operation, [NotNullWhen(true)] out SyntaxNode? expressionUnderTest) { if (operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.Equals, RightOperand: { } rightOperand } binaryOperation && + binaryOperation.OperatorMethod is not { MethodKind: MethodKind.UserDefinedOperator } && rightOperand.WalkDownConversion() is ILiteralOperation { ConstantValue: { HasValue: true, Value: null } }) { expressionUnderTest = binaryOperation.LeftOperand.Syntax; @@ -221,6 +222,7 @@ private static bool IsEqualsNullBinaryOperator(IOperation operation, [NotNullWhe private static bool IsNotEqualsNullBinaryOperator(IOperation operation, [NotNullWhen(true)] out SyntaxNode? expressionUnderTest) { if (operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.NotEquals, RightOperand: { } rightOperand } binaryOperation && + binaryOperation.OperatorMethod is not { MethodKind: MethodKind.UserDefinedOperator } && rightOperand.WalkDownConversion() is ILiteralOperation { ConstantValue: { HasValue: true, Value: null } }) { expressionUnderTest = binaryOperation.LeftOperand.Syntax; @@ -253,7 +255,8 @@ private static EqualityCheckStatus RecognizeEqualityCheck(IOperation operation, toBecomeActual = isPattern1.Value.Syntax; return EqualityCheckStatus.Equals; } - else if (operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.Equals } binaryOperation1) + else if (operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.Equals } binaryOperation1 && + binaryOperation1.OperatorMethod is not { MethodKind: MethodKind.UserDefinedOperator }) { // This is quite arbitrary. We can do extra checks to see which one (if any) looks like a "constant" and make it the expected. toBecomeExpected = binaryOperation1.RightOperand.Syntax; @@ -266,7 +269,8 @@ private static EqualityCheckStatus RecognizeEqualityCheck(IOperation operation, toBecomeActual = isPattern2.Value.Syntax; return EqualityCheckStatus.NotEquals; } - else if (operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.NotEquals } binaryOperation2) + else if (operation is IBinaryOperation { OperatorKind: BinaryOperatorKind.NotEquals } binaryOperation2 && + binaryOperation2.OperatorMethod is not { MethodKind: MethodKind.UserDefinedOperator }) { // This is quite arbitrary. We can do extra checks to see which one (if any) looks like a "constant" and make it the expected. toBecomeExpected = binaryOperation2.RightOperand.Syntax; diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs index cdb5bfaf7c..1676550103 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseProperAssertMethodsAnalyzerTests.cs @@ -11,6 +11,14 @@ namespace MSTest.Analyzers.Test; [TestClass] public sealed class UseProperAssertMethodsAnalyzerTests { + private const string SomeClassWithUserDefinedEqualityOperators = """ + public class SomeClass + { + public static bool operator ==(SomeClass x, SomeClass y) => true; + public static bool operator !=(SomeClass x, SomeClass y) => false; + } + """; + [TestMethod] public async Task WhenAssertIsTrueWithEqualsNullArgument() { @@ -51,6 +59,29 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsTrueWithEqualsNullArgumentAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + Assert.IsTrue(x == null); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [TestMethod] public async Task WhenAssertIsTrueWithIsNullArgument() { @@ -91,6 +122,50 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsTrueWithIsNullArgumentAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + {|#0:Assert.IsTrue(x is null)|}; + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + string fixedCode = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + Assert.IsNull(x); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync( + code, + // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNull' instead of 'Assert.IsTrue' + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNull", "IsTrue"), + fixedCode); + } + [TestMethod] public async Task WhenAssertIsTrueWithNotEqualsNullArgument() { @@ -131,6 +206,29 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsTrueWithNotEqualsNullArgumentAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + Assert.IsTrue(x != null); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [TestMethod] public async Task WhenAssertIsTrueWithIsNotNullArgument() { @@ -171,6 +269,50 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsTrueWithIsNotNullArgumentAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + {|#0:Assert.IsTrue(x is not null)|}; + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + string fixedCode = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + Assert.IsNotNull(x); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync( + code, + // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNotNull' instead of 'Assert.IsTrue' + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNotNull", "IsTrue"), + fixedCode); + } + [TestMethod] public async Task WhenAssertIsFalseWithEqualsNullArgument() { @@ -211,6 +353,29 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsFalseWithEqualsNullArgumentAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + Assert.IsFalse(x == null); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [TestMethod] public async Task WhenAssertIsFalseWithIsNullArgument() { @@ -251,6 +416,50 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsFalseWithIsNullArgumentAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + {|#0:Assert.IsFalse(x is null)|}; + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + string fixedCode = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + Assert.IsNotNull(x); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync( + code, + // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNotNull' instead of 'Assert.IsFalse' + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNotNull", "IsFalse"), + fixedCode); + } + [TestMethod] public async Task WhenAssertIsFalseWithNotEqualsNullArgument() { @@ -291,6 +500,29 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsFalseWithNotEqualsNullArgumentAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + Assert.IsFalse(x != null); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [TestMethod] public async Task WhenAssertIsFalseWithIsNotNullArgument() { @@ -331,6 +563,50 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsFalseWithIsNotNullArgumentAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + {|#0:Assert.IsFalse(x is not null)|}; + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + string fixedCode = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + Assert.IsNull(x); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync( + code, + // /0/Test0.cs(10,9): info MSTEST0037: Use 'Assert.IsNull' instead of 'Assert.IsFalse' + VerifyCS.DiagnosticIgnoringAdditionalLocations().WithLocation(0).WithArguments("IsNull", "IsFalse"), + fixedCode); + } + [TestMethod] public async Task WhenAssertIsTrueAndArgumentIsEquality() { @@ -373,6 +649,30 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsTrueAndArgumentIsEqualityAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + SomeClass y = new SomeClass(); + Assert.IsTrue(x == y); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [TestMethod] public async Task WhenAssertIsTrueAndArgumentIsInequality() { @@ -415,6 +715,30 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsTrueAndArgumentIsInequalityAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + SomeClass y = new SomeClass(); + Assert.IsTrue(x != y); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [TestMethod] public async Task WhenAssertIsFalseAndArgumentIsEquality() { @@ -457,6 +781,30 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsFalseAndArgumentIsEqualityAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + SomeClass y = new SomeClass(); + Assert.IsFalse(x == y); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [TestMethod] public async Task WhenAssertIsFalseAndArgumentIsInequality() { @@ -499,6 +847,30 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenAssertIsFalseAndArgumentIsInequalityAndUserDefinedOperator() + { + string code = $$""" + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + SomeClass x = new SomeClass(); + SomeClass y = new SomeClass(); + Assert.IsFalse(x != y); + } + } + + {{SomeClassWithUserDefinedEqualityOperators}} + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [TestMethod] public async Task WhenAssertAreEqualAndExpectedIsNull() { From a50e2b8b021c1b2f2fa0102611328c2d7d08569b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Dec 2024 15:33:09 +0100 Subject: [PATCH 187/273] [main] Bump MSTest from 3.8.0-preview.24616.6 to 3.8.0-preview.24623.10 (#4440) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Amaury Levé --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 2ab7b2733f..fb5512616f 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -24,7 +24,7 @@ 1.1.3-beta1.24423.1 - 3.8.0-preview.24616.6 + 3.8.0-preview.24623.10 From cbcc9c91a1063ee2c4bf61759b78895ee0055ef1 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sat, 28 Dec 2024 14:48:32 +0100 Subject: [PATCH 188/273] Fix MSTEST0017 false positive when both actual/expected are constants (#4460) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- ...rgsShouldBePassedInCorrectOrderAnalyzer.cs | 10 ++++++--- ...ouldBePassedInCorrectOrderAnalyzerTests.cs | 22 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/AssertionArgsShouldBePassedInCorrectOrderAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AssertionArgsShouldBePassedInCorrectOrderAnalyzer.cs index a675d0fc33..9d7e1f6aee 100644 --- a/src/Analyzers/MSTest.Analyzers/AssertionArgsShouldBePassedInCorrectOrderAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/AssertionArgsShouldBePassedInCorrectOrderAnalyzer.cs @@ -57,6 +57,9 @@ public override void Initialize(AnalysisContext context) }); } + private static bool IsConstant(IArgumentOperation argumentOperation) + => argumentOperation.Value.ConstantValue.HasValue; + private static void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol assertSymbol) { var invocationOperation = (IInvocationOperation)context.Operation; @@ -69,9 +72,10 @@ private static void AnalyzeOperation(OperationAnalysisContext context, INamedTyp return; } - // If the actual value is a constant or a literal, then the arguments are in the wrong order. - if (actualArgument.Value.Kind == OperationKind.Literal - || actualArgument.Value.ConstantValue.HasValue) + // If the actual value is a constant or a literal and expected is not, then the arguments are in the wrong order. + // Note that we don't report if both are literals or constants, as there is no real fix for this. + // If both are literals or constants, the assert will always pass or always fail. + if (IsConstant(actualArgument) && !IsConstant(expectedArgument)) { context.ReportDiagnostic(invocationOperation.CreateDiagnostic(Rule)); return; diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldBePassedInCorrectOrderAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldBePassedInCorrectOrderAnalyzerTests.cs index 2084f21415..7be33c066d 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldBePassedInCorrectOrderAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldBePassedInCorrectOrderAnalyzerTests.cs @@ -162,6 +162,28 @@ await VerifyCS.VerifyCodeFixAsync( fixedCode); } + [TestMethod] + public async Task WhenBothAreLiterals_NoDiagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void NonCompliant() + { + Assert.AreEqual(0, 0); + Assert.AreEqual(0, 1); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } + [TestMethod] public async Task LiteralUsingNamedArgument() { From 8fe24658b24f243ec34b768d2997330b2173657f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sat, 28 Dec 2024 15:41:11 +0100 Subject: [PATCH 189/273] Better handling of CTS and timeout tokens (#4444) --- .../Execution/TestMethodInfo.cs | 143 ++- .../Extensions/TestResultExtensions.cs | 4 +- .../Extensions/UnitTestOutcomeExtensions.cs | 13 + .../Helpers/FixtureMethodRunner.cs | 45 +- .../Resources/Resource.Designer.cs | 4 +- .../Resources/Resource.resx | 4 +- .../Resources/xlf/Resource.cs.xlf | 12 +- .../Resources/xlf/Resource.de.xlf | 12 +- .../Resources/xlf/Resource.es.xlf | 12 +- .../Resources/xlf/Resource.fr.xlf | 12 +- .../Resources/xlf/Resource.it.xlf | 12 +- .../Resources/xlf/Resource.ja.xlf | 12 +- .../Resources/xlf/Resource.ko.xlf | 12 +- .../Resources/xlf/Resource.pl.xlf | 12 +- .../Resources/xlf/Resource.pt-BR.xlf | 12 +- .../Resources/xlf/Resource.ru.xlf | 12 +- .../Resources/xlf/Resource.tr.xlf | 12 +- .../Resources/xlf/Resource.zh-Hans.xlf | 12 +- .../Resources/xlf/Resource.zh-Hant.xlf | 12 +- .../Extensions/ExceptionExtensions.cs | 7 +- .../Services/ThreadOperations.cs | 13 +- .../TestContextShouldBeValidAnalyzer.cs | 2 +- .../TestFramework.Extensions/TestContext.cs | 2 +- .../TestFramework.Extensions.csproj | 4 + .../CancellationTests.cs | 2 +- .../InitializeAndCleanupTimeoutTests.cs | 762 --------------- .../TimeoutTests.cs | 912 +++++++++++++++++- .../Execution/TestMethodInfoTests.cs | 6 +- 28 files changed, 1147 insertions(+), 932 deletions(-) delete mode 100644 test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs index 966eb13863..aec6cdcd0a 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs @@ -5,6 +5,7 @@ using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; using Microsoft.VisualStudio.TestTools.UnitTesting; using ObjectModelUnitTestOutcome = Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestOutcome; @@ -113,7 +114,7 @@ public virtual TestResult Invoke(object?[]? arguments) watch.Start(); try { - result = IsTimeoutSet ? ExecuteInternalWithTimeout(arguments) : ExecuteInternal(arguments); + result = IsTimeoutSet ? ExecuteInternalWithTimeout(arguments) : ExecuteInternal(arguments, null); } finally { @@ -217,7 +218,7 @@ public virtual TestResult Invoke(object?[]? arguments) /// Arguments to be passed to the method. /// The result of the execution. [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] - private TestResult ExecuteInternal(object?[]? arguments) + private TestResult ExecuteInternal(object?[]? arguments, CancellationTokenSource? timeoutTokenSource) { DebugEx.Assert(TestMethod != null, "UnitTestExecuter.DefaultTestMethodInvoke: testMethod = null."); @@ -239,7 +240,7 @@ private TestResult ExecuteInternal(object?[]? arguments) // For any failure after this point, we must run TestCleanup _isTestContextSet = true; - if (RunTestInitializeMethod(_classInstance, result)) + if (RunTestInitializeMethod(_classInstance, result, timeoutTokenSource)) { hasTestInitializePassed = true; if (IsTimeoutSet) @@ -267,12 +268,21 @@ private TestResult ExecuteInternal(object?[]? arguments) // Expected Exception was thrown, so Pass the test result.Outcome = UTF.UnitTestOutcome.Passed; } - else if (realException is OperationCanceledException oce && oce.CancellationToken == TestMethodOptions.TestContext?.Context.CancellationTokenSource.Token) + else if (realException.IsOperationCanceledExceptionFromToken(TestMethodOptions.TestContext!.Context.CancellationTokenSource.Token)) { result.Outcome = UTF.UnitTestOutcome.Timeout; result.TestFailureException = new TestFailedException( ObjectModelUnitTestOutcome.Timeout, - string.Format(CultureInfo.CurrentCulture, Resource.Execution_Test_Cancelled, TestMethodName)); + timeoutTokenSource?.Token.IsCancellationRequested == true + ? string.Format( + CultureInfo.InvariantCulture, + Resource.Execution_Test_Timeout, + TestMethodName, + TestMethodOptions.TimeoutInfo.Timeout) + : string.Format( + CultureInfo.InvariantCulture, + Resource.Execution_Test_Cancelled, + TestMethodName)); } else { @@ -321,7 +331,7 @@ private TestResult ExecuteInternal(object?[]? arguments) // Pulling it out so extension writers can abort custom cleanups if need be. Having this in a finally block // does not allow a thread abort exception to be raised within the block but throws one after finally is executed // crashing the process. This was blocking writing an extension for Dynamic Timeout in VSO. - RunTestCleanupMethod(result); + RunTestCleanupMethod(result, timeoutTokenSource); return testRunnerException != null ? throw testRunnerException : result; } @@ -466,7 +476,7 @@ private static TestFailedException HandleMethodException(Exception ex, Exception /// /// Instance of TestResult. [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] - private void RunTestCleanupMethod(TestResult result) + private void RunTestCleanupMethod(TestResult result, CancellationTokenSource? timeoutTokenSource) { DebugEx.Assert(result != null, "result != null"); @@ -482,16 +492,25 @@ private void RunTestCleanupMethod(TestResult result) { try { + // Reset the cancellation token source to avoid cancellation of cleanup methods because of the init or test method cancellation. + TestMethodOptions.TestContext!.Context.CancellationTokenSource = new CancellationTokenSource(); + + // If we are running with a method timeout, we need to cancel the cleanup when the overall timeout expires. If it already expired, nothing to do. + if (timeoutTokenSource is { IsCancellationRequested: false }) + { + timeoutTokenSource?.Token.Register(TestMethodOptions.TestContext.Context.CancellationTokenSource.Cancel); + } + // Test cleanups are called in the order of discovery // Current TestClass -> Parent -> Grandparent testCleanupException = testCleanupMethod is not null - ? InvokeCleanupMethod(testCleanupMethod, _classInstance, Parent.BaseTestCleanupMethodsQueue.Count) + ? InvokeCleanupMethod(testCleanupMethod, _classInstance, Parent.BaseTestCleanupMethodsQueue.Count, timeoutTokenSource) : null; var baseTestCleanupQueue = new Queue(Parent.BaseTestCleanupMethodsQueue); while (baseTestCleanupQueue.Count > 0 && testCleanupException is null) { testCleanupMethod = baseTestCleanupQueue.Dequeue(); - testCleanupException = InvokeCleanupMethod(testCleanupMethod, _classInstance, baseTestCleanupQueue.Count); + testCleanupException = InvokeCleanupMethod(testCleanupMethod, _classInstance, baseTestCleanupQueue.Count, timeoutTokenSource); } } finally @@ -515,9 +534,9 @@ private void RunTestCleanupMethod(TestResult result) } // If the exception is already a `TestFailedException` we throw it as-is - if (testCleanupException is TestFailedException) + if (testCleanupException is TestFailedException tfe) { - result.Outcome = UTF.UnitTestOutcome.Failed; + result.Outcome = tfe.Outcome.ToAdapterOutcome(); result.TestFailureException = testCleanupException; return; } @@ -593,7 +612,7 @@ private void RunTestCleanupMethod(TestResult result) /// Instance of TestResult. /// True if the TestInitialize method(s) did not throw an exception. [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "Requirement is to handle all kinds of user exceptions and message appropriately.")] - private bool RunTestInitializeMethod(object classInstance, TestResult result) + private bool RunTestInitializeMethod(object classInstance, TestResult result, CancellationTokenSource? timeoutTokenSource) { DebugEx.Assert(classInstance != null, "classInstance != null"); DebugEx.Assert(result != null, "result != null"); @@ -609,7 +628,9 @@ private bool RunTestInitializeMethod(object classInstance, TestResult result) while (baseTestInitializeStack.Count > 0) { testInitializeMethod = baseTestInitializeStack.Pop(); - testInitializeException = testInitializeMethod is not null ? InvokeInitializeMethod(testInitializeMethod, classInstance) : null; + testInitializeException = testInitializeMethod is not null + ? InvokeInitializeMethod(testInitializeMethod, classInstance, timeoutTokenSource) + : null; if (testInitializeException is not null) { break; @@ -619,7 +640,9 @@ private bool RunTestInitializeMethod(object classInstance, TestResult result) if (testInitializeException == null) { testInitializeMethod = Parent.TestInitializeMethod; - testInitializeException = testInitializeMethod is not null ? InvokeInitializeMethod(testInitializeMethod, classInstance) : null; + testInitializeException = testInitializeMethod is not null + ? InvokeInitializeMethod(testInitializeMethod, classInstance, timeoutTokenSource) + : null; } } catch (Exception ex) @@ -634,9 +657,9 @@ private bool RunTestInitializeMethod(object classInstance, TestResult result) } // If the exception is already a `TestFailedException` we throw it as-is - if (testInitializeException is TestFailedException) + if (testInitializeException is TestFailedException tfe) { - result.Outcome = UTF.UnitTestOutcome.Failed; + result.Outcome = tfe.Outcome.ToAdapterOutcome(); result.TestFailureException = testInitializeException; return false; } @@ -655,7 +678,9 @@ private bool RunTestInitializeMethod(object classInstance, TestResult result) exceptionMessage); StackTraceInformation? stackTrace = realException.GetStackTraceInformation(); - result.Outcome = realException is AssertInconclusiveException ? UTF.UnitTestOutcome.Inconclusive : UTF.UnitTestOutcome.Failed; + result.Outcome = realException is AssertInconclusiveException + ? UTF.UnitTestOutcome.Inconclusive + : UTF.UnitTestOutcome.Failed; result.TestFailureException = new TestFailedException( result.Outcome.ToUnitTestOutcome(), errorMessage, @@ -665,7 +690,7 @@ private bool RunTestInitializeMethod(object classInstance, TestResult result) return false; } - private TestFailedException? InvokeInitializeMethod(MethodInfo methodInfo, object classInstance) + private TestFailedException? InvokeInitializeMethod(MethodInfo methodInfo, object classInstance, CancellationTokenSource? timeoutTokenSource) { TimeoutInfo? timeout = null; if (Parent.TestInitializeMethodTimeoutMilliseconds.TryGetValue(methodInfo, out TimeoutInfo localTimeout)) @@ -680,10 +705,13 @@ private bool RunTestInitializeMethod(object classInstance, TestResult result) methodInfo, new InstanceExecutionContextScope(classInstance, Parent.ClassType), Resource.TestInitializeWasCancelled, - Resource.TestInitializeTimedOut); + Resource.TestInitializeTimedOut, + timeoutTokenSource is null + ? null + : (timeoutTokenSource, TestMethodOptions.TimeoutInfo.Timeout)); } - private TestFailedException? InvokeCleanupMethod(MethodInfo methodInfo, object classInstance, int remainingCleanupCount) + private TestFailedException? InvokeCleanupMethod(MethodInfo methodInfo, object classInstance, int remainingCleanupCount, CancellationTokenSource? timeoutTokenSource) { TimeoutInfo? timeout = null; if (Parent.TestCleanupMethodTimeoutMilliseconds.TryGetValue(methodInfo, out TimeoutInfo localTimeout)) @@ -698,7 +726,10 @@ private bool RunTestInitializeMethod(object classInstance, TestResult result) methodInfo, new InstanceExecutionContextScope(classInstance, Parent.ClassType, remainingCleanupCount), Resource.TestCleanupWasCancelled, - Resource.TestCleanupTimedOut); + Resource.TestCleanupTimedOut, + timeoutTokenSource is null + ? null + : (timeoutTokenSource, TestMethodOptions.TimeoutInfo.Timeout)); } /// @@ -782,18 +813,27 @@ private bool SetTestContext(object classInstance, TestResult result) // In most cases, exception will be TargetInvocationException with real exception wrapped // in the InnerException; or user code throws an exception. // It also seems that in rare cases the ex can be null. - Exception actualException = ex.InnerException ?? ex; - string exceptionMessage = actualException.GetFormattedExceptionMessage(); - StackTraceInformation? stackTraceInfo = actualException.GetStackTraceInformation(); + Exception realException = ex.GetRealException(); - string errorMessage = string.Format( - CultureInfo.CurrentCulture, - Resource.UTA_InstanceCreationError, - TestClassName, - exceptionMessage); + if (realException.IsOperationCanceledExceptionFromToken(TestMethodOptions.TestContext!.Context.CancellationTokenSource.Token)) + { + result.Outcome = UTF.UnitTestOutcome.Timeout; + result.TestFailureException = new TestFailedException(ObjectModelUnitTestOutcome.Timeout, string.Format(CultureInfo.CurrentCulture, Resource.Execution_Test_Timeout, TestMethodName, TestMethodOptions.TimeoutInfo.Timeout)); + } + else + { + string exceptionMessage = realException.GetFormattedExceptionMessage(); + StackTraceInformation? stackTraceInfo = realException.GetStackTraceInformation(); - result.Outcome = UTF.UnitTestOutcome.Failed; - result.TestFailureException = new TestFailedException(ObjectModelUnitTestOutcome.Failed, errorMessage, stackTraceInfo); + string errorMessage = string.Format( + CultureInfo.CurrentCulture, + Resource.UTA_InstanceCreationError, + TestClassName, + exceptionMessage); + + result.Outcome = UTF.UnitTestOutcome.Failed; + result.TestFailureException = new TestFailedException(ObjectModelUnitTestOutcome.Failed, errorMessage, stackTraceInfo); + } } return classInstance; @@ -823,13 +863,13 @@ private TestResult ExecuteInternalWithTimeout(object?[]? arguments) Outcome = UTF.UnitTestOutcome.Timeout, TestFailureException = new TestFailedException( ObjectModelUnitTestOutcome.Timeout, - string.Format(CultureInfo.CurrentCulture, Resource.Execution_Test_Timeout, TestMethodName)), + string.Format(CultureInfo.CurrentCulture, Resource.Execution_Test_Timeout, TestMethodName, TestMethodOptions.TimeoutInfo.Timeout)), }; } try { - return ExecuteInternal(arguments); + return ExecuteInternal(arguments, timeoutTokenSource); } catch (OperationCanceledException) { @@ -841,7 +881,7 @@ private TestResult ExecuteInternalWithTimeout(object?[]? arguments) TestFailureException = new TestFailedException( ObjectModelUnitTestOutcome.Timeout, timeoutTokenSource.Token.IsCancellationRequested - ? string.Format(CultureInfo.CurrentCulture, Resource.Execution_Test_Timeout, TestMethodName) + ? string.Format(CultureInfo.CurrentCulture, Resource.Execution_Test_Timeout, TestMethodName, TestMethodOptions.TimeoutInfo.Timeout) : string.Format(CultureInfo.CurrentCulture, Resource.Execution_Test_Cancelled, TestMethodName)), }; } @@ -849,26 +889,14 @@ private TestResult ExecuteInternalWithTimeout(object?[]? arguments) finally { timeoutTokenSource?.Dispose(); + timeoutTokenSource = null; } } TestResult? result = null; Exception? failure = null; - void ExecuteAsyncAction() - { - try - { - result = ExecuteInternal(arguments); - } - catch (Exception ex) - { - failure = ex; - } - } - - CancellationToken cancelToken = TestMethodOptions.TestContext!.Context.CancellationTokenSource.Token; - if (PlatformServiceProvider.Instance.ThreadOperations.Execute(ExecuteAsyncAction, TestMethodOptions.TimeoutInfo.Timeout, cancelToken)) + if (PlatformServiceProvider.Instance.ThreadOperations.Execute(ExecuteAsyncAction, TestMethodOptions.TimeoutInfo.Timeout, TestMethodOptions.TestContext!.Context.CancellationTokenSource.Token)) { if (failure != null) { @@ -879,12 +907,12 @@ void ExecuteAsyncAction() // It's possible that some failures happened and that the cleanup wasn't executed, so we need to run it here. // The method already checks if the cleanup was already executed. - RunTestCleanupMethod(result); + RunTestCleanupMethod(result, null); return result; } // Timed out or canceled - string errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.Execution_Test_Timeout, TestMethodName); + string errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.Execution_Test_Timeout, TestMethodName, TestMethodOptions.TimeoutInfo.Timeout); if (TestMethodOptions.TestContext.Context.CancellationTokenSource.IsCancellationRequested) { errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.Execution_Test_Cancelled, TestMethodName); @@ -899,7 +927,20 @@ void ExecuteAsyncAction() // We don't know when the cancellation happened so it's possible that the cleanup wasn't executed, so we need to run it here. // The method already checks if the cleanup was already executed. - RunTestCleanupMethod(timeoutResult); + RunTestCleanupMethod(timeoutResult, null); return timeoutResult; + + // Local functions + void ExecuteAsyncAction() + { + try + { + result = ExecuteInternal(arguments, null); + } + catch (Exception ex) + { + failure = ex; + } + } } } diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs index 301984dbb1..ecdd6901b5 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs @@ -36,7 +36,9 @@ internal static UnitTestResult[] ToUnitTestResults(this IReadOnlyCollection UnitTestOutcome.Error, }; + internal static UTF.UnitTestOutcome ToAdapterOutcome(this UnitTestOutcome outcome) + => outcome switch + { + UnitTestOutcome.Failed => UTF.UnitTestOutcome.Failed, + UnitTestOutcome.Inconclusive => UTF.UnitTestOutcome.Inconclusive, + UnitTestOutcome.InProgress => UTF.UnitTestOutcome.InProgress, + UnitTestOutcome.Passed => UTF.UnitTestOutcome.Passed, + UnitTestOutcome.Timeout => UTF.UnitTestOutcome.Timeout, + UnitTestOutcome.NotRunnable => UTF.UnitTestOutcome.NotRunnable, + UnitTestOutcome.NotFound => UTF.UnitTestOutcome.NotFound, + _ => UTF.UnitTestOutcome.Error, + }; + /// /// Returns more important outcome of two. /// diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/FixtureMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Helpers/FixtureMethodRunner.cs index c7f5f4b126..79dd00a0aa 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/FixtureMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/FixtureMethodRunner.cs @@ -5,6 +5,7 @@ using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; using UnitTestOutcome = Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel.UnitTestOutcome; @@ -14,8 +15,18 @@ internal static class FixtureMethodRunner { internal static TestFailedException? RunWithTimeoutAndCancellation( Action action, CancellationTokenSource cancellationTokenSource, TimeoutInfo? timeoutInfo, MethodInfo methodInfo, - IExecutionContextScope executionContextScope, string methodCanceledMessageFormat, string methodTimedOutMessageFormat) + IExecutionContextScope executionContextScope, string methodCanceledMessageFormat, string methodTimedOutMessageFormat, + // When a test method is marked with [Timeout], this timeout is applied from ctor to destructor, so we need to take + // that into account when processing the OCE of the action. + (CancellationTokenSource TokenSource, int Timeout)? testTimeoutInfo = default) { + if (cancellationTokenSource.Token.IsCancellationRequested) + { + return new( + UnitTestOutcome.Timeout, + string.Format(CultureInfo.InvariantCulture, methodCanceledMessageFormat, methodInfo.DeclaringType!.FullName, methodInfo.Name)); + } + // If no timeout is specified, we can run the action directly. This avoids any overhead of creating a task/thread and // ensures that the execution context is preserved (as we run the action on the current thread). if (timeoutInfo is null) @@ -27,13 +38,22 @@ internal static class FixtureMethodRunner } catch (Exception ex) { - Exception realException = ex.GetRealException(); - - if (realException is OperationCanceledException oce && oce.CancellationToken == cancellationTokenSource.Token) + if (ex.GetRealException().IsOperationCanceledExceptionFromToken(cancellationTokenSource.Token)) { return new( UnitTestOutcome.Timeout, - string.Format(CultureInfo.InvariantCulture, methodCanceledMessageFormat, methodInfo.DeclaringType!.FullName, methodInfo.Name)); + testTimeoutInfo?.TokenSource.Token.IsCancellationRequested == true + ? string.Format( + CultureInfo.InvariantCulture, + methodTimedOutMessageFormat, + methodInfo.DeclaringType!.FullName, + methodInfo.Name, + testTimeoutInfo.Value.Timeout) + : string.Format( + CultureInfo.InvariantCulture, + methodCanceledMessageFormat, + methodInfo.DeclaringType!.FullName, + methodInfo.Name)); } throw; @@ -75,7 +95,7 @@ internal static class FixtureMethodRunner action(); return null; } - catch (OperationCanceledException) + catch (Exception ex) when (ex.IsOperationCanceledExceptionFromToken(cancellationTokenSource.Token)) { // Ideally we would like to check that the token of the exception matches cancellationTokenSource but TestContext // instances are not well defined so we have to handle the exception entirely. @@ -148,9 +168,7 @@ internal static class FixtureMethodRunner methodInfo.Name, timeout)); } - catch (Exception ex) when - (ex is OperationCanceledException - || (ex is AggregateException aggregateEx && aggregateEx.InnerExceptions.OfType().Any())) + catch (Exception ex) when (ex.IsOperationCanceledExceptionFromToken(cancellationTokenSource.Token)) { return new( UnitTestOutcome.Timeout, @@ -168,7 +186,7 @@ internal static class FixtureMethodRunner } } - [System.Runtime.Versioning.SupportedOSPlatform("windows")] + [SupportedOSPlatform("windows")] private static TestFailedException? RunWithTimeoutAndCancellationWithSTAThread( Action action, CancellationTokenSource cancellationTokenSource, int timeout, MethodInfo methodInfo, IExecutionContextScope executionContextScope, string methodCanceledMessageFormat, string methodTimedOutMessageFormat) @@ -212,12 +230,7 @@ internal static class FixtureMethodRunner methodInfo.Name, timeout)); } - catch (Exception ex) when - - // This exception occurs when the cancellation happens before the task is actually started. - ((ex is TaskCanceledException tce && tce.CancellationToken == cancellationTokenSource.Token) - || (ex is OperationCanceledException oce && oce.CancellationToken == cancellationTokenSource.Token) - || (ex is AggregateException aggregateEx && aggregateEx.InnerExceptions.OfType().Any())) + catch (Exception ex) when (ex.IsOperationCanceledExceptionFromToken(cancellationTokenSource.Token)) { return new( UnitTestOutcome.Timeout, diff --git a/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs b/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs index 1614764330..d459e481e5 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs +++ b/src/Adapter/MSTest.TestAdapter/Resources/Resource.Designer.cs @@ -279,7 +279,7 @@ internal static string ExceptionsThrown { } /// - /// Looks up a localized string similar to Test '{0}' execution has been aborted.. + /// Looks up a localized string similar to Test '{0}' was canceled. /// internal static string Execution_Test_Cancelled { get { @@ -288,7 +288,7 @@ internal static string Execution_Test_Cancelled { } /// - /// Looks up a localized string similar to Test '{0}' exceeded execution timeout period.. + /// Looks up a localized string similar to Test '{0}' timed out after {1}ms. /// internal static string Execution_Test_Timeout { get { diff --git a/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx b/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx index 4a476afa7d..fba272ebdf 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx +++ b/src/Adapter/MSTest.TestAdapter/Resources/Resource.resx @@ -118,7 +118,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - Test '{0}' exceeded execution timeout period. + Test '{0}' timed out after {1}ms Running tests in any of the provided sources is not supported for the selected platform @@ -308,7 +308,7 @@ Error: {1} Cannot run test method '{0}.{1}': Method has parameters, but does not define any test source. Use '[DataRow]', '[DynamicData]', or a custom 'ITestDataSource' data source to provide test data. - Test '{0}' execution has been aborted. + Test '{0}' was canceled Exception occurred while enumerating IDataSource attribute on "{0}.{1}": {2} diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf index 75dc16e953..3184131b78 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf @@ -67,9 +67,9 @@ byl však přijat tento počet argumentů: {4} s typy {5}. - Test '{0}' exceeded execution timeout period. - Test {0} překročil časový limit spuštění. - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Chyba: {1} - Test '{0}' execution has been aborted. - Spouštění testu {0} se přerušilo. - + Test '{0}' was canceled + Spouštění testu {0} se přerušilo. + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf index 0e8d214715..f10f5c2787 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf @@ -67,9 +67,9 @@ aber empfing {4} Argument(e) mit den Typen „{5}“. - Test '{0}' exceeded execution timeout period. - Der Test "{0}" hat das Ausführungstimeout überschritten. - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Fehler: {1} - Test '{0}' execution has been aborted. - Die Ausführung des Tests "{0}" wurde abgebrochen. - + Test '{0}' was canceled + Die Ausführung des Tests "{0}" wurde abgebrochen. + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf index 395a71c5bd..fe8e4275a6 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf @@ -67,9 +67,9 @@ pero recibió {4} argumento(s), con los tipos "{5}". - Test '{0}' exceeded execution timeout period. - La prueba '{0}' superó el tiempo de espera de ejecución. - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Error: {1} - Test '{0}' execution has been aborted. - Se anuló la ejecución de la prueba "{0}". - + Test '{0}' was canceled + Se anuló la ejecución de la prueba "{0}". + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf index b553cacfa8..a91f23e7cf 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf @@ -67,9 +67,9 @@ mais a reçu {4} argument(s), avec les types « {5} ». - Test '{0}' exceeded execution timeout period. - Le test '{0}' a dépassé le délai d'attente de l'exécution. - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Erreur : {1} - Test '{0}' execution has been aborted. - L'exécution du test '{0}' a été abandonnée. - + Test '{0}' was canceled + L'exécution du test '{0}' a été abandonnée. + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf index 6c5116a95b..917dfb783d 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf @@ -67,9 +67,9 @@ ma ha ricevuto {4} argomenti, con tipi "{5}". - Test '{0}' exceeded execution timeout period. - È stato superato il periodo di timeout per l'esecuzione del test '{0}'. - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Errore: {1} - Test '{0}' execution has been aborted. - L'esecuzione del test '{0}' è stata interrotta. - + Test '{0}' was canceled + L'esecuzione del test '{0}' è stata interrotta. + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf index 01bed386e8..85c9c7e0eb 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf @@ -68,9 +68,9 @@ but received {4} argument(s), with types '{5}'. - Test '{0}' exceeded execution timeout period. - テスト '{0}' は実行タイムアウトを超えました。 - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -419,9 +419,9 @@ Error: {1} - Test '{0}' execution has been aborted. - テスト '{0}' の実行が中止されました。 - + Test '{0}' was canceled + テスト '{0}' の実行が中止されました。 + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf index f5710bb237..12e3c7bc3b 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf @@ -67,9 +67,9 @@ but received {4} argument(s), with types '{5}'. - Test '{0}' exceeded execution timeout period. - '{0}' 테스트가 실행 시간 제한을 초과했습니다. - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Error: {1} - Test '{0}' execution has been aborted. - 테스트 '{0}' 실행이 중단되었습니다. - + Test '{0}' was canceled + 테스트 '{0}' 실행이 중단되었습니다. + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf index 8e18340251..63394f6986 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf @@ -67,9 +67,9 @@ ale liczba odebranych argumentów to {4} z typami „{5}”. - Test '{0}' exceeded execution timeout period. - Test „{0}” przekroczył okres limitu czasu na wykonanie. - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Błąd: {1} - Test '{0}' execution has been aborted. - Wykonanie testu „{0}” zostało przerwane. - + Test '{0}' was canceled + Wykonanie testu „{0}” zostało przerwane. + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf index d8232e39e2..6982a4d066 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf @@ -67,9 +67,9 @@ mas {4} argumentos recebidos, com tipos '{5}'. - Test '{0}' exceeded execution timeout period. - Teste '{0}' ultrapassou o período de tempo limite de execução. - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Erro: {1} - Test '{0}' execution has been aborted. - A execução do teste '{0}' foi anulada. - + Test '{0}' was canceled + A execução do teste '{0}' foi anulada. + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf index ad1b9f9366..102c60d3bb 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf @@ -67,9 +67,9 @@ but received {4} argument(s), with types '{5}'. - Test '{0}' exceeded execution timeout period. - Превышено время ожидания выполнения теста "{0}". - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Error: {1} - Test '{0}' execution has been aborted. - Выполнение теста "{0}" было прервано. - + Test '{0}' was canceled + Выполнение теста "{0}" было прервано. + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf index 6854ff4926..0c266c1565 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf @@ -67,9 +67,9 @@ ancak, '{5}' türüyle {4} argüman aldı. - Test '{0}' exceeded execution timeout period. - '{0}' testi yürütme zaman aşımı süresini aştı. - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Hata: {1} - Test '{0}' execution has been aborted. - '{0}' testinin yürütülmesi iptal edildi. - + Test '{0}' was canceled + '{0}' testinin yürütülmesi iptal edildi. + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf index 9f451c98c1..8d35d39c8f 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf @@ -67,9 +67,9 @@ but received {4} argument(s), with types '{5}'. - Test '{0}' exceeded execution timeout period. - 测试“{0}”的执行超时。 - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Error: {1} - Test '{0}' execution has been aborted. - 已中止测试“{0}”的执行。 - + Test '{0}' was canceled + 已中止测试“{0}”的执行。 + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf index 2dce2845f5..d9a3cf3089 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf @@ -67,9 +67,9 @@ but received {4} argument(s), with types '{5}'. - Test '{0}' exceeded execution timeout period. - 測試 '{0}' 超過執行逾時期限。 - + Test '{0}' timed out after {1}ms + Test '{0}' timed out after {1}ms + The type of the generic parameter '{0}' could not be inferred. @@ -418,9 +418,9 @@ Error: {1} - Test '{0}' execution has been aborted. - 測試 '{0}' 執行已中止。 - + Test '{0}' was canceled + 測試 '{0}' 執行已中止。 + Invalid value '{0}' specified for 'ClassCleanupLifecycle'. Supported scopes are {1}. diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Extensions/ExceptionExtensions.cs b/src/Adapter/MSTestAdapter.PlatformServices/Extensions/ExceptionExtensions.cs index 37b35a029c..04389c8555 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Extensions/ExceptionExtensions.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Extensions/ExceptionExtensions.cs @@ -1,8 +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. -#if !WINDOWS_UWP - namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; /// @@ -32,5 +30,8 @@ internal static string GetExceptionMessage(this Exception? exception) return exceptionString; } + + internal static bool IsOperationCanceledExceptionFromToken(this Exception ex, CancellationToken cancellationToken) + => (ex is OperationCanceledException oce && oce.CancellationToken == cancellationToken) + || (ex is AggregateException aggregateEx && aggregateEx.InnerExceptions.OfType().Any(oce => oce.CancellationToken == cancellationToken)); } -#endif diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs index d4c8b4ee1b..52ee8d5205 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ThreadOperations.cs @@ -1,6 +1,7 @@ // 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.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Extensions; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; @@ -43,11 +44,7 @@ private static bool ExecuteWithThreadPool(Action action, int timeout, Cancellati // False means execution timed out. return executionTask.Wait(timeout, cancellationToken); } - catch (Exception ex) when - ((ex is OperationCanceledException oce && oce.CancellationToken == cancellationToken) - - // This exception occurs when the cancellation happens before the task is actually started. - || (ex is TaskCanceledException tce && tce.CancellationToken == cancellationToken)) + catch (Exception ex) when (ex.IsOperationCanceledExceptionFromToken(cancellationToken)) { // Task execution canceled. return false; @@ -81,11 +78,7 @@ private static bool ExecuteWithCustomThread(Action action, int timeout, Cancella // If the execution thread completes before the timeout, the task will return true, otherwise false. return executionTask.Result; } - catch (Exception ex) when - ((ex is OperationCanceledException oce && oce.CancellationToken == cancellationToken) - - // This exception occurs when the cancellation happens before the task is actually started. - || (ex is TaskCanceledException tce && tce.CancellationToken == cancellationToken)) + catch (Exception ex) when (ex.IsOperationCanceledExceptionFromToken(cancellationToken)) { // Task execution canceled. return false; diff --git a/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs index f0d1e3a689..7ed69424de 100644 --- a/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/TestContextShouldBeValidAnalyzer.cs @@ -124,7 +124,7 @@ private static void CollectTestContextFieldsAssignedInConstructor( } if (operation is ISimpleAssignmentOperation assignmentOperation && - assignmentOperation.Target is IMemberReferenceOperation { Member: IFieldSymbol { } candidateField } targetMemberReference && + assignmentOperation.Target is IMemberReferenceOperation { Member: IFieldSymbol { } candidateField } && assignmentOperation.Value is IParameterReferenceOperation parameterReference && SymbolEqualityComparer.Default.Equals(parameterReference.Parameter, testContextParameter)) { diff --git a/src/TestFramework/TestFramework.Extensions/TestContext.cs b/src/TestFramework/TestFramework.Extensions/TestContext.cs index 418a7007e0..feb96117db 100644 --- a/src/TestFramework/TestFramework.Extensions/TestContext.cs +++ b/src/TestFramework/TestFramework.Extensions/TestContext.cs @@ -48,7 +48,7 @@ public abstract class TestContext /// /// Gets or sets the cancellation token source. This token source is canceled when test times out. Also when explicitly canceled the test will be aborted. /// - public virtual CancellationTokenSource CancellationTokenSource { get; protected set; } = new(); + public virtual CancellationTokenSource CancellationTokenSource { get; protected internal set; } = new(); public object?[]? TestData { get; protected set; } diff --git a/src/TestFramework/TestFramework.Extensions/TestFramework.Extensions.csproj b/src/TestFramework/TestFramework.Extensions/TestFramework.Extensions.csproj index a66f58bbf3..7aadfd3436 100644 --- a/src/TestFramework/TestFramework.Extensions/TestFramework.Extensions.csproj +++ b/src/TestFramework/TestFramework.Extensions/TestFramework.Extensions.csproj @@ -81,6 +81,10 @@ + + + + PreserveNewest diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs index 36124bf44a..e3ece73a25 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/CancellationTests.cs @@ -110,7 +110,7 @@ public async Task WhenCancelingTestContextTokenInTestMethod_MessageIsAsExpected( // Assert testHostResult.AssertExitCodeIs(2); - testHostResult.AssertOutputContains("Test 'TestMethod' execution has been aborted."); + testHostResult.AssertOutputContains("Test 'TestMethod' was canceled"); testHostResult.AssertOutputContains("Failed!"); } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs deleted file mode 100644 index feccbd7bbd..0000000000 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/InitializeAndCleanupTimeoutTests.cs +++ /dev/null @@ -1,762 +0,0 @@ -// 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.Testing.Platform.Acceptance.IntegrationTests; -using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; - -namespace MSTest.Acceptance.IntegrationTests; - -[TestClass] -public class InitializeAndCleanupTimeoutTests : AcceptanceTestBase -{ - private static readonly Dictionary InfoByKind = new() - { - ["assemblyInit"] = ("TestClass.AssemblyInit", "Assembly initialize", "ASSEMBLYINIT", "AssemblyInitializeTimeout"), - ["assemblyCleanup"] = ("TestClass.AssemblyCleanupMethod", "Assembly cleanup", "ASSEMBLYCLEANUP", "AssemblyCleanupTimeout"), - ["classInit"] = ("TestClass.ClassInit", "Class initialize", "CLASSINIT", "ClassInitializeTimeout"), - ["baseClassInit"] = ("TestClassBase.ClassInitBase", "Class initialize", "BASE_CLASSINIT", "ClassInitializeTimeout"), - ["classCleanup"] = ("TestClass.ClassCleanupMethod", "Class cleanup", "CLASSCLEANUP", "ClassCleanupTimeout"), - ["baseClassCleanup"] = ("TestClassBase.ClassCleanupBase", "Class cleanup", "BASE_CLASSCLEANUP", "ClassCleanupTimeout"), - ["testInit"] = ("TestClass.TestInit", "Test initialize", "TESTINIT", "TestInitializeTimeout"), - ["testCleanup"] = ("TestClass.TestCleanupMethod", "Test cleanup", "TESTCLEANUP", "TestCleanupTimeout"), - }; - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task AssemblyInit_WhenTestContextCanceled_AssemblyInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestWasCanceledAsync(AssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, - tfm, "TESTCONTEXT_CANCEL_", "assemblyInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task AssemblyInit_WhenTimeoutExpires_AssemblyInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, - tfm, "LONG_WAIT_", "assemblyInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task AssemblyInit_WhenTimeoutExpiresAndTestContextTokenIsUsed_AssemblyInitializeExits(string tfm) - => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, - "TIMEOUT_", "assemblyInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassInit_WhenTestContextCanceled_ClassInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestWasCanceledAsync(AssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, tfm, - "TESTCONTEXT_CANCEL_", "classInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassInit_WhenTimeoutExpires_ClassInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, - "LONG_WAIT_", "classInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassInit_WhenTimeoutExpiresAndTestContextTokenIsUsed_ClassInitializeExits(string tfm) - => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, - "TIMEOUT_", "classInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassInitBase_WhenTestContextCanceled_ClassInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestWasCanceledAsync(AssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, tfm, - "TESTCONTEXT_CANCEL_", "baseClassInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassInitBase_WhenTimeoutExpires_ClassInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, - "LONG_WAIT_", "baseClassInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassInitBase_WhenTimeoutExpiresAndTestContextTokenIsUsed_ClassInitializeExits(string tfm) - => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, - "TIMEOUT_", "baseClassInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task AssemblyInitialize_WhenTimeoutExpires_FromRunSettings_AssemblyInitializeIsCanceled(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "assemblyInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassInitialize_WhenTimeoutExpires_FromRunSettings_ClassInitializeIsCanceled(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "classInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task BaseClassInitialize_WhenTimeoutExpires_FromRunSettings_ClassInitializeIsCanceled(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "baseClassInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task AssemblyInitialize_WhenTimeoutExpires_AssemblyInitializeIsCanceled_AttributeTakesPrecedence(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "assemblyInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassInitialize_WhenTimeoutExpires_ClassInitializeIsCanceled_AttributeTakesPrecedence(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "classInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task BaseClassInitialize_WhenTimeoutExpires_ClassInitializeIsCanceled_AttributeTakesPrecedence(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "baseClassInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassCleanupBase_WhenTimeoutExpires_ClassCleanupTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, - "LONG_WAIT_", "baseClassCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassCleanup_WhenTimeoutExpires_ClassCleanupTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, - "LONG_WAIT_", "classCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassCleanup_WhenTimeoutExpires_FromRunSettings_ClassCleanupIsCanceled(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "classCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task BaseClassCleanup_WhenTimeoutExpires_FromRunSettings_ClassCleanupIsCanceled(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "baseClassCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task ClassCleanup_WhenTimeoutExpires_ClassCleanupIsCanceled_AttributeTakesPrecedence(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "classCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task BaseClassCleanup_WhenTimeoutExpires_ClassCleanupIsCanceled_AttributeTakesPrecedence(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "baseClassCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task AssemblyCleanup_WhenTimeoutExpires_AssemblyCleanupTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, - "LONG_WAIT_", "assemblyCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task AssemblyCleanup_WhenTimeoutExpires_FromRunSettings_AssemblyCleanupIsCanceled(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "assemblyCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task AssemblyCleanup_WhenTimeoutExpires_AssemblyCleanupIsCanceled_AttributeTakesPrecedence(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "assemblyCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task TestInitialize_WhenTimeoutExpires_TestInitializeTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, - "LONG_WAIT_", "testInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task TestInitialize_WhenTimeoutExpires_FromRunSettings_TestInitializeIsCanceled(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "testInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task TestInitialize_WhenTimeoutExpires_TestInitializeIsCanceled_AttributeTakesPrecedence(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "testInit"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task TestCleanup_WhenTimeoutExpires_TestCleanupTaskIsCanceled(string tfm) - => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, - "LONG_WAIT_", "testCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task TestCleanup_WhenTimeoutExpires_FromRunSettings_TestCleanupIsCanceled(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "testCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task TestCleanup_WhenTimeoutExpires_TestCleanupIsCanceled_AttributeTakesPrecedence(string tfm) - => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "testCleanup"); - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenAssemblyInitTimeoutExpires_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["TASKDELAY_ASSEMBLYINIT"] = "1" }); - - testHostResult.AssertOutputContains("AssemblyInit started"); - testHostResult.AssertOutputContains("Assembly initialize method 'TestClass.AssemblyInit' timed out after 100ms"); - testHostResult.AssertOutputDoesNotContain("AssemblyInit Thread.Sleep completed"); - testHostResult.AssertOutputDoesNotContain("AssemblyInit completed"); - } - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenAssemblyCleanupTimeoutExpires_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["TASKDELAY_ASSEMBLYCLEANUP"] = "1" }); - - testHostResult.AssertOutputContains("AssemblyCleanup started"); - testHostResult.AssertOutputContains("Assembly cleanup method 'TestClass.AssemblyCleanup' timed out after 100ms"); - testHostResult.AssertOutputDoesNotContain("AssemblyCleanup Thread.Sleep completed"); - testHostResult.AssertOutputDoesNotContain("AssemblyCleanup completed"); - } - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenClassInitTimeoutExpires_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["TASKDELAY_CLASSINIT"] = "1" }); - - testHostResult.AssertOutputContains("ClassInit started"); - testHostResult.AssertOutputContains("Class initialize method 'TestClass.ClassInit' timed out after 100ms"); - testHostResult.AssertOutputDoesNotContain("ClassInit Thread.Sleep completed"); - testHostResult.AssertOutputDoesNotContain("ClassInit completed"); - } - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenClassCleanupTimeoutExpires_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["TASKDELAY_CLASSCLEANUP"] = "1" }); - - testHostResult.AssertOutputContains("ClassCleanup started"); - testHostResult.AssertOutputContains("Class cleanup method 'TestClass.ClassCleanup' timed out after 100ms"); - testHostResult.AssertOutputDoesNotContain("ClassCleanup Thread.Sleep completed"); - testHostResult.AssertOutputDoesNotContain("ClassCleanup completed"); - } - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenTestInitTimeoutExpires_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["TASKDELAY_TESTINIT"] = "1" }); - - testHostResult.AssertOutputContains("TestInit started"); - testHostResult.AssertOutputContains("Test initialize method 'TestClass.TestInit' timed out after 100ms"); - testHostResult.AssertOutputDoesNotContain("TestInit completed"); - } - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenTestCleanupTimeoutExpires_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["TASKDELAY_TESTCLEANUP"] = "1" }); - - testHostResult.AssertOutputContains("TestCleanup started"); - // TODO: We would expect to have the following line but that's not the case - // testHostResult.AssertOutputContains("Test cleanup method 'TestClass.TestCleanup' timed out after 100ms"); - testHostResult.AssertOutputContains("Test cleanup method 'TestClass.TestCleanup' was canceled"); - testHostResult.AssertOutputDoesNotContain("TestCleanup completed"); - } - - [TestMethod] - [Ignore("Move to a different project")] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenTestMethodTimeoutExpires_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["TASKDELAY_TESTMETHOD"] = "1" }); - - testHostResult.AssertOutputContains("TestMethod started"); - testHostResult.AssertOutputContains("Test 'TestMethod' execution has been aborted."); - testHostResult.AssertOutputDoesNotContain("TestMethod completed"); - } - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenAssemblyInitTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["CHECKTOKEN_ASSEMBLYINIT"] = "1" }); - - testHostResult.AssertOutputContains("AssemblyInit started"); - testHostResult.AssertOutputContains("Assembly initialize method 'TestClass.AssemblyInit' timed out after 100ms"); - testHostResult.AssertOutputContains("AssemblyInit Thread.Sleep completed"); - testHostResult.AssertOutputDoesNotContain("AssemblyInit completed"); - } - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenAssemblyCleanupTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["CHECKTOKEN_ASSEMBLYCLEANUP"] = "1" }); - - testHostResult.AssertOutputContains("AssemblyCleanup started"); - testHostResult.AssertOutputContains("AssemblyCleanup Thread.Sleep completed"); - testHostResult.AssertOutputContains("Assembly cleanup method 'TestClass.AssemblyCleanup' timed out after 100ms"); - testHostResult.AssertOutputDoesNotContain("AssemblyCleanup completed"); - } - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenClassInitTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["CHECKTOKEN_CLASSINIT"] = "1" }); - - testHostResult.AssertOutputContains("ClassInit started"); - testHostResult.AssertOutputContains("Class initialize method 'TestClass.ClassInit' timed out after 100ms"); - testHostResult.AssertOutputContains("ClassInit Thread.Sleep completed"); - testHostResult.AssertOutputDoesNotContain("ClassInit completed"); - } - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenClassCleanupTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["CHECKTOKEN_CLASSCLEANUP"] = "1" }); - - testHostResult.AssertOutputContains("ClassCleanup started"); - testHostResult.AssertOutputContains("ClassCleanup Thread.Sleep completed"); - testHostResult.AssertOutputContains("Class cleanup method 'TestClass.ClassCleanup' timed out after 100ms"); - testHostResult.AssertOutputDoesNotContain("ClassCleanup completed"); - } - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenTestInitTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["CHECKTOKEN_TESTINIT"] = "1" }); - - testHostResult.AssertOutputContains("TestInit started"); - testHostResult.AssertOutputDoesNotContain("TestInit completed"); - testHostResult.AssertOutputContains("Test initialize method 'TestClass.TestInit' timed out after 100ms"); - } - - [TestMethod] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenTestCleanupTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["CHECKTOKEN_TESTCLEANUP"] = "1" }); - - testHostResult.AssertOutputContains("TestCleanup started"); - testHostResult.AssertOutputDoesNotContain("TestCleanup completed"); - testHostResult.AssertOutputContains("Test cleanup method 'TestClass.TestCleanup' timed out after 100ms"); - } - - [TestMethod] - [Ignore("Move to a different project")] - [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] - public async Task CooperativeCancellation_WhenTestMethodTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) - { - var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync( - "--settings my.runsettings", - new() { ["CHECKTOKEN_TESTMETHOD"] = "1" }); - - testHostResult.AssertOutputContains("TestMethod started"); - testHostResult.AssertOutputContains("Test 'TestMethod' execution has been aborted."); - } - - private async Task RunAndAssertTestWasCanceledAsync(string rootFolder, string assetName, string tfm, string envVarPrefix, string entryKind) - { - var testHost = TestHost.LocateFrom(rootFolder, assetName, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { { envVarPrefix + InfoByKind[entryKind].EnvVarSuffix, "1" } }); - testHostResult.AssertOutputContains($"{InfoByKind[entryKind].Prefix} method '{InfoByKind[entryKind].MethodFullName}' was canceled"); - } - - private async Task RunAndAssertTestTimedOutAsync(string rootFolder, string assetName, string tfm, string envVarPrefix, string entryKind) - { - var testHost = TestHost.LocateFrom(rootFolder, assetName, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { { envVarPrefix + InfoByKind[entryKind].EnvVarSuffix, "1" } }); - testHostResult.AssertOutputContains($"{InfoByKind[entryKind].Prefix} method '{InfoByKind[entryKind].MethodFullName}' timed out after 1000ms"); - } - - private async Task RunAndAssertWithRunSettingsAsync(string tfm, int timeoutValue, bool assertAttributePrecedence, string entryKind) - { - string runSettingsEntry = InfoByKind[entryKind].RunSettingsEntryName; - string runSettings = $""" - - - - - - <{runSettingsEntry}>{timeoutValue} - - -"""; - - // if assertAttributePrecedence is set we will use CodeWithOneSecTimeoutAssetPath - timeoutValue = assertAttributePrecedence ? 1000 : timeoutValue; - - TestHost testHost = assertAttributePrecedence - ? TestHost.LocateFrom(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm) - : TestHost.LocateFrom(AssetFixture.CodeWithNoTimeoutAssetPath, TestAssetFixture.CodeWithNoTimeout, tfm); - string runSettingsFilePath = Path.Combine(testHost.DirectoryName, $"{Guid.NewGuid():N}.runsettings"); - File.WriteAllText(runSettingsFilePath, runSettings); - - var stopwatch = Stopwatch.StartNew(); - TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { { $"TIMEOUT_{InfoByKind[entryKind].EnvVarSuffix}", "1" } }); - stopwatch.Stop(); - - if (assertAttributePrecedence) - { - Assert.IsTrue(stopwatch.Elapsed.TotalSeconds < 25); - } - - testHostResult.AssertOutputContains($"{InfoByKind[entryKind].Prefix} method '{InfoByKind[entryKind].MethodFullName}' timed out after {timeoutValue}ms"); - } - - public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) - { - public const string CodeWithOneSecTimeout = nameof(CodeWithOneSecTimeout); - public const string CodeWithSixtySecTimeout = nameof(CodeWithSixtySecTimeout); - public const string CodeWithNoTimeout = nameof(CodeWithNoTimeout); - public const string CooperativeTimeout = nameof(CooperativeTimeout); - - private const string CooperativeTimeoutSourceCode = """ -#file $ProjectName$.csproj - - - - Exe - true - $TargetFrameworks$ - - - - - - - - - - PreserveNewest - - - - - -#file my.runsettings - - - false - - - -#file UnitTest1.cs -using System; -using System.Threading.Tasks; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -[TestClass] -public class TestClass -{ - [Timeout(100, CooperativeCancellation = true)] - [AssemblyInitialize] - public static async Task AssemblyInit(TestContext testContext) - => await DoWork("ASSEMBLYINIT", "AssemblyInit", testContext); - - [Timeout(100, CooperativeCancellation = true)] - [AssemblyCleanup] - public static async Task AssemblyCleanup(TestContext testContext) - => await DoWork("ASSEMBLYCLEANUP", "AssemblyCleanup", testContext); - - [Timeout(100, CooperativeCancellation = true)] - [ClassInitialize] - public static async Task ClassInit(TestContext testContext) - => await DoWork("CLASSINIT", "ClassInit", testContext); - - [Timeout(100, CooperativeCancellation = true)] - [ClassCleanup(ClassCleanupBehavior.EndOfClass)] - public static async Task ClassCleanup(TestContext testContext) - => await DoWork("CLASSCLEANUP", "ClassCleanup", testContext); - - public TestContext TestContext { get; set; } - - [Timeout(100, CooperativeCancellation = true)] - [TestInitialize] - public async Task TestInit() - => await DoWork("TESTINIT", "TestInit", TestContext); - - [Timeout(100, CooperativeCancellation = true)] - [TestCleanup] - public async Task TestCleanup() - => await DoWork("TESTCLEANUP", "TestCleanup", TestContext); - - [TestMethod] - public async Task TestMethod() - { - } - - private static async Task DoWork(string envVarSuffix, string stepName, TestContext testContext) - { - Console.WriteLine($"{stepName} started"); - - if (Environment.GetEnvironmentVariable($"TASKDELAY_{envVarSuffix}") == "1") - { - await Task.Delay(10_000, testContext.CancellationTokenSource.Token); - } - else - { - System.Threading.Thread.Sleep(200); - Console.WriteLine($"{stepName} Thread.Sleep completed"); - if (Environment.GetEnvironmentVariable($"CHECKTOKEN_{envVarSuffix}") == "1") - { - testContext.CancellationTokenSource.Token.ThrowIfCancellationRequested(); - } - - } - - Console.WriteLine($"{stepName} completed"); - } -} -"""; - - private const string SourceCode = """ -#file $ProjectName$.csproj - - - - Exe - true - $TargetFrameworks$ - - - - - - - - - -#file UnitTest1.cs - -using System; -using System.Threading.Tasks; -using Microsoft.VisualStudio.TestTools.UnitTesting; - -public class TestClassBase -{ - $TimeoutAttribute$ - [ClassInitialize(inheritanceBehavior: InheritanceBehavior.BeforeEachDerivedClass)] - public static async Task ClassInitBase(TestContext testContext) - { - if (Environment.GetEnvironmentVariable("TESTCONTEXT_CANCEL_BASE_CLASSINIT") == "1") - { - testContext.CancellationTokenSource.Cancel(); - await Task.Delay(10_000); - } - else if (Environment.GetEnvironmentVariable("LONG_WAIT_BASE_CLASSINIT") == "1") - { - await Task.Delay(10_000); - } - else if (Environment.GetEnvironmentVariable("TIMEOUT_BASE_CLASSINIT") == "1") - { - await Task.Delay(10_000, testContext.CancellationTokenSource.Token); - } - else - { - await Task.CompletedTask; - } - } - - $TimeoutAttribute$ - [ClassCleanup(inheritanceBehavior: InheritanceBehavior.BeforeEachDerivedClass)] - public static async Task ClassCleanupBase() - { - if (Environment.GetEnvironmentVariable("LONG_WAIT_BASE_CLASSCLEANUP") == "1" || Environment.GetEnvironmentVariable("TIMEOUT_BASE_CLASSCLEANUP") == "1") - { - await Task.Delay(10_000); - } - else - { - await Task.CompletedTask; - } - } - -} - -[TestClass] -public class TestClass : TestClassBase -{ - $TimeoutAttribute$ - [AssemblyInitialize] - public static async Task AssemblyInit(TestContext testContext) - { - if (Environment.GetEnvironmentVariable("TESTCONTEXT_CANCEL_ASSEMBLYINIT") == "1") - { - testContext.CancellationTokenSource.Cancel(); - await Task.Delay(10_000); - } - else if (Environment.GetEnvironmentVariable("LONG_WAIT_ASSEMBLYINIT") == "1") - { - await Task.Delay(10_000); - } - else if (Environment.GetEnvironmentVariable("TIMEOUT_ASSEMBLYINIT") == "1") - { - await Task.Delay(60_000, testContext.CancellationTokenSource.Token); - } - else - { - await Task.CompletedTask; - } - } - - $TimeoutAttribute$ - [AssemblyCleanup] - public static async Task AssemblyCleanupMethod() - { - if (Environment.GetEnvironmentVariable("LONG_WAIT_ASSEMBLYCLEANUP") == "1" || Environment.GetEnvironmentVariable("TIMEOUT_ASSEMBLYCLEANUP") == "1") - { - await Task.Delay(10_000); - } - else - { - await Task.CompletedTask; - } - } - - $TimeoutAttribute$ - [ClassInitialize] - public static async Task ClassInit(TestContext testContext) - { - if (Environment.GetEnvironmentVariable("TESTCONTEXT_CANCEL_CLASSINIT") == "1") - { - testContext.CancellationTokenSource.Cancel(); - await Task.Delay(10_000); - } - else if (Environment.GetEnvironmentVariable("LONG_WAIT_CLASSINIT") == "1") - { - await Task.Delay(10_000); - } - else if (Environment.GetEnvironmentVariable("TIMEOUT_CLASSINIT") == "1") - { - await Task.Delay(60_000, testContext.CancellationTokenSource.Token); - } - else - { - await Task.CompletedTask; - } - } - - $TimeoutAttribute$ - [ClassCleanup] - public static async Task ClassCleanupMethod() - { - if (Environment.GetEnvironmentVariable("LONG_WAIT_CLASSCLEANUP") == "1" || Environment.GetEnvironmentVariable("TIMEOUT_CLASSCLEANUP") == "1") - { - await Task.Delay(10_000); - } - else - { - await Task.CompletedTask; - } - } - - $TimeoutAttribute$ - [TestInitialize] - public async Task TestInit() - { - if (Environment.GetEnvironmentVariable("LONG_WAIT_TESTINIT") == "1" || Environment.GetEnvironmentVariable("TIMEOUT_TESTINIT") == "1") - { - await Task.Delay(10_000); - } - else - { - await Task.CompletedTask; - } - } - - $TimeoutAttribute$ - [TestCleanup] - public async Task TestCleanupMethod() - { - if (Environment.GetEnvironmentVariable("LONG_WAIT_TESTCLEANUP") == "1" || Environment.GetEnvironmentVariable("TIMEOUT_TESTCLEANUP") == "1") - { - await Task.Delay(10_000); - } - else - { - await Task.CompletedTask; - } - } - - [TestMethod] - public Task Test1() => Task.CompletedTask; -} -"""; - - public string CodeWithOneSecTimeoutAssetPath => GetAssetPath(CodeWithOneSecTimeout); - - public string CodeWithSixtySecTimeoutAssetPath => GetAssetPath(CodeWithSixtySecTimeout); - - public string CodeWithNoTimeoutAssetPath => GetAssetPath(CodeWithNoTimeout); - - public string CooperativeTimeoutAssetPath => GetAssetPath(CooperativeTimeout); - - public override IEnumerable<(string ID, string Name, string Code)> GetAssetsToGenerate() - { - yield return (CodeWithNoTimeout, CodeWithNoTimeout, - SourceCode - .PatchCodeWithReplace("$TimeoutAttribute$", string.Empty) - .PatchCodeWithReplace("$ProjectName$", CodeWithNoTimeout) - .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); - - yield return (CodeWithOneSecTimeout, CodeWithOneSecTimeout, - SourceCode - .PatchCodeWithReplace("$TimeoutAttribute$", "[Timeout(1000)]") - .PatchCodeWithReplace("$ProjectName$", CodeWithOneSecTimeout) - .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); - - yield return (CodeWithSixtySecTimeout, CodeWithSixtySecTimeout, - SourceCode - .PatchCodeWithReplace("$TimeoutAttribute$", "[Timeout(60000)]") - .PatchCodeWithReplace("$ProjectName$", CodeWithSixtySecTimeout) - .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); - - yield return (CooperativeTimeout, CooperativeTimeout, - CooperativeTimeoutSourceCode - .PatchCodeWithReplace("$ProjectName$", CooperativeTimeout) - .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); - } - } -} diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs index 59a05bfe2f..3e289d95de 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs @@ -10,6 +10,407 @@ namespace MSTest.Acceptance.IntegrationTests; [TestClass] public class TimeoutTests : AcceptanceTestBase { + private static readonly Dictionary InfoByKind = new() + { + ["assemblyInit"] = ("TestClass.AssemblyInit", "Assembly initialize", "ASSEMBLYINIT", "AssemblyInitializeTimeout"), + ["assemblyCleanup"] = ("TestClass.AssemblyCleanupMethod", "Assembly cleanup", "ASSEMBLYCLEANUP", "AssemblyCleanupTimeout"), + ["classInit"] = ("TestClass.ClassInit", "Class initialize", "CLASSINIT", "ClassInitializeTimeout"), + ["baseClassInit"] = ("TestClassBase.ClassInitBase", "Class initialize", "BASE_CLASSINIT", "ClassInitializeTimeout"), + ["classCleanup"] = ("TestClass.ClassCleanupMethod", "Class cleanup", "CLASSCLEANUP", "ClassCleanupTimeout"), + ["baseClassCleanup"] = ("TestClassBase.ClassCleanupBase", "Class cleanup", "BASE_CLASSCLEANUP", "ClassCleanupTimeout"), + ["testInit"] = ("TestClass.TestInit", "Test initialize", "TESTINIT", "TestInitializeTimeout"), + ["testCleanup"] = ("TestClass.TestCleanupMethod", "Test cleanup", "TESTCLEANUP", "TestCleanupTimeout"), + }; + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task AssemblyInit_WhenTestContextCanceled_AssemblyInitializeTaskIsCanceled(string tfm) + => await RunAndAssertTestWasCanceledAsync(AssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, + tfm, "TESTCONTEXT_CANCEL_", "assemblyInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task AssemblyInit_WhenTimeoutExpires_AssemblyInitializeTaskIsCanceled(string tfm) + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, + tfm, "LONG_WAIT_", "assemblyInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task AssemblyInit_WhenTimeoutExpiresAndTestContextTokenIsUsed_AssemblyInitializeExits(string tfm) + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + "TIMEOUT_", "assemblyInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassInit_WhenTestContextCanceled_ClassInitializeTaskIsCanceled(string tfm) + => await RunAndAssertTestWasCanceledAsync(AssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, tfm, + "TESTCONTEXT_CANCEL_", "classInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassInit_WhenTimeoutExpires_ClassInitializeTaskIsCanceled(string tfm) + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + "LONG_WAIT_", "classInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassInit_WhenTimeoutExpiresAndTestContextTokenIsUsed_ClassInitializeExits(string tfm) + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + "TIMEOUT_", "classInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassInitBase_WhenTestContextCanceled_ClassInitializeTaskIsCanceled(string tfm) + => await RunAndAssertTestWasCanceledAsync(AssetFixture.CodeWithSixtySecTimeoutAssetPath, TestAssetFixture.CodeWithSixtySecTimeout, tfm, + "TESTCONTEXT_CANCEL_", "baseClassInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassInitBase_WhenTimeoutExpires_ClassInitializeTaskIsCanceled(string tfm) + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + "LONG_WAIT_", "baseClassInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassInitBase_WhenTimeoutExpiresAndTestContextTokenIsUsed_ClassInitializeExits(string tfm) + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + "TIMEOUT_", "baseClassInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task AssemblyInitialize_WhenTimeoutExpires_FromRunSettings_AssemblyInitializeIsCanceled(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "assemblyInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassInitialize_WhenTimeoutExpires_FromRunSettings_ClassInitializeIsCanceled(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "classInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task BaseClassInitialize_WhenTimeoutExpires_FromRunSettings_ClassInitializeIsCanceled(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "baseClassInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task AssemblyInitialize_WhenTimeoutExpires_AssemblyInitializeIsCanceled_AttributeTakesPrecedence(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "assemblyInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassInitialize_WhenTimeoutExpires_ClassInitializeIsCanceled_AttributeTakesPrecedence(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "classInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task BaseClassInitialize_WhenTimeoutExpires_ClassInitializeIsCanceled_AttributeTakesPrecedence(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "baseClassInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassCleanupBase_WhenTimeoutExpires_ClassCleanupTaskIsCanceled(string tfm) + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + "LONG_WAIT_", "baseClassCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassCleanup_WhenTimeoutExpires_ClassCleanupTaskIsCanceled(string tfm) + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + "LONG_WAIT_", "classCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassCleanup_WhenTimeoutExpires_FromRunSettings_ClassCleanupIsCanceled(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "classCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task BaseClassCleanup_WhenTimeoutExpires_FromRunSettings_ClassCleanupIsCanceled(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "baseClassCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task ClassCleanup_WhenTimeoutExpires_ClassCleanupIsCanceled_AttributeTakesPrecedence(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "classCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task BaseClassCleanup_WhenTimeoutExpires_ClassCleanupIsCanceled_AttributeTakesPrecedence(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "baseClassCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task AssemblyCleanup_WhenTimeoutExpires_AssemblyCleanupTaskIsCanceled(string tfm) + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + "LONG_WAIT_", "assemblyCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task AssemblyCleanup_WhenTimeoutExpires_FromRunSettings_AssemblyCleanupIsCanceled(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "assemblyCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task AssemblyCleanup_WhenTimeoutExpires_AssemblyCleanupIsCanceled_AttributeTakesPrecedence(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "assemblyCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task TestInitialize_WhenTimeoutExpires_TestInitializeTaskIsCanceled(string tfm) + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + "LONG_WAIT_", "testInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task TestInitialize_WhenTimeoutExpires_FromRunSettings_TestInitializeIsCanceled(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "testInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task TestInitialize_WhenTimeoutExpires_TestInitializeIsCanceled_AttributeTakesPrecedence(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "testInit"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task TestCleanup_WhenTimeoutExpires_TestCleanupTaskIsCanceled(string tfm) + => await RunAndAssertTestTimedOutAsync(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm, + "LONG_WAIT_", "testCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task TestCleanup_WhenTimeoutExpires_FromRunSettings_TestCleanupIsCanceled(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 300, false, "testCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task TestCleanup_WhenTimeoutExpires_TestCleanupIsCanceled_AttributeTakesPrecedence(string tfm) + => await RunAndAssertWithRunSettingsAsync(tfm, 25000, true, "testCleanup"); + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenAssemblyInitTimeoutExpires_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["TASKDELAY_ASSEMBLYINIT"] = "1" }); + + testHostResult.AssertOutputContains("AssemblyInit started"); + testHostResult.AssertOutputContains("Assembly initialize method 'TestClass.AssemblyInit' timed out after 1000ms"); + testHostResult.AssertOutputDoesNotContain("AssemblyInit Thread.Sleep completed"); + testHostResult.AssertOutputDoesNotContain("AssemblyInit completed"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenAssemblyCleanupTimeoutExpires_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["TASKDELAY_ASSEMBLYCLEANUP"] = "1" }); + + testHostResult.AssertOutputContains("AssemblyCleanup started"); + testHostResult.AssertOutputContains("Assembly cleanup method 'TestClass.AssemblyCleanup' timed out after 1000ms"); + testHostResult.AssertOutputDoesNotContain("AssemblyCleanup Thread.Sleep completed"); + testHostResult.AssertOutputDoesNotContain("AssemblyCleanup completed"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenClassInitTimeoutExpires_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["TASKDELAY_CLASSINIT"] = "1" }); + + testHostResult.AssertOutputContains("ClassInit started"); + testHostResult.AssertOutputContains("Class initialize method 'TestClass.ClassInit' timed out after 1000ms"); + testHostResult.AssertOutputDoesNotContain("ClassInit Thread.Sleep completed"); + testHostResult.AssertOutputDoesNotContain("ClassInit completed"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenClassCleanupTimeoutExpires_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["TASKDELAY_CLASSCLEANUP"] = "1" }); + + testHostResult.AssertOutputContains("ClassCleanup started"); + testHostResult.AssertOutputContains("Class cleanup method 'TestClass.ClassCleanup' timed out after 1000ms"); + testHostResult.AssertOutputDoesNotContain("ClassCleanup Thread.Sleep completed"); + testHostResult.AssertOutputDoesNotContain("ClassCleanup completed"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenTestInitTimeoutExpires_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["TASKDELAY_TESTINIT"] = "1" }); + + testHostResult.AssertOutputContains("TestInit started"); + testHostResult.AssertOutputContains("Test initialize method 'TestClass.TestInit' timed out after 1000ms"); + testHostResult.AssertOutputDoesNotContain("TestInit completed"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenTestCleanupTimeoutExpires_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["TASKDELAY_TESTCLEANUP"] = "1" }); + + testHostResult.AssertOutputContains("TestCleanup started"); + testHostResult.AssertOutputContains("Test cleanup method 'TestClass.TestCleanup' timed out after 1000ms"); + testHostResult.AssertOutputDoesNotContain("TestCleanup completed"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenAssemblyInitTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["CHECKTOKEN_ASSEMBLYINIT"] = "1" }); + + testHostResult.AssertOutputContains("AssemblyInit started"); + testHostResult.AssertOutputContains("Assembly initialize method 'TestClass.AssemblyInit' timed out after 1000ms"); + testHostResult.AssertOutputContains("AssemblyInit Thread.Sleep completed"); + testHostResult.AssertOutputDoesNotContain("AssemblyInit completed"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenAssemblyCleanupTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["CHECKTOKEN_ASSEMBLYCLEANUP"] = "1" }); + + testHostResult.AssertOutputContains("AssemblyCleanup started"); + testHostResult.AssertOutputContains("AssemblyCleanup Thread.Sleep completed"); + testHostResult.AssertOutputContains("Assembly cleanup method 'TestClass.AssemblyCleanup' timed out after 1000ms"); + testHostResult.AssertOutputDoesNotContain("AssemblyCleanup completed"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenClassInitTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["CHECKTOKEN_CLASSINIT"] = "1" }); + + testHostResult.AssertOutputContains("ClassInit started"); + testHostResult.AssertOutputContains("Class initialize method 'TestClass.ClassInit' timed out after 1000ms"); + testHostResult.AssertOutputContains("ClassInit Thread.Sleep completed"); + testHostResult.AssertOutputDoesNotContain("ClassInit completed"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenClassCleanupTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["CHECKTOKEN_CLASSCLEANUP"] = "1" }); + + testHostResult.AssertOutputContains("ClassCleanup started"); + testHostResult.AssertOutputContains("ClassCleanup Thread.Sleep completed"); + testHostResult.AssertOutputContains("Class cleanup method 'TestClass.ClassCleanup' timed out after 1000ms"); + testHostResult.AssertOutputDoesNotContain("ClassCleanup completed"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenTestInitTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["CHECKTOKEN_TESTINIT"] = "1" }); + + testHostResult.AssertOutputContains("TestInit started"); + testHostResult.AssertOutputDoesNotContain("TestInit completed"); + testHostResult.AssertOutputContains("Test initialize method 'TestClass.TestInit' timed out after 1000ms"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeCancellation_WhenTestCleanupTimeoutExpiresAndUserChecksToken_StepThrows(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTimeoutAssetPath, TestAssetFixture.CooperativeTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync( + "--settings my.runsettings", + new() { ["CHECKTOKEN_TESTCLEANUP"] = "1" }); + + testHostResult.AssertOutputContains("TestCleanup started"); + testHostResult.AssertOutputDoesNotContain("TestCleanup completed"); + testHostResult.AssertOutputContains("Test cleanup method 'TestClass.TestCleanup' timed out after 1000ms"); + } + + private async Task RunAndAssertTestWasCanceledAsync(string rootFolder, string assetName, string tfm, string envVarPrefix, string entryKind) + { + var testHost = TestHost.LocateFrom(rootFolder, assetName, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { { envVarPrefix + InfoByKind[entryKind].EnvVarSuffix, "1" } }); + testHostResult.AssertOutputContains($"{InfoByKind[entryKind].Prefix} method '{InfoByKind[entryKind].MethodFullName}' was canceled"); + } + + private async Task RunAndAssertTestTimedOutAsync(string rootFolder, string assetName, string tfm, string envVarPrefix, string entryKind) + { + var testHost = TestHost.LocateFrom(rootFolder, assetName, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { { envVarPrefix + InfoByKind[entryKind].EnvVarSuffix, "1" } }); + testHostResult.AssertOutputContains($"{InfoByKind[entryKind].Prefix} method '{InfoByKind[entryKind].MethodFullName}' timed out after 1000ms"); + } + + private async Task RunAndAssertWithRunSettingsAsync(string tfm, int timeoutValue, bool assertAttributePrecedence, string entryKind) + { + string runSettingsEntry = InfoByKind[entryKind].RunSettingsEntryName; + string runSettings = $""" + + + + + + <{runSettingsEntry}>{timeoutValue} + + +"""; + + // if assertAttributePrecedence is set we will use CodeWithOneSecTimeoutAssetPath + timeoutValue = assertAttributePrecedence ? 1000 : timeoutValue; + + TestHost testHost = assertAttributePrecedence + ? TestHost.LocateFrom(AssetFixture.CodeWithOneSecTimeoutAssetPath, TestAssetFixture.CodeWithOneSecTimeout, tfm) + : TestHost.LocateFrom(AssetFixture.CodeWithNoTimeoutAssetPath, TestAssetFixture.CodeWithNoTimeout, tfm); + string runSettingsFilePath = Path.Combine(testHost.DirectoryName, $"{Guid.NewGuid():N}.runsettings"); + File.WriteAllText(runSettingsFilePath, runSettings); + + var stopwatch = Stopwatch.StartNew(); + TestHostResult testHostResult = await testHost.ExecuteAsync($"--settings {runSettingsFilePath}", environmentVariables: new() { { $"TIMEOUT_{InfoByKind[entryKind].EnvVarSuffix}", "1" } }); + stopwatch.Stop(); + + if (assertAttributePrecedence) + { + Assert.IsTrue(stopwatch.Elapsed.TotalSeconds < 25); + } + + testHostResult.AssertOutputContains($"{InfoByKind[entryKind].Prefix} method '{InfoByKind[entryKind].MethodFullName}' timed out after {timeoutValue}ms"); + } + [TestMethod] [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] public async Task TimeoutWithInvalidArg_WithoutLetterSuffix_OutputInvalidMessage(string tfm) @@ -66,9 +467,127 @@ public async Task Timeout_WhenTimeoutValueGreaterThanTestDuration_OutputDoesNotC testHostResult.AssertOutputDoesNotContain("Canceling the test session"); } + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task Timeout_WhenMethodTimeoutAndWaitInCtor_TestGetsCanceled(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.TestMethodTimeoutAssetPath, TestAssetFixture.TestMethodTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() + { + ["LONG_WAIT_CTOR"] = "1", + }); + + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContains("Test 'TestMethod' timed out after 1000ms"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task Timeout_WhenMethodTimeoutAndWaitInTestInit_TestGetsCanceled(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.TestMethodTimeoutAssetPath, TestAssetFixture.TestMethodTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() + { + ["LONG_WAIT_TESTINIT"] = "1", + }); + + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContains("Test 'TestMethod' timed out after 1000ms"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task Timeout_WhenMethodTimeoutAndWaitInTestCleanup_TestGetsCanceled(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.TestMethodTimeoutAssetPath, TestAssetFixture.TestMethodTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() + { + ["LONG_WAIT_TESTCLEANUP"] = "1", + }); + + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContains("Test 'TestMethod' timed out after 1000ms"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task Timeout_WhenMethodTimeoutAndWaitInTestMethod_TestGetsCanceled(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.TestMethodTimeoutAssetPath, TestAssetFixture.TestMethodTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() + { + ["LONG_WAIT_TEST"] = "1", + }); + + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContains("Test 'TestMethod' timed out after 1000ms"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeTimeout_WhenMethodTimeoutAndWaitInCtor_TestGetsCanceled(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTestMethodTimeoutAssetPath, TestAssetFixture.CooperativeTestMethodTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() + { + ["LONG_WAIT_CTOR"] = "1", + }); + + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContains("Test 'TestMethod' timed out after 1000ms"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeTimeout_WhenMethodTimeoutAndWaitInTestInit_TestGetsCanceled(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTestMethodTimeoutAssetPath, TestAssetFixture.CooperativeTestMethodTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() + { + ["LONG_WAIT_TESTINIT"] = "1", + }); + + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContains("Test initialize method 'TimeoutTest.UnitTest1.TestInit' timed out after 1000ms"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeTimeout_WhenMethodTimeoutAndWaitInTestCleanup_TestGetsCanceled(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTestMethodTimeoutAssetPath, TestAssetFixture.CooperativeTestMethodTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() + { + ["LONG_WAIT_TESTCLEANUP"] = "1", + }); + + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContains("Test cleanup method 'TimeoutTest.UnitTest1.TestCleanup' timed out after 1000ms"); + } + + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task CooperativeTimeout_WhenMethodTimeoutAndWaitInTestMethod_TestGetsCanceled(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.CooperativeTestMethodTimeoutAssetPath, TestAssetFixture.CooperativeTestMethodTimeout, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() + { + ["LONG_WAIT_TEST"] = "1", + }); + + testHostResult.AssertExitCodeIs(ExitCodes.AtLeastOneTestFailed); + testHostResult.AssertOutputContains("Test 'TestMethod' timed out after 1000ms"); + } + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string AssetName = "TimeoutTest"; + public const string CodeWithOneSecTimeout = nameof(CodeWithOneSecTimeout); + public const string CodeWithSixtySecTimeout = nameof(CodeWithSixtySecTimeout); + public const string CodeWithNoTimeout = nameof(CodeWithNoTimeout); + public const string CooperativeTimeout = nameof(CooperativeTimeout); + public const string TestMethodTimeout = nameof(TestMethodTimeout); + public const string CooperativeTestMethodTimeout = nameof(CooperativeTestMethodTimeout); private const string TestCode = """ #file TimeoutTest.csproj @@ -102,16 +621,407 @@ public void TestA() Thread.Sleep(10000); } } +"""; + + private const string CooperativeTimeoutSourceCode = """ +#file $ProjectName$.csproj + + + + Exe + true + $TargetFrameworks$ + + + + + + + + + + PreserveNewest + + + + + +#file my.runsettings + + + false + + + +#file UnitTest1.cs +using System; +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[TestClass] +public class TestClass +{ + [Timeout(1000, CooperativeCancellation = true)] + [AssemblyInitialize] + public static async Task AssemblyInit(TestContext testContext) + => await DoWork("ASSEMBLYINIT", "AssemblyInit", testContext); + + [Timeout(1000, CooperativeCancellation = true)] + [AssemblyCleanup] + public static async Task AssemblyCleanup(TestContext testContext) + => await DoWork("ASSEMBLYCLEANUP", "AssemblyCleanup", testContext); + + [Timeout(1000, CooperativeCancellation = true)] + [ClassInitialize] + public static async Task ClassInit(TestContext testContext) + => await DoWork("CLASSINIT", "ClassInit", testContext); + + [Timeout(1000, CooperativeCancellation = true)] + [ClassCleanup(ClassCleanupBehavior.EndOfClass)] + public static async Task ClassCleanup(TestContext testContext) + => await DoWork("CLASSCLEANUP", "ClassCleanup", testContext); + + public TestContext TestContext { get; set; } + + [Timeout(1000, CooperativeCancellation = true)] + [TestInitialize] + public async Task TestInit() + => await DoWork("TESTINIT", "TestInit", TestContext); + + [Timeout(1000, CooperativeCancellation = true)] + [TestCleanup] + public async Task TestCleanup() + => await DoWork("TESTCLEANUP", "TestCleanup", TestContext); + + [TestMethod] + public void TestMethod() + { + } + + private static async Task DoWork(string envVarSuffix, string stepName, TestContext testContext) + { + Console.WriteLine($"{stepName} started"); + + if (Environment.GetEnvironmentVariable($"TASKDELAY_{envVarSuffix}") == "1") + { + await Task.Delay(10_000, testContext.CancellationTokenSource.Token); + } + else + { + // We want to wait more than the timeout value to ensure the timeout is hit + await Task.Delay(2_000); + Console.WriteLine($"{stepName} Thread.Sleep completed"); + if (Environment.GetEnvironmentVariable($"CHECKTOKEN_{envVarSuffix}") == "1") + { + testContext.CancellationTokenSource.Token.ThrowIfCancellationRequested(); + } + + } + + Console.WriteLine($"{stepName} completed"); + } +} +"""; + + private const string SourceCode = """ +#file $ProjectName$.csproj + + + + Exe + true + $TargetFrameworks$ + + + + + + + + + +#file UnitTest1.cs + +using System; +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +public class TestClassBase +{ + $TimeoutAttribute$ + [ClassInitialize(inheritanceBehavior: InheritanceBehavior.BeforeEachDerivedClass)] + public static async Task ClassInitBase(TestContext testContext) + { + if (Environment.GetEnvironmentVariable("TESTCONTEXT_CANCEL_BASE_CLASSINIT") == "1") + { + testContext.CancellationTokenSource.Cancel(); + await Task.Delay(10_000); + } + else if (Environment.GetEnvironmentVariable("LONG_WAIT_BASE_CLASSINIT") == "1") + { + await Task.Delay(10_000); + } + else if (Environment.GetEnvironmentVariable("TIMEOUT_BASE_CLASSINIT") == "1") + { + await Task.Delay(10_000, testContext.CancellationTokenSource.Token); + } + else + { + await Task.CompletedTask; + } + } + + $TimeoutAttribute$ + [ClassCleanup(inheritanceBehavior: InheritanceBehavior.BeforeEachDerivedClass)] + public static async Task ClassCleanupBase() + { + if (Environment.GetEnvironmentVariable("LONG_WAIT_BASE_CLASSCLEANUP") == "1" || Environment.GetEnvironmentVariable("TIMEOUT_BASE_CLASSCLEANUP") == "1") + { + await Task.Delay(10_000); + } + else + { + await Task.CompletedTask; + } + } + +} + +[TestClass] +public class TestClass : TestClassBase +{ + $TimeoutAttribute$ + [AssemblyInitialize] + public static async Task AssemblyInit(TestContext testContext) + { + if (Environment.GetEnvironmentVariable("TESTCONTEXT_CANCEL_ASSEMBLYINIT") == "1") + { + testContext.CancellationTokenSource.Cancel(); + await Task.Delay(10_000); + } + else if (Environment.GetEnvironmentVariable("LONG_WAIT_ASSEMBLYINIT") == "1") + { + await Task.Delay(10_000); + } + else if (Environment.GetEnvironmentVariable("TIMEOUT_ASSEMBLYINIT") == "1") + { + await Task.Delay(60_000, testContext.CancellationTokenSource.Token); + } + else + { + await Task.CompletedTask; + } + } + + $TimeoutAttribute$ + [AssemblyCleanup] + public static async Task AssemblyCleanupMethod() + { + if (Environment.GetEnvironmentVariable("LONG_WAIT_ASSEMBLYCLEANUP") == "1" || Environment.GetEnvironmentVariable("TIMEOUT_ASSEMBLYCLEANUP") == "1") + { + await Task.Delay(10_000); + } + else + { + await Task.CompletedTask; + } + } + + $TimeoutAttribute$ + [ClassInitialize] + public static async Task ClassInit(TestContext testContext) + { + if (Environment.GetEnvironmentVariable("TESTCONTEXT_CANCEL_CLASSINIT") == "1") + { + testContext.CancellationTokenSource.Cancel(); + await Task.Delay(10_000); + } + else if (Environment.GetEnvironmentVariable("LONG_WAIT_CLASSINIT") == "1") + { + await Task.Delay(10_000); + } + else if (Environment.GetEnvironmentVariable("TIMEOUT_CLASSINIT") == "1") + { + await Task.Delay(60_000, testContext.CancellationTokenSource.Token); + } + else + { + await Task.CompletedTask; + } + } + + $TimeoutAttribute$ + [ClassCleanup] + public static async Task ClassCleanupMethod() + { + if (Environment.GetEnvironmentVariable("LONG_WAIT_CLASSCLEANUP") == "1" || Environment.GetEnvironmentVariable("TIMEOUT_CLASSCLEANUP") == "1") + { + await Task.Delay(10_000); + } + else + { + await Task.CompletedTask; + } + } + + $TimeoutAttribute$ + [TestInitialize] + public async Task TestInit() + { + if (Environment.GetEnvironmentVariable("LONG_WAIT_TESTINIT") == "1" || Environment.GetEnvironmentVariable("TIMEOUT_TESTINIT") == "1") + { + await Task.Delay(10_000); + } + else + { + await Task.CompletedTask; + } + } + + $TimeoutAttribute$ + [TestCleanup] + public async Task TestCleanupMethod() + { + if (Environment.GetEnvironmentVariable("LONG_WAIT_TESTCLEANUP") == "1" || Environment.GetEnvironmentVariable("TIMEOUT_TESTCLEANUP") == "1") + { + await Task.Delay(10_000); + } + else + { + await Task.CompletedTask; + } + } + + [TestMethod] + public Task Test1() => Task.CompletedTask; +} +"""; + + private const string TestMethodTimeoutCode = """ +#file $ProjectName$.csproj + + + $TargetFrameworks$ + true + Exe + enable + preview + + + + + + +#file UnitTest1.cs +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.VisualStudio.TestTools.UnitTesting; +namespace TimeoutTest; +[TestClass] +public class UnitTest1 +{ + private readonly TestContext _testContext; + + public UnitTest1(TestContext testContext) + { + _testContext = testContext; + if (Environment.GetEnvironmentVariable("LONG_WAIT_CTOR") == "1") + { + Task.Delay(10_000, _testContext.CancellationTokenSource.Token).Wait(); + } + } + + [TestInitialize] + public async Task TestInit() + { + if (Environment.GetEnvironmentVariable("LONG_WAIT_TESTINIT") == "1") + { + await Task.Delay(10_000, _testContext.CancellationTokenSource.Token); + } + } + + [TestCleanup] + public async Task TestCleanup() + { + if (Environment.GetEnvironmentVariable("LONG_WAIT_TESTCLEANUP") == "1") + { + await Task.Delay(10_000, _testContext.CancellationTokenSource.Token); + } + } + + [TestMethod] + [Timeout(1000$TimeoutExtraArgs$)] + public async Task TestMethod() + { + if (Environment.GetEnvironmentVariable("LONG_WAIT_TEST") == "1") + { + await Task.Delay(10_000, _testContext.CancellationTokenSource.Token); + } + } +} """; public string NoExtensionTargetAssetPath => GetAssetPath(AssetName); + public string CodeWithOneSecTimeoutAssetPath => GetAssetPath(CodeWithOneSecTimeout); + + public string CodeWithSixtySecTimeoutAssetPath => GetAssetPath(CodeWithSixtySecTimeout); + + public string CodeWithNoTimeoutAssetPath => GetAssetPath(CodeWithNoTimeout); + + public string CooperativeTimeoutAssetPath => GetAssetPath(CooperativeTimeout); + + public string TestMethodTimeoutAssetPath => GetAssetPath(TestMethodTimeout); + + public string CooperativeTestMethodTimeoutAssetPath => GetAssetPath(CooperativeTestMethodTimeout); + public override IEnumerable<(string ID, string Name, string Code)> GetAssetsToGenerate() { yield return (AssetName, AssetName, TestCode .PatchTargetFrameworks(TargetFrameworks.All) - .PatchCodeWithReplace("$MicrosoftTestingPlatformVersion$", MicrosoftTestingPlatformVersion) + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); + + yield return (CodeWithNoTimeout, CodeWithNoTimeout, + SourceCode + .PatchCodeWithReplace("$TimeoutAttribute$", string.Empty) + .PatchCodeWithReplace("$ProjectName$", CodeWithNoTimeout) + .PatchTargetFrameworks(TargetFrameworks.All) + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); + + yield return (CodeWithOneSecTimeout, CodeWithOneSecTimeout, + SourceCode + .PatchCodeWithReplace("$TimeoutAttribute$", "[Timeout(1000)]") + .PatchCodeWithReplace("$ProjectName$", CodeWithOneSecTimeout) + .PatchTargetFrameworks(TargetFrameworks.All) + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); + + yield return (CodeWithSixtySecTimeout, CodeWithSixtySecTimeout, + SourceCode + .PatchCodeWithReplace("$TimeoutAttribute$", "[Timeout(60000)]") + .PatchCodeWithReplace("$ProjectName$", CodeWithSixtySecTimeout) + .PatchTargetFrameworks(TargetFrameworks.All) + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); + + yield return (CooperativeTimeout, CooperativeTimeout, + CooperativeTimeoutSourceCode + .PatchCodeWithReplace("$ProjectName$", CooperativeTimeout) + .PatchTargetFrameworks(TargetFrameworks.All) + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); + + yield return (TestMethodTimeout, TestMethodTimeout, + TestMethodTimeoutCode + .PatchTargetFrameworks(TargetFrameworks.All) + .PatchCodeWithReplace("$ProjectName$", TestMethodTimeout) + .PatchCodeWithReplace("$TimeoutExtraArgs$", string.Empty) + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); + + yield return (CooperativeTestMethodTimeout, CooperativeTestMethodTimeout, + TestMethodTimeoutCode + .PatchTargetFrameworks(TargetFrameworks.All) + .PatchCodeWithReplace("$ProjectName$", CooperativeTestMethodTimeout) + .PatchCodeWithReplace("$TimeoutExtraArgs$", ", CooperativeCancellation = true") .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); } } diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs index d9b7d08a8e..84fcb95c57 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs @@ -1272,7 +1272,7 @@ public void TestMethodInfoInvokeShouldReturnTestFailureOnTimeout() UTF.TestResult result = method.Invoke(null); Verify(result.Outcome == UTF.UnitTestOutcome.Timeout); - Verify(result.TestFailureException.Message.Contains("exceeded execution timeout period")); + Verify(result.TestFailureException.Message.Equals("Test 'DummyTestMethod' timed out after 1ms", StringComparison.Ordinal)); }); } @@ -1299,7 +1299,7 @@ public void TestMethodInfoInvokeShouldCancelTokenSourceOnTimeout() UTF.TestResult result = method.Invoke(null); Verify(result.Outcome == UTF.UnitTestOutcome.Timeout); - Verify(result.TestFailureException.Message.Contains("exceeded execution timeout period")); + Verify(result.TestFailureException.Message.Equals("Test 'DummyTestMethod' timed out after 1ms", StringComparison.Ordinal)); Verify(_testContextImplementation.CancellationTokenSource.IsCancellationRequested, "Not canceled.."); }); } @@ -1329,7 +1329,7 @@ public void TestMethodInfoInvokeShouldFailOnTokenSourceCancellation() UTF.TestResult result = method.Invoke(null); Verify(result.Outcome == UTF.UnitTestOutcome.Timeout); - Verify(result.TestFailureException.Message.Contains("execution has been aborted")); + Verify(result.TestFailureException.Message.Equals("Test 'DummyTestMethod' was canceled", StringComparison.Ordinal)); Verify(_testContextImplementation.CancellationTokenSource.IsCancellationRequested, "Not canceled.."); }); } From 438eec45fe16fec30c5a8223387dcdff1abdcce2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sat, 28 Dec 2024 15:41:31 +0100 Subject: [PATCH 190/273] Fix "Could not load file or assembly 'System.Runtime.CompilerServicesUnsafe'" (#4461) --- Directory.Packages.props | 5 +++-- .../MSTest.IntegrationTests/MSTest.IntegrationTests.csproj | 1 - .../Utilities/TestCaseFilterFactory.cs | 2 ++ .../MSTestAdapter.PlatformServices.UnitTests.csproj | 6 ++---- .../MSTestAdapter.UnitTests/MSTestAdapter.UnitTests.csproj | 1 + .../TestFramework.ForTestingMSTest.csproj | 4 ++++ 6 files changed, 12 insertions(+), 7 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index fb5512616f..dbb9c381ac 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -64,6 +64,7 @@ + @@ -79,7 +80,7 @@ - + diff --git a/eng/Versions.props b/eng/Versions.props index d38cff4451..4c02e9e431 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,6 +10,6 @@ 10.0.0-beta.24604.4 17.14.0-preview.24620.2 - 1.0.0-alpha.24619.2 + 1.0.0-alpha.24628.3 diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs index 6aefda6e22..ad84b6721b 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/NativeAotTests.cs @@ -83,7 +83,6 @@ public void TestMethod3(int a, int b) """; [TestMethod] - [Ignore("https://github.com/microsoft/testfx/issues/4369")] public async Task NativeAotTests_WillRunWithExitCodeZero() { // The hosted AzDO agents for Mac OS don't have the required tooling for us to test Native AOT. From 549f7d9b33a74bb55095c69b87e5d917710b736d Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sun, 29 Dec 2024 20:37:39 +1100 Subject: [PATCH 193/273] remove redundant null check in ComputeStringHash (#4420) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../Helpers/FNV1HashHelper.cs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/Helpers/FNV1HashHelper.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/Helpers/FNV1HashHelper.cs index 6063f65d9d..c25bfbbfab 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HangDump/Helpers/FNV1HashHelper.cs +++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/Helpers/FNV1HashHelper.cs @@ -10,20 +10,6 @@ internal static class FNV_1aHashHelper /// Computes a hash of the string using the FNV-1a algorithm. /// Used by Roslyn. /// - public static uint ComputeStringHash(string s) - { - uint num = default; - if (s != null) - { - num = 2166136261u; - int num2 = 0; - while (num2 < s.Length) - { - num = (s[num2] ^ num) * 16777619; - num2++; - } - } - - return num; - } + public static uint ComputeStringHash(string input) => + input.Aggregate(2166136261u, (current, ch) => (ch ^ current) * 16777619); } From c743f67d7788673e13a3c2d84824b89dfd75c119 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 29 Dec 2024 11:04:47 +0100 Subject: [PATCH 194/273] Hide DataTestMethodAttribute from IntelliSense (#4465) --- .../Attributes/DataSource/DataTestMethodAttribute.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DataTestMethodAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DataTestMethodAttribute.cs index 7ccc26126a..9232c36f59 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DataTestMethodAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DataTestMethodAttribute.cs @@ -1,6 +1,8 @@ // 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.ComponentModel; + namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// @@ -8,6 +10,7 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// present for backward compatibility. Using is recommended, even for parameterized tests. /// [AttributeUsage(AttributeTargets.Method)] +[EditorBrowsable(EditorBrowsableState.Never)] public class DataTestMethodAttribute : TestMethodAttribute { /// From 56cacddf84e734074420819fa1f300fd77afe33e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Sun, 29 Dec 2024 12:10:44 +0100 Subject: [PATCH 195/273] Refactor running of data driven tests (#4466) --- .../Execution/TestMethodRunner.cs | 235 ++++++++++-------- 1 file changed, 125 insertions(+), 110 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs index a3ee59fa98..562bb7376e 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs @@ -161,43 +161,54 @@ internal UnitTestResult[] RunTestMethod() DebugEx.Assert(_testMethodInfo.TestMethod != null, "Test method should not be null."); List results = []; - bool isDataDriven = false; - var parentStopwatch = Stopwatch.StartNew(); - - if (_testMethodInfo.TestMethodOptions.Executor != null) + if (_testMethodInfo.TestMethodOptions.Executor == null) { - if (_test.DataType == DynamicDataType.ITestDataSource) - { - object?[]? data = DataSerializationHelper.Deserialize(_test.SerializedData); - TestResult[] testResults = ExecuteTestWithDataSource(null, data); - results.AddRange(testResults); - } - else if (ExecuteDataSourceBasedTests(results)) - { - isDataDriven = true; - } - else + PlatformServiceProvider.Instance.AdapterTraceLogger.LogError( + "Not able to get executor for method {0}.{1}", + _testMethodInfo.TestClassName, + _testMethodInfo.TestMethodName); + + TestResult emptyResult = new() { - _testContext.SetDisplayName(_test.DisplayName); - TestResult[] testResults = ExecuteTest(_testMethodInfo); + Outcome = UTF.UnitTestOutcome.Unknown, + TestFailureException = new TestFailedException(UnitTestOutcome.Error, Resource.UTA_NoTestResult), + }; + _testContext.SetOutcome(emptyResult.Outcome); - foreach (TestResult testResult in testResults) - { - if (StringEx.IsNullOrWhiteSpace(testResult.DisplayName)) - { - testResult.DisplayName = _test.DisplayName; - } - } + results.Add(emptyResult); + return results.ToUnitTestResults(); + } - results.AddRange(testResults); - } + bool isDataDriven = false; + var parentStopwatch = Stopwatch.StartNew(); + if (_test.DataType == DynamicDataType.ITestDataSource) + { + object?[]? data = DataSerializationHelper.Deserialize(_test.SerializedData); + TestResult[] testResults = ExecuteTestWithDataSource(null, data); + results.AddRange(testResults); + } + else if (TryExecuteDataSourceBasedTests(results)) + { + isDataDriven = true; + } + else if (TryExecuteFoldedDataDrivenTests(results)) + { + isDataDriven = true; } else { - PlatformServiceProvider.Instance.AdapterTraceLogger.LogError( - "Not able to get executor for method {0}.{1}", - _testMethodInfo.TestClassName, - _testMethodInfo.TestMethodName); + _testContext.SetDisplayName(_test.DisplayName); + TestResult[] testResults = ExecuteTest(_testMethodInfo); + + foreach (TestResult testResult in testResults) + { + if (StringEx.IsNullOrWhiteSpace(testResult.DisplayName)) + { + testResult.DisplayName = _test.DisplayName; + } + } + + results.AddRange(testResults); } // Get aggregate outcome. @@ -210,6 +221,7 @@ internal UnitTestResult[] RunTestMethod() // In legacy scenario #pragma warning disable CS0618 // Type or member is obsolete if (_test.TestIdGenerationStrategy == TestIdGenerationStrategy.Legacy) +#pragma warning restore CS0618 // Type or member is obsolete { parentStopwatch.Stop(); var parentResult = new TestResult @@ -221,7 +233,6 @@ internal UnitTestResult[] RunTestMethod() results = UpdateResultsWithParentInfo(results, parentResult); } -#pragma warning restore CS0618 // Type or member is obsolete else { results = UpdateResultsWithParentInfo(results); @@ -243,108 +254,112 @@ internal UnitTestResult[] RunTestMethod() return results.ToUnitTestResults(); } - private bool ExecuteDataSourceBasedTests(List results) + private bool TryExecuteDataSourceBasedTests(List results) { - bool isDataDriven = false; - DataSourceAttribute[] dataSourceAttribute = _testMethodInfo.GetAttributes(false); if (dataSourceAttribute is { Length: 1 }) { - isDataDriven = true; - Stopwatch watch = new(); - watch.Start(); + ExecuteTestFromDataSourceAttribute(results); + return true; + } - try + return false; + } + + private bool TryExecuteFoldedDataDrivenTests(List results) + { + IEnumerable? testDataSources = _testMethodInfo.GetAttributes(false)?.OfType(); + if (testDataSources?.Any() != true) + { + return false; + } + + foreach (UTF.ITestDataSource testDataSource in testDataSources) + { + IEnumerable? dataSource; + + // This code is to execute tests. To discover the tests code is in AssemblyEnumerator.ProcessTestDataSourceTests. + // Any change made here should be reflected in AssemblyEnumerator.ProcessTestDataSourceTests as well. + dataSource = testDataSource.GetData(_testMethodInfo.MethodInfo); + + if (!dataSource.Any()) { - IEnumerable? dataRows = PlatformServiceProvider.Instance.TestDataSource.GetData(_testMethodInfo, _testContext); + if (!MSTestSettings.CurrentSettings.ConsiderEmptyDataSourceAsInconclusive) + { + throw testDataSource.GetExceptionForEmptyDataSource(_testMethodInfo.MethodInfo); + } + + var inconclusiveResult = new TestResult + { + Outcome = UTF.UnitTestOutcome.Inconclusive, + }; + results.Add(inconclusiveResult); + continue; + } - if (dataRows == null) + foreach (object?[] data in dataSource) + { + try { - var inconclusiveResult = new TestResult - { - Outcome = UTF.UnitTestOutcome.Inconclusive, - Duration = watch.Elapsed, - }; - results.Add(inconclusiveResult); + TestResult[] testResults = ExecuteTestWithDataSource(testDataSource, data); + + results.AddRange(testResults); } - else + finally { - try - { - int rowIndex = 0; - - foreach (object dataRow in dataRows) - { - TestResult[] testResults = ExecuteTestWithDataRow(dataRow, rowIndex++); - results.AddRange(testResults); - } - } - finally - { - _testContext.SetDataConnection(null); - _testContext.SetDataRow(null); - } + _testMethodInfo.SetArguments(null); } } - catch (Exception ex) + } + + return true; + } + + private void ExecuteTestFromDataSourceAttribute(List results) + { + Stopwatch watch = new(); + watch.Start(); + + try + { + IEnumerable? dataRows = PlatformServiceProvider.Instance.TestDataSource.GetData(_testMethodInfo, _testContext); + if (dataRows == null) { - var failedResult = new TestResult + var inconclusiveResult = new TestResult { - Outcome = UTF.UnitTestOutcome.Error, - TestFailureException = ex, + Outcome = UTF.UnitTestOutcome.Inconclusive, Duration = watch.Elapsed, }; - results.Add(failedResult); + results.Add(inconclusiveResult); + return; } - } - else - { - IEnumerable? testDataSources = _testMethodInfo.GetAttributes(false)?.OfType(); - if (testDataSources != null) + try { - foreach (UTF.ITestDataSource testDataSource in testDataSources) + int rowIndex = 0; + + foreach (object dataRow in dataRows) { - isDataDriven = true; - IEnumerable? dataSource; - - // This code is to execute tests. To discover the tests code is in AssemblyEnumerator.ProcessTestDataSourceTests. - // Any change made here should be reflected in AssemblyEnumerator.ProcessTestDataSourceTests as well. - dataSource = testDataSource.GetData(_testMethodInfo.MethodInfo); - - if (!dataSource.Any()) - { - if (!MSTestSettings.CurrentSettings.ConsiderEmptyDataSourceAsInconclusive) - { - throw testDataSource.GetExceptionForEmptyDataSource(_testMethodInfo.MethodInfo); - } - - var inconclusiveResult = new TestResult - { - Outcome = UTF.UnitTestOutcome.Inconclusive, - }; - results.Add(inconclusiveResult); - continue; - } - - foreach (object?[] data in dataSource) - { - try - { - TestResult[] testResults = ExecuteTestWithDataSource(testDataSource, data); - - results.AddRange(testResults); - } - finally - { - _testMethodInfo.SetArguments(null); - } - } + TestResult[] testResults = ExecuteTestWithDataRow(dataRow, rowIndex++); + results.AddRange(testResults); } } + finally + { + _testContext.SetDataConnection(null); + _testContext.SetDataRow(null); + } + } + catch (Exception ex) + { + var failedResult = new TestResult + { + Outcome = UTF.UnitTestOutcome.Error, + TestFailureException = ex, + Duration = watch.Elapsed, + }; + results.Add(failedResult); } - - return isDataDriven; } private TestResult[] ExecuteTestWithDataSource(UTF.ITestDataSource? testDataSource, object?[]? data) From ec5041adbe5926059c3d5a4785e36470d2124d19 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 30 Dec 2024 09:52:18 +0100 Subject: [PATCH 196/273] Small cleanup to Assert.AreEqual (#4472) --- .../Assertions/Assert.AreEqual.cs | 32 +++---------------- 1 file changed, 4 insertions(+), 28 deletions(-) diff --git a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs index defca4bcc5..2079f60160 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs @@ -561,20 +561,8 @@ public static void AreEqual(float expected, float actual, float delta, string? m public static void AreEqual(float expected, float actual, float delta, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (float.IsNaN(expected) || float.IsNaN(actual) || float.IsNaN(delta)) - { - string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualDeltaFailMsg, - userMessage, - expected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreEqual", finalMessage); - } - - if (Math.Abs(expected - actual) > delta) + if (float.IsNaN(expected) || float.IsNaN(actual) || float.IsNaN(delta) || + Math.Abs(expected - actual) > delta) { string userMessage = BuildUserMessage(message, parameters); string finalMessage = string.Format( @@ -1130,20 +1118,8 @@ public static void AreEqual(double expected, double actual, double delta, string public static void AreEqual(double expected, double actual, double delta, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (double.IsNaN(expected) || double.IsNaN(actual) || double.IsNaN(delta)) - { - string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualDeltaFailMsg, - userMessage, - expected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreEqual", finalMessage); - } - - if (Math.Abs(expected - actual) > delta) + if (double.IsNaN(expected) || double.IsNaN(actual) || double.IsNaN(delta) || + Math.Abs(expected - actual) > delta) { string userMessage = BuildUserMessage(message, parameters); string finalMessage = string.Format( From 81f9499e064944185f5a1f797f91461fa4dbfa38 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 09:57:28 +0100 Subject: [PATCH 197/273] [main] Update dependencies from microsoft/testanywhere (#4470) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 836f728084..c6c4b9f24e 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -17,9 +17,9 @@ https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage 8ec298cce46b78be7e9ceb9e7403ad555b51f12b - + https://github.com/microsoft/testanywhere - 5475377201a11dba5ed12888525e88e2c86cf6f6 + 70a9fbe65deff4f8b3a8043a7ea5e2533b7e176e diff --git a/eng/Versions.props b/eng/Versions.props index 4c02e9e431..8742fecc4a 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,6 +10,6 @@ 10.0.0-beta.24604.4 17.14.0-preview.24620.2 - 1.0.0-alpha.24628.3 + 1.0.0-alpha.24629.1 From 2cab07f315e7138bb23ce0cc3632dc8b782b2c8f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 10:16:35 +0100 Subject: [PATCH 198/273] =?UTF-8?q?[main]=20Bump=20MSTest=C2=A0from=203.8.?= =?UTF-8?q?0-preview.24623.10=20to=203.8.0-preview.24629.5=20(#4474)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index dbb9c381ac..e2ae160f50 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -24,7 +24,7 @@ 1.1.3-beta1.24423.1 - 3.8.0-preview.24623.10 + 3.8.0-preview.24629.5 From 7067bc628bccc96e3adcd7c4437ccf9ab4c15071 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 30 Dec 2024 10:17:22 +0100 Subject: [PATCH 199/273] [main] Bump MicrosoftCodeAnalysisPublicApiAnalyzersVersion from 3.11.0-beta1.24605.2 to 3.11.0-beta1.24629.2 (#4473) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index e2ae160f50..5e65027feb 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -8,7 +8,7 @@ 17.11.4 3.11.0 4.10.0 - 3.11.0-beta1.24605.2 + 3.11.0-beta1.24629.2 $(MicrosoftCodeAnalysisPublicApiAnalyzersVersion) 6.2.14 From 39301632581ced30da3f7f713e6e8e786f547c9a Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 31 Dec 2024 08:24:35 +0100 Subject: [PATCH 200/273] Don't report MSTEST0001 when TestAdapter isn't referenced (#4481) --- .../UseParallelizeAttributeAnalyzer.cs | 7 ++++ .../UseParallelizeAttributeAnalyzerTests.cs | 36 ++++++++++++++++--- 2 files changed, 38 insertions(+), 5 deletions(-) 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); } } From f9f91bb2b5fbeaed0dcb4fe5167522c247185bae Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Mon, 30 Dec 2024 23:38:13 -0800 Subject: [PATCH 201/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2610622 --- .../Resources/xlf/Resource.cs.xlf | 4 +- .../Resources/xlf/Resource.de.xlf | 4 +- .../Resources/xlf/Resource.es.xlf | 4 +- .../Resources/xlf/Resource.fr.xlf | 4 +- .../Resources/xlf/Resource.it.xlf | 4 +- .../Resources/xlf/Resource.ja.xlf | 4 +- .../Resources/xlf/Resource.ko.xlf | 4 +- .../Resources/xlf/Resource.pl.xlf | 4 +- .../Resources/xlf/Resource.pt-BR.xlf | 4 +- .../Resources/xlf/Resource.ru.xlf | 4 +- .../Resources/xlf/Resource.tr.xlf | 4 +- .../Resources/xlf/Resource.zh-Hans.xlf | 4 +- .../Resources/xlf/Resource.zh-Hant.xlf | 4 +- .../MSTest.Analyzers/xlf/Resources.cs.xlf | 66 ++++++++--------- .../MSTest.Analyzers/xlf/Resources.de.xlf | 66 ++++++++--------- .../MSTest.Analyzers/xlf/Resources.es.xlf | 66 ++++++++--------- .../MSTest.Analyzers/xlf/Resources.fr.xlf | 66 ++++++++--------- .../MSTest.Analyzers/xlf/Resources.it.xlf | 66 ++++++++--------- .../MSTest.Analyzers/xlf/Resources.ja.xlf | 66 ++++++++--------- .../MSTest.Analyzers/xlf/Resources.ko.xlf | 66 ++++++++--------- .../MSTest.Analyzers/xlf/Resources.pl.xlf | 66 ++++++++--------- .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 66 ++++++++--------- .../MSTest.Analyzers/xlf/Resources.ru.xlf | 70 ++++++++++--------- .../MSTest.Analyzers/xlf/Resources.tr.xlf | 66 ++++++++--------- .../xlf/Resources.zh-Hans.xlf | 66 ++++++++--------- .../xlf/Resources.zh-Hant.xlf | 66 ++++++++--------- 26 files changed, 459 insertions(+), 455 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf index f1dfec23f3..0e1defb645 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.cs.xlf @@ -68,7 +68,7 @@ byl však přijat tento počet argumentů: {4} s typy {5}. Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + Časový limit '{0}' testu vypršel po {1}ms. @@ -419,7 +419,7 @@ Chyba: {1} Test '{0}' was canceled - Test '{0}' was canceled + Testovací '{0}' se zrušila. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf index 816cc3d5dd..4f563a2f9d 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.de.xlf @@ -68,7 +68,7 @@ aber empfing {4} Argument(e) mit den Typen „{5}“. Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + Timeout bei test '{0}' nach {1}ms. @@ -419,7 +419,7 @@ Fehler: {1} Test '{0}' was canceled - Test '{0}' was canceled + Test '{0}' wurde abgebrochen. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf index 7370dd51bc..a7665e8fe1 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.es.xlf @@ -68,7 +68,7 @@ pero recibió {4} argumento(s), con los tipos "{5}". Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + Se agotó el tiempo de espera de la '{0}' de pruebas después de {1}ms @@ -419,7 +419,7 @@ Error: {1} Test '{0}' was canceled - Test '{0}' was canceled + Se canceló la '{0}' de pruebas diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf index 8a23aa209d..908df3801d 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.fr.xlf @@ -68,7 +68,7 @@ mais a reçu {4} argument(s), avec les types « {5} ». Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + Délai de '{0}' de test dépassé après {1}ms @@ -419,7 +419,7 @@ Erreur : {1} Test '{0}' was canceled - Test '{0}' was canceled + Le test '{0}' a été annulé diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf index fd8040e388..4bbe3658f6 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.it.xlf @@ -68,7 +68,7 @@ ma ha ricevuto {4} argomenti, con tipi "{5}". Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + Timeout del '{0}' di test dopo {1}ms @@ -419,7 +419,7 @@ Errore: {1} Test '{0}' was canceled - Test '{0}' was canceled + Il '{0}' di test è stato annullato diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf index 2a3412aa9c..f33a668f43 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ja.xlf @@ -69,7 +69,7 @@ but received {4} argument(s), with types '{5}'. Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + テスト '{0}' が {1}ミリ秒後にタイムアウトしました @@ -420,7 +420,7 @@ Error: {1} Test '{0}' was canceled - Test '{0}' was canceled + テスト '{0}' が取り消されました diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf index 0287b024b8..83f037d230 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ko.xlf @@ -68,7 +68,7 @@ but received {4} argument(s), with types '{5}'. Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + 테스트 '{0}' {1}밀리초 후에 시간 초과되었습니다. @@ -419,7 +419,7 @@ Error: {1} Test '{0}' was canceled - Test '{0}' was canceled + 테스트 '{0}' 취소되었습니다. diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf index 4bc9fbaefc..4889dce291 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pl.xlf @@ -68,7 +68,7 @@ ale liczba odebranych argumentów to {4} z typami „{5}”. Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + Upłynął limit czasu '{0}' testu po {1}ms @@ -419,7 +419,7 @@ Błąd: {1} Test '{0}' was canceled - Test '{0}' was canceled + Anulowano '{0}' testowe diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf index 3095b9a4eb..25daeea3dc 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.pt-BR.xlf @@ -68,7 +68,7 @@ mas {4} argumentos recebidos, com tipos '{5}'. Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + Tempo '{0}' tempo limite do teste após {1}ms @@ -419,7 +419,7 @@ Erro: {1} Test '{0}' was canceled - Test '{0}' was canceled + O '{0}' teste foi cancelado diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf index a8f146d6bc..ce2e4f5ef3 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.ru.xlf @@ -68,7 +68,7 @@ but received {4} argument(s), with types '{5}'. Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + Время ожидания '{0}' истекло через {1}мс @@ -419,7 +419,7 @@ Error: {1} Test '{0}' was canceled - Test '{0}' was canceled + Проверка '{0}' отменена diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf index a6b0023ad7..255dbab729 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.tr.xlf @@ -68,7 +68,7 @@ ancak, '{5}' türüyle {4} argüman aldı. Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + Test '{0}' ms sonra zaman aşımına {1}oldu @@ -419,7 +419,7 @@ Hata: {1} Test '{0}' was canceled - Test '{0}' was canceled + Test '{0}' iptal edildi diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf index cb61f67d73..c8617c0588 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hans.xlf @@ -68,7 +68,7 @@ but received {4} argument(s), with types '{5}'. Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + 测试 '{0}' 在 {1}毫秒后超时 @@ -419,7 +419,7 @@ Error: {1} Test '{0}' was canceled - Test '{0}' was canceled + 测试 '{0}' 已取消 diff --git a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf index 1e49c6e342..6943b4e708 100644 --- a/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf +++ b/src/Adapter/MSTest.TestAdapter/Resources/xlf/Resource.zh-Hant.xlf @@ -68,7 +68,7 @@ but received {4} argument(s), with types '{5}'. Test '{0}' timed out after {1}ms - Test '{0}' timed out after {1}ms + 測試 '{0}' 在 {1}毫秒後逾時 @@ -419,7 +419,7 @@ Error: {1} Test '{0}' was canceled - Test '{0}' was canceled + 已取消測試 '{0}' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index c79e88f0d6..c00244ab27 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + Aby byly metody s označením [AssemblyCleanup] platné, musí se řídit následujícím rozložením: +– Nesmí být deklarované pro obecnou třídu. +– Musí být public. +– Musí být static. +– Nesmí být async void. +– Nesmí být speciální metodou (finalizační metoda, operátor...). +– Nesmí být obecné. +– Nesmí přijímat žádný parametr, nebo musí přijímat jediný parametr typu TestContext. +– Návratový typ musí být void, Task nebo ValueTask. -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Typ deklarující tyto metody by měl také respektovat následující pravidla: +– Typ by měl být třída. +– Třída by měla být public nebo internal (pokud testovací projekt používá atribut [DiscoverInternals]). +– Třída by neměla být static. +– Třída by měla být označena atributem [TestClass] (nebo odvozeným atributem). +– Třída by neměla být obecná. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + Aby byly metody s označením [ClassCleanup] platné, musí se řídit následujícím rozložením: +– Nesmí být deklarované pro obecnou třídu bez nastavení režimu InheritanceBehavior. +– Musí být public. +– Musí být static. +– Nesmí být async void. +– Nesmí být speciální metodou (finalizační metoda, operátor...). +– Nesmí být obecné. +– Nesmí přijímat žádný parametr, nebo musí přijímat jediný parametr typu TestContext. +– Návratový typ musí být void, Task nebo ValueTask. +– V případě třídy abstract by měl být zadán parametr atributu InheritanceBehavior.BeforeEachDerivedClass. +– V případě třídy sealed by neměl být zadán parametr atributu InheritanceBehavior.BeforeEachDerivedClass. -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Typ deklarující tyto metody by měl také respektovat následující pravidla: +– Typ by měl být třída. +– Třída by měla být public nebo internal (pokud testovací projekt používá atribut [DiscoverInternals]). +– Třída by neměla být static. +– Pokud je třída sealed, měla by být označena atributem [TestClass] (nebo odvozeným atributem). +– Třída by neměla být obecná. @@ -379,7 +379,7 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + Člen [DynamicData] {0}.{1} byl nalezen více než jednou. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 7aaa0f678d..1096835671 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + Methoden, die mit „[AssemblyCleanup]“ gekennzeichnet sind, müssen dem folgenden Layout folgen, um gültig zu sein: +– kann nicht für eine generische Klasse deklariert werden +– muss „public“ sein +– muss „static“ sein +– darf nicht „async void“ sein +– darf keine spezielle Methode sein (Finalizer, Operator...) +– darf nicht „generic“ sein +– sollte entweder keinen Parameter oder einen einzelnen Parameter vom Typ „TestContext“ verwenden +– der Rückgabetyp muss „void“, „Task“ oder „ValueTask“ sein -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachten: +– Der Typ sollte eine Klasse sein +– Die Klasse muss „public“ oder „internal“ sein (wenn das Testprojekt das Attribut „[DiscoverInternals]“ verwendet) +– Die Klasse darf nicht „static“ sein +– Die Klasse muss mit „[TestClass]“ (oder einem abgeleiteten Attribut) markiert werden +- die Klasse darf nicht generisch sein. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + Methoden, die mit „[ClassCleanup]“ gekennzeichnet sind, müssen dem folgenden Layout folgen, um gültig zu sein: +– kann nicht für eine generische Klasse deklariert werden, ohne dass der Modus „InheritanceBehavior“ festgelegt ist +– muss „public“ sein +– muss „static“ sein +– darf nicht „async void“ sein +– darf keine spezielle Methode sein (Finalizer, Operator...) +– darf nicht „generic“ sein +– sollte entweder keinen Parameter oder einen einzelnen Parameter vom Typ „TestContext“ verwenden +– der Rückgabetyp muss „void“, „Task“ oder „ValueTask“ sein +– der Attributparameter „InheritanceBehavior.BeforeEachDerivedClass“ sollte angegeben werden, wenn die Klasse „abstract“ ist +– der Attributparameter „InheritanceBehavior.BeforeEachDerivedClass“ sollte angegeben werden, wenn die Klasse „sealed“ ist -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachten: +– Der Typ sollte eine Klasse sein +– Die Klasse muss „public“ oder „internal“ sein (wenn das Testprojekt das Attribut „[DiscoverInternals]“ verwendet) +– Die Klasse darf nicht „static“ sein +– Wenn die Klasse „sealed“ ist, sollte sie mit „[TestClass]“ (oder einem abgeleiteten Attribut) markiert werden +- die Klasse darf nicht generisch sein. @@ -380,7 +380,7 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + „[DynamicData]“-Mitglied „{0}.{1}“ wurde mehrmals gefunden. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 6fbe5e76f5..0df0f975dd 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + Los métodos marcados con '[AssemblyCleanup]' deben seguir el siguiente diseño para ser válidos: +-no se puede declarar en una clase genérica +- debería ser 'público' +- debería estar 'estático' +-no debe ser 'async void' +-no debe ser un método especial (finalizador, operador...). +-no debe ser genérico +-no debe tomar ningún parámetro o tomar un único parámetro de tipo 'TestContext' +- El tipo de valor devuelto debe ser 'void', 'Task' o 'ValueTask' -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +El tipo que declara estos métodos también debe respetar las reglas siguientes: +-El tipo debe ser una clase +-La clase debe ser 'public' o 'internal' (si el proyecto de prueba usa el atributo '[DiscoverInternals]') +-La clase no debe ser 'static' +-La clase debe marcarse con '[TestClass]' (o un atributo derivado) +-la clase no debe ser genérica. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + Los métodos marcados con '[ClassCleanup]' deben seguir el siguiente diseño para ser válidos: +-no se puede declarar en una clase genérica sin el modo 'InheritanceBehavior' establecido +- debería ser 'público' +- debería estar 'estático' +-no debe ser 'async void' +-no debe ser un método especial (finalizador, operador...). +-no debe ser genérico +-no debe tomar ningún parámetro o tomar un único parámetro de tipo 'TestContext' +- El tipo de valor devuelto debe ser 'void', 'Task' o 'ValueTask' +Se debe especificar el parámetro de atributo -'InheritanceBehavior.BeforeEachDerivedClass' si la clase es 'abstract' +No se debe especificar el parámetro de atributo -'InheritanceBehavior.BeforeEachDerivedClass' si la clase es 'sealed' -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +El tipo que declara estos métodos también debe respetar las reglas siguientes: +-El tipo debe ser una clase +-La clase debe ser 'public' o 'internal' (si el proyecto de prueba usa el atributo '[DiscoverInternals]') +-La clase no debe ser 'static' +-Si la clase es 'sealed', debe marcarse con '[TestClass]' (o un atributo derivado) +-la clase no debe ser genérica. @@ -379,7 +379,7 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + '[DynamicData]' miembro '{0}.{1}' se encuentra más de una vez diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index d31fd65b76..a35f7d47a4 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + Les méthodes marquées par « [AssemblyCleanup] » doivent respecter le schéma suivant pour être valides : +-il ne peut pas être déclarée dans une classe générique +– il doit être « public » +– il doit être « static » +– il ne doit pas être « async void » +– Il ne doit pas s’agir d’une méthode spéciale (finaliseur, opérateur...). +– il ne doit pas être générique +- il ne doit pas prendre de paramètre ou prendre un seul paramètre de type 'TestContext' +- le type de retour doit être « vide », « Task » ou « ValueTask » -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Le type déclarant ces méthodes doit également respecter les règles suivantes : +Le type doit être une classe +-La classe doit être « public » ou « internal » (si le projet de test utilise l’attribut ’[DiscoverInternals]’) +-La classe ne doit pas être» ’static » +-La classe doit être marquée par « [TestClass] » (ou un attribut dérivé) +-la classe ne doit pas être générique. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + Les méthodes marquées par « [ClassCleanup] » doivent respecter le schéma suivant pour être valides : +-il ne peut pas être déclarée dans une classe générique si le mode ’InheritanceBehavior’ n’est pas activé +– il doit être « public » +– il doit être « static » +– il ne doit pas être « async void » +– Il ne doit pas s’agir d’une méthode spéciale (finaliseur, opérateur...). +– il ne doit pas être générique +- il ne doit pas prendre de paramètre ou prendre un seul paramètre de type 'TestContext' +- le type de retour doit être « vide », « Task » ou « ValueTask » +- « InheritanceBehavior.BeforeEachDerivedClass » doit être spécifié si la classe est « abstract » +-Le paramètre d’attribut « InheritanceBehavior.BeforeEachDerivedClass » ne doit pas être spécifié si la classe est « scellée » -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Le type déclarant ces méthodes doit également respecter les règles suivantes : +Le type doit être une classe +-La classe doit être « public » ou « internal » (si le projet de test utilise l’attribut ’[DiscoverInternals]’) +-La classe ne doit pas être « static » +-Si la classe est « sealed », elle doit être marquée avec « [TestClass] » (ou un attribut dérivé) +-la classe ne doit pas être générique. @@ -379,7 +379,7 @@ Le type doit être une classe '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + '[DynamicData]' membre ' {0}.{1}' est trouvé plusieurs fois diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index ab85a55c21..5673cca759 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + I metodi contrassegnati con ‘[AssemblyCleanup]' devono seguire il layout seguente per essere validi: +-Non può essere dichiarato in una classe generica +- Deve essere 'public' +- Deve essere 'static' +- Non deve essere 'async void' +- Non deve essere un metodo speciale (finalizzatore, operatore...). +- Non deve essere generico +- Non deve accettare alcun parametro o accettare un singolo parametro di tipo 'TestContext' +- il tipo restituito deve essere 'void', 'Task' o 'ValueTask' -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: +-Il tipo deve essere una classe +-La classe deve essere 'public' o 'internal' (se il progetto di test usa l'attributo '[DiscoverInternals]') +-La classe non deve essere 'static' +-La classe deve essere contrassegnata con '[TestClass]' (o un attributo derivato) +-La classe non deve essere generica. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + I metodi contrassegnati con ‘[ClassCleanup]' devono seguire il layout seguente per essere validi: +-Non può essere dichiarato in una classe generica se la modalità 'InheritanceBehavior' non è impostata +- Deve essere 'public' +- Deve essere 'static' +- Non deve essere 'async void' +- Non deve essere un metodo speciale (finalizzatore, operatore...). +- Non deve essere generico +- Non deve accettare alcun parametro o accettare un singolo parametro di tipo 'TestContext' +- il tipo restituito deve essere 'void', 'Task' o 'ValueTask' +- È necessario specificare il parametro dell'attributo 'InheritanceBehavior.BeforeEachDerivedClass' se la classe è 'abstract' +- Non è necessario specificare il parametro dell'attributo 'InheritanceBehavior.BeforeEachDerivedClass' se la classe è 'sealed' -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: +-Il tipo deve essere una classe +-La classe deve essere 'public' o 'internal' (se il progetto di test usa l'attributo '[DiscoverInternals]') +-La classe non deve essere 'static' +-Se la classe è 'sealed', deve essere contrassegnata con '[TestClass]' (o un attributo derivato) +-La classe non deve essere generica. @@ -379,7 +379,7 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + Il membro '[DynamicData]' '{0}.{1}' è stato trovato più di una volta diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 7b9f8b38db..0ff2e8bd4f 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + '[AssemblyCleanup]' でマークされたメソッドを有効にするには、次のレイアウトに従う必要があります: +- ジェネリック クラスで宣言することはできません +- 'public' である必要があります +- 'static' である必要があります +- 'async void' にすることはできません +- 特殊なメソッド (ファイナライザー、演算子...) にすることはできません。 +- ジェネリックにすることはできません +- パラメーターを受け取らないか、'TestContext' 型の 1 つのパラメーターを受け取る必要があります +- 戻り値の型が 'void'、'Task'、または 'ValueTask' である必要があります -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +これらのメソッドを宣言する型も、次の規則に従う必要があります: +- 型はクラスである必要があります +- クラスは 'public' または 'internal' である必要があります (テスト プロジェクトが '[DiscoverInternals]' 属性を使用している場合) +- クラスを 'static' にすることはできません +- クラスは '[TestClass]' (または派生属性) でマークする必要があります +- クラスをジェネリックにすることはできません。 @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + '[ClassCleanup]' でマークされたメソッドを有効にするには、次のレイアウトに従う必要があります: +- 'InheritanceBehavior' モードが設定されていないと、ジェネリック クラスで宣言できません +- 'public' である必要があります +- 'static' である必要があります +- 'async void' にすることはできません +- 特殊なメソッド (ファイナライザー、演算子...) にすることはできません。 +- ジェネリックにすることはできません +- パラメーターを受け取らないか、'TestContext' 型の 1 つのパラメーターを受け取る必要があります +- 戻り値の型が 'void'、'Task'、または 'ValueTask' である必要があります +- クラスが 'abstract' である場合は 'InheritanceBehavior.BeforeEachDerivedClass' 属性パラメーターを指定する必要があります +- クラスが 'sealed' である場合は 'InheritanceBehavior.BeforeEachDerivedClass' 属性パラメーターを指定しない必要があります -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +これらのメソッドを宣言する型も、次の規則に従う必要があります: +- 型はクラスである必要があります +- クラスは 'public' または 'internal' である必要があります (テスト プロジェクトが '[DiscoverInternals]' 属性を使用している場合) +- クラスを 'static' にすることはできません +- クラスが 'sealed' の場合は、'[TestClass]' (または派生属性) でマークする必要があります +- クラスをジェネリックにすることはできません。 @@ -379,7 +379,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + '[DynamicData]' メンバー '{0}.{1}' が複数回見つかりました diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index b191882072..1ae3a6c497 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + '[AssemblyCleanup]'으로 표시된 메서드가 유효하려면 다음 레이아웃을 따라야 합니다. +- 제네릭 클래스에서 선언할 수 없습니다. +- 'public'이어야 합니다. +- 'static'이어야 합니다. +- 'async void'가 아니어야 합니다. +- 특수 메서드(종료자, 연산자...)가 아니어야 합니다. +- 제네릭이 아니어야 합니다. +- 매개 변수를 사용하거나 'TestContext' 형식의 단일 매개 변수를 사용해서는 안 됩니다. +- 반환 형식은 'void', 'Task' 또는 'ValueTask'여야 합니다. -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +이러한 메서드를 선언하는 형식은 다음 규칙도 준수해야 합니다. +- 형식은 클래스여야 합니다. +- 클래스는 'public' 또는 'internal'이어야 합니다(테스트 프로젝트에서 '[DiscoverInternals]' 특성을 사용하는 경우). +- 클래스는 'static'이 되어서는 안 됩니다. +- 클래스는 '[TestClass]'(또는 파생 특성)로 표시되어야 합니다. +- 클래스는 제네릭이 아니어야 합니다. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + '[ClassCleanup]'으로 표시된 메서드가 유효하려면 다음 레이아웃을 따라야 합니다. +- 'InheritanceBehavior' 모드가 설정되지 않은 제네릭 클래스에서 선언할 수 없습니다. +- 'public'이어야 합니다. +- 'static'이어야 합니다. +- 'async void'가 아니어야 합니다. +- 특수 메서드(종료자, 연산자...)가 아니어야 합니다. +- 제네릭이 아니어야 합니다. +- 매개 변수를 사용하거나 'TestContext' 형식의 단일 매개 변수를 사용해서는 안 됩니다. +- 반환 형식은 'void', 'Task' 또는 'ValueTask'여야 합니다. +- 클래스가 'abstract'인 경우 'InheritanceBehavior.BeforeEachDerivedClass' 특성 매개 변수를 지정해야 합니다. +- 클래스가 'sealed'인 경우 'InheritanceBehavior.BeforeEachDerivedClass' 특성 매개 변수를 지정하면 안 됩니다. -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +이러한 메서드를 선언하는 형식은 다음 규칙도 준수해야 합니다. +- 형식은 클래스여야 합니다. +- 클래스는 'public' 또는 'internal'이어야 합니다(테스트 프로젝트에서 '[DiscoverInternals]' 특성을 사용하는 경우). +- 클래스는 'static'이 되어서는 안 됩니다. +- 클래스가 'sealed'인 경우 '[TestClass]'(또는 파생 특성)로 표시되어야 합니다. +- 클래스는 제네릭이 아니어야 합니다. @@ -379,7 +379,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + '[DynamicData]' 멤버 '{0}.{1}'을(를) 두 번 이상 찾았습니다. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 076f2f56d1..73ec8d0837 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + Metody oznaczone za pomocą „[AssemblyCleanup]” powinny być zgodne z następującym układem, aby były prawidłowe: +— nie może być zadeklarowana w klasie ogólnej +— powinna być typu „public” +— powinna mieć wartość „static” +— nie powinna to być wartość „async void” +— nie powinna to być metoda specjalna (finalizator, operator...). +— nie powinna być ogólna +— nie powinien przyjmować żadnego parametru lub przyjmować pojedynczego parametru typu „TestContext” +— zwracany typ powinien mieć wartość „void”, „Taks” lub „ValueTask” -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Typ deklarujący te metody powinien również przestrzegać następujących reguł: +— typ powinien być klasą +— klasa powinna mieć wartość „public” lub „internal” (jeśli projekt testowy używa atrybutu „[DiscoverInternals]”) +— klasa nie powinna mieć wartości „static” +— klasa powinna być oznaczona „[TestClass]” (lub atrybutem pochodnym) +— klasa nie powinna być ogólna. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + Metody oznaczone za pomocą „[ClassCleanup]” powinny być zgodne z następującym układem, aby były prawidłowe: +— nie może być zadeklarowana w klasie ogólnej bez ustawionego trybu „InheritanceBehavior” +— powinna być typu „public” +— powinna mieć wartość „static” +— nie powinna to być wartość „async void” +— nie powinna to być metoda specjalna (finalizator, operator...). +— nie powinna być ogólna +— nie powinien przyjmować żadnego parametru lub przyjmować pojedynczego parametru typu „TestContext” +— zwracany typ powinien mieć wartość „void”, „Taks” lub „ValueTask” +— parametr atrybutu „InheritanceBehavior.BeforeEachDerivedClass” powinien być określony, jeśli klasa ma wartość „abstract” +— parametr atrybutu „InheritanceBehavior.BeforeEachDerivedClass” nie powinien być określony, jeśli klasa ma wartość „sealed” -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Typ deklarujący te metody powinien również przestrzegać następujących reguł: +— typ powinien być klasą +— klasa powinna mieć wartość „public” lub „internal” (jeśli projekt testowy używa atrybutu „[DiscoverInternals]”) +— klasa nie powinna mieć wartości „static” +— jeśli klasa ma wartość „sealed”, powinna być oznaczona za pomocą „[TestClass]” (lub atrybutem pochodnym) +— klasa nie powinna być ogólna. @@ -379,7 +379,7 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + Element członkowski „[DynamicData]” „{0}.{1}” znaleziono więcej niż raz diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 55e17fd899..31c0643151 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + Os métodos marcados com '[AssemblyCleanup]' devem seguir o seguinte layout para serem válidos: +-não pode ser declarado em uma classe genérica +-deve ser 'public' +-deve ser 'static' +-não deve ser 'async void' +-não deve ser um método especial (finalizador, operador...). +-ele não deve ser genérico +-ele não deve ter nenhum parâmetro ou usar um único parâmetro do tipo 'TestContext' +-o tipo de retorno deve ser 'void', 'Task' ou 'ValueTask' -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +O tipo declarando esses métodos também deve respeitar as seguintes regras: +-O tipo deve ser uma classe +-A classe deve ser 'public' ou 'internal' (se o projeto de teste estiver usando o '[DiscoverInternals]' atributo) +-A classe não deve ser 'static' +-A classe deve ser marcada com '[TestClass]' (ou um atributo derivado) +-a classe não deve ser genérica. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + Os métodos marcados com '[ClassCleanup]' devem seguir o seguinte layout para serem válidos: +-não pode ser declarado em uma classe genérica sem que o modo 'InheritanceBehavior' esteja definido +-deve ser 'public' +-deve ser 'static' +-não deve ser 'async void' +-não deve ser um método especial (finalizador, operador...). +-ele não deve ser genérico +-ele não deve ter nenhum parâmetro ou usar um único parâmetro do tipo 'TestContext' +-o tipo de retorno deve ser 'void', 'Task' ou 'ValueTask' +O parâmetro de atributo -'InheritanceBehavior.BeforeEachDerivedClass' deve ser especificado se a classe for 'abstract' +O parâmetro de atributo -'InheritanceBehavior.BeforeEachDerivedClass' não deve ser especificado se a classe for 'sealed' -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +O tipo declarando esses métodos também deve respeitar as seguintes regras: +-O tipo deve ser uma classe +-A classe deve ser 'public' ou 'internal' (se o projeto de teste estiver usando o '[DiscoverInternals]' atributo) +-A classe não deve ser 'static' +-Se a classe for 'sealed', ela deverá ser marcada com '[TestClass]' (ou um atributo derivado) +-a classe não deve ser genérica. @@ -379,7 +379,7 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + O membro '[DynamicData]' '{0}.{1}' foi encontrado mais de uma vez diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index ee59f488cf..b9ce60a39d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -19,22 +19,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + Чтобы метод, помеченный "[AssemblyCleanup]", был допустимым, он должен соответствовать следующим правилам: +– не может быть объявлен для универсального класса ("generic"); +– должен быть общедоступным ("public"); +– должен быть статическим ("static"); +– не должен быть асинхронным и не возвращающим значения ("async void") +– не должен быть специальным (метод завершения, оператор…). +– не должен быть общим ("generic") +; +– не должен принимать никаких параметров или должен принимать один параметр типа TestContext +; +– должен иметь тип возвращаемого значения "void", "Task" или "ValueTask"; -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Тип, объявляющий такие методы, также должен соответствовать следующим правилам: +– должен быть классом; +– класс должен быть объявлен как "public" или "internal" (если тестовый проект использует атрибут "[DiscoverInternals]"); +– не должен быть статическим ("static"); +– должен быть помечен как "[TestClass]" (или производный атрибут); +– не должен быть универсальным ("generic"). @@ -152,24 +154,26 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + Чтобы метод, помеченный "[ClassCleanup]", был допустимым, он должен соответствовать следующим правилам: +– не может быть объявлен для универсального класса, если не установлен режим InheritanceBehavior; +– должен быть общедоступным ("public"); +– должен быть статическим ("static"); +– не должен быть асинхронным и не возвращающим значения ("async void") +– не должен быть специальным (метод завершения, оператор…). +– не должен быть общим ("generic") +; +– не должен принимать никаких параметров или должен принимать один параметр типа TestContext +; +– должен иметь тип возвращаемого значения "void", "Task" или "ValueTask"; +– если класс абстрактный, должен быть указан параметр атрибута "InheritanceBehavior.BeforeEachDerivedClass"; +– если класс запечатанный, не следует указывать параметр атрибута "InheritanceBehavior.BeforeEachDerivedClass"; -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Тип, объявляющий такие методы, также должен соответствовать следующим правилам: +– должен быть классом; +– класс должен быть объявлен как "public" или "internal" (если тестовый проект использует атрибут "[DiscoverInternals]"); +– не должен быть объявлен как статический ("static"); +– если класс запечатанный, его следует пометить как "[TestClass]" (или производный атрибут); +– не должен быть универсальным ("generic"). @@ -381,7 +385,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + Элемент "[DynamicData]" "{0}.{1}" обнаружен несколько раз diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index 3791c4e8ad..a2552a12f6 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + '[AssemblyCleanup]' ile işaretlenen yöntemlerin geçerli olması için aşağıdaki düzeni takip etmesi gerekir: +-genel bir sınıfta tanımlanamaz +-'public' olmalıdır +-'static' olmalıdır +-'async void' olmamalıdır +-özel bir metot (sonlandırıcı, işleç...) olmamalıdır. +- genel olmamalıdır +-herhangi bir parametre almamalı veya 'TestContext' türünde tek bir parametre almalıdır +- dönüş türü 'void', 'Task' veya 'ValueTask' olmalıdır -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Bu metotları bildiren türün ayrıca aşağıdaki kurallara uyması gerekir: +-Tür bir sınıf olmalıdır +-Sınıf 'public' veya 'internal' olmalıdır (test projesi '[DiscoverInternals]' niteliğini kullanıyorsa) +-Sınıf 'static' olmamalıdır +-Sınıf '[TestClass]' (veya türetilmiş bir öznitelik) ile işaretlenmelidir +-sınıf genel olmamalıdır. @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + '[ClassCleanup]' ile işaretlenen yöntemlerin geçerli olması için aşağıdaki düzeni takip etmesi gereklidir: +-'InheritanceBehavior' modu ayarlanmadan genel bir sınıfta tanımlanamaz +-'public' olmalıdır +-'static' olmalıdır +-'async void' olmamalıdır +-özel bir metot (sonlandırıcı, işleç...) olmamalıdır. +- genel olmamalıdır +-herhangi bir parametre almamalı veya 'TestContext' türünde tek bir parametre almalıdır +- dönüş türü 'void', 'Task' veya 'ValueTask' olmalıdır +-Sınıf 'abstract' ise 'InheritanceBehavior.BeforeEachDerivedClass' öznitelik parametresi belirtilmelidir +-'InheritanceBehavior.BeforeEachDerivedClass' öznitelik parametresi, sınıf 'sealed' ise belirtilmemelidir -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +Bu metotları bildiren türün ayrıca aşağıdaki kurallara uyması gerekir: +-Tür bir sınıf olmalıdır +-Sınıf 'public' veya 'internal' olmalıdır (test projesi '[DiscoverInternals]' niteliğini kullanıyorsa) +-Sınıf 'static' olmamalıdır +-Sınıf 'sealed' ise '[TestClass]' (veya türetilmiş bir öznitelik) ile işaretlenmelidir +-sınıf genel olmamalıdır. @@ -379,7 +379,7 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + '[DynamicData]' üyesi '{0}.{1}' birden çok kez bulundu diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index ad6f1bbac2..6fa047a137 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + 标记有“[AssemblyCleanup]”的方法应遵循以下布局才会有效: +-不能在泛型类上声明它 +- 它应为“public” +- 它应为“static” +- 它不应为“async void” +- 它不应是特殊方法(终结器、运算符...)。 +- 它不应是泛型的 +-它不应采用任何参数,或采用类型为“TestContext”的单个参数 +- 返回类型应为“void”、“Task”或“ValueTask” -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +声明这些方法的类型还应遵循以下规则: +-类型应为类 +-类应为“public”或“internal”(如果测试项目正在使用“[DiscoverInternals]”属性) +-类不应为“static” +-应使用“[TestClass]”(或派生属性)标记类 +-类不应是泛型的。 @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + 标记有“[ClassCleanup]”的方法应遵循以下布局才会有效: +-如果未设置“InheritanceBehavior”模式,则不能在泛型类上声明它 +- 它应为“public” +- 它应为“static” +- 它不应为“async void” +- 它不应是特殊方法(终结器、运算符...)。 +- 它不应是泛型的 +-它不应采用任何参数,或采用类型为“TestContext”的单个参数 +- 返回类型应为“void”、“Task”或“ValueTask” +- "InheritanceBehavior.BeforeEachDerivedClass" 属性参数应在类为 "abstract" 时指定 +- "InheritanceBehavior.BeforeEachDerivedClass" 属性参数不应在类为 "sealed" 时指定 -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +声明这些方法的类型还应遵循以下规则: +-类型应为类 +-类应为“public”或“internal”(如果测试项目正在使用“[DiscoverInternals]”属性) +-类不应为“static” +-如果类为“sealed”,应使用“[TestClass]”(或派生属性)标记该类 +-类不应是泛型的。 @@ -379,7 +379,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + 多次找到 "[DynamicData]" 成员“{0}.{1}” diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 954e70c12b..9251582b4d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -19,22 +19,22 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -The class should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[AssemblyCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' + 標示為 '[AssemblyCleanup]' 的方法應該遵循下列配置才能有效: +-其不能在泛型類別上宣告 +-其應為 'public' +-其應為 'static' +-其不應為 'async void' +-其不應為特殊方法 (完成項、運算子...)。 +-其不應為泛型 +-其不應接受任何參數,或接受類型為 'TestContext' 的單一參數 +-傳回類型應為 'void'、'Task' 或 'ValueTask' -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --The class should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +宣告這些方法的類型還應遵循以下規則: +-類型應為類別 +-類別應為 'public' 或 'internal' (如果測試專案使用 '[DiscoverInternals]' 屬性) +-類別不應為 'static' +-類別應標示為 '[TestClass]' (或衍生屬性) +-類別不應為泛型。 @@ -151,24 +151,24 @@ The type declaring these methods should also respect the following rules: -The class shouldn't be 'static' -If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) -the class should not be generic. - Methods marked with '[ClassCleanup]' should follow the following layout to be valid: --it can't be declared on a generic class without the 'InheritanceBehavior' mode is set --it should be 'public' --it should be 'static' --it should not be 'async void' --it should not be a special method (finalizer, operator...). --it should not be generic --it should either not take any parameter, or take a single parameter of type 'TestContext' --return type should be 'void', 'Task' or 'ValueTask' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should be specified if the class is 'abstract' --'InheritanceBehavior.BeforeEachDerivedClass' attribute parameter should not be specified if the class is 'sealed' + 標示 '[ClassCleanup]' 的方法應該遵循下列配置,才會有效: +-未設定 'InheritanceBehavior' 模式的情況下不能在泛型類別上宣告它 +-其應為 'public' +-其應為 'static' +-其不應為 'async void' +-其不應為特殊方法 (完成項、運算子...)。 +-其不應為泛型 +-其不應接受任何參數,或接受類型為 'TestContext' 的單一參數 +-傳回類型應為 'void'、'Task' 或 'ValueTask' +-如果類別為 'abstract',應指定 'InheritanceBehavior.BeforeEachDerivedClass' 屬性參數 +-如果類別為 'sealed',則不應指定 'InheritanceBehavior.BeforeEachDerivedClass' 屬性參數 -The type declaring these methods should also respect the following rules: --The type should be a class --The class should be 'public' or 'internal' (if the test project is using the '[DiscoverInternals]' attribute) --The class shouldn't be 'static' --If the class is 'sealed', it should be marked with '[TestClass]' (or a derived attribute) --the class should not be generic. +宣告這些方法的類型還應遵循以下規則: +-類型應為類別 +-類別應為 'public' 或 'internal' (如果測試專案使用 '[DiscoverInternals]' 屬性) +-類別不應為 'static' +-如果類別是 'sealed',則應標示為 '[TestClass]' (或衍生屬性) +-類別不應為泛型。 @@ -379,7 +379,7 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is found more than once - '[DynamicData]' member '{0}.{1}' is found more than once + '[DynamicData]' 成員 '{0}。{1}' 多次發現 From edf018c9af71d65f446faa02af9d456fc5999e11 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 31 Dec 2024 09:12:44 +0100 Subject: [PATCH 202/273] [main] Update dependencies from devdiv/DevDiv/vs-code-coverage (#4479) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index c6c4b9f24e..59b0aa8edf 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,9 +13,9 @@ https://github.com/dotnet/arcade 45d845e04c05fbe5da9838c454bbc3af1df6be81 - + https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage - 8ec298cce46b78be7e9ceb9e7403ad555b51f12b + d4a113f856a31bcdcbf6e08da8928961c98bb497 https://github.com/microsoft/testanywhere diff --git a/eng/Versions.props b/eng/Versions.props index 8742fecc4a..1e7318a8f6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,7 +8,7 @@ 10.0.0-beta.24604.4 - 17.14.0-preview.24620.2 + 17.14.0-preview.24630.1 1.0.0-alpha.24629.1 From 0121dcee4ddae16a4ffa7c8bf2b15a8e0904ff28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:21:20 +0100 Subject: [PATCH 203/273] [main] Bump MSTest from 3.8.0-preview.24629.5 to 3.8.0-preview.24630.3 (#4483) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 5e65027feb..49844147f0 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -24,7 +24,7 @@ 1.1.3-beta1.24423.1 - 3.8.0-preview.24629.5 + 3.8.0-preview.24630.3 From 3a30ddbd7c533938e30c4502bd12df0a90ad6962 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 31 Dec 2024 11:49:19 +0100 Subject: [PATCH 204/273] Update SB reference packages (#4485) --- eng/Version.Details.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 59b0aa8edf..5dae748dab 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -34,9 +34,9 @@ - + https://github.com/dotnet/source-build-reference-packages - 94798e07efab2663f2d1a71862780bc365d2e3ab + 80f1e84b2077a7208943db050067d86c94ace837 From 3e602eea4ca1433c2da9914582bcba607d87a2f1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 31 Dec 2024 14:58:01 +0100 Subject: [PATCH 205/273] [main] Bump Polyfill from 7.5.0 to 7.9.1 (#4475) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Amaury Levé --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 49844147f0..20a10dccf7 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -46,7 +46,7 @@ - + From 74aefa856885aab9b490ff196171eded958ac8d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 31 Dec 2024 16:15:47 +0100 Subject: [PATCH 206/273] Move codecov yml file to root --- .github/codecov.yml => codecov.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/codecov.yml => codecov.yml (100%) diff --git a/.github/codecov.yml b/codecov.yml similarity index 100% rename from .github/codecov.yml rename to codecov.yml From 068de75b03571d316d0868bdfec038de49547522 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 2 Jan 2025 15:45:24 +0100 Subject: [PATCH 207/273] Fix match all filter not working when property expression is present (#4495) --- .../Requests/TreeNodeFilter/TreeNodeFilter.cs | 8 +++++++- .../Requests/TreeNodeFilterTests.cs | 19 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs index 5421aee941..9bec02318e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs @@ -441,7 +441,13 @@ public bool MatchesFilter(string testNodeFullPath, PropertyBag filterablePropert if (currentFragmentIndex >= _filters.Count) { // Note: The regex for ** is .*.*, so we match against such a value expression. - return currentFragmentIndex > 0 && _filters.Last() is ValueExpression { Value: ".*.*" }; + FilterExpression lastFilter = _filters.Last(); + if (lastFilter is ValueAndPropertyExpression valueAndPropertyExpression) + { + lastFilter = valueAndPropertyExpression.Value; + } + + return currentFragmentIndex > 0 && lastFilter is ValueExpression { Value: ".*.*" }; } if (!MatchFilterPattern( diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs index facd2f354b..f07a899ae9 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs @@ -167,4 +167,23 @@ public void PropertiesDoNotNeedUrlEncodingOfSlashes(string filter, string nodePa Assert.IsFalse(filterInstance.MatchesFilter(nodePath, nodeProperties)); } } + + [TestMethod] + public void MatchAllFilterWithPropertyExpression() + { + TreeNodeFilter filter = new("/**[A=B]"); + Assert.IsTrue(filter.MatchesFilter("/A/B/C/D", new PropertyBag(new KeyValuePairStringProperty("A", "B")))); + Assert.IsFalse(filter.MatchesFilter("/A/B/C/D", new PropertyBag(new KeyValuePairStringProperty("A", "C")))); + } + + [TestMethod] + public void MatchAllFilterSubpathWithPropertyExpression() + { + TreeNodeFilter filter = new("/A/**[A=B]"); + Assert.IsTrue(filter.MatchesFilter("/A/B/C/D", new PropertyBag(new KeyValuePairStringProperty("A", "B")))); + Assert.IsFalse(filter.MatchesFilter("/B/A/C/D", new PropertyBag(new KeyValuePairStringProperty("A", "B")))); + } + + [TestMethod] + public void MatchAllFilterWithPropertyExpression_DoNotAllowInMiddleOfFilter() => Assert.ThrowsException(() => _ = new TreeNodeFilter("/**/Path[A=B]")); } From 8291cecfaf9567dc7b0dbd319eccb9b74fa4b342 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 2 Jan 2025 20:51:40 +0100 Subject: [PATCH 208/273] Simplify unnecessary extension methods in analyzers (#4497) --- .../AssemblyCleanupShouldBeValidAnalyzer.cs | 2 +- .../AssemblyInitializeShouldBeValidAnalyzer.cs | 2 +- .../ClassCleanupShouldBeValidAnalyzer.cs | 2 +- .../ClassInitializeShouldBeValidAnalyzer.cs | 2 +- .../MSTest.Analyzers/Helpers/FixtureUtils.cs | 18 ------------------ .../Helpers/IMethodSymbolExtensions.cs | 3 +++ ...ferConstructorOverTestInitializeAnalyzer.cs | 2 +- .../PreferDisposeOverTestCleanupAnalyzer.cs | 2 +- .../TestCleanupShouldBeValidAnalyzer.cs | 2 +- .../TestInitializeShouldBeValidAnalyzer.cs | 2 +- 10 files changed, 11 insertions(+), 26 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/AssemblyCleanupShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AssemblyCleanupShouldBeValidAnalyzer.cs index 0152e94b5d..39a385b64c 100644 --- a/src/Analyzers/MSTest.Analyzers/AssemblyCleanupShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/AssemblyCleanupShouldBeValidAnalyzer.cs @@ -61,7 +61,7 @@ private static void AnalyzeSymbol( { var methodSymbol = (IMethodSymbol)context.Symbol; - if (!methodSymbol.IsAssemblyCleanupMethod(assemblyCleanupAttributeSymbol)) + if (!methodSymbol.HasAttribute(assemblyCleanupAttributeSymbol)) { return; } diff --git a/src/Analyzers/MSTest.Analyzers/AssemblyInitializeShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AssemblyInitializeShouldBeValidAnalyzer.cs index 2e7ac95c28..79268d60c0 100644 --- a/src/Analyzers/MSTest.Analyzers/AssemblyInitializeShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/AssemblyInitializeShouldBeValidAnalyzer.cs @@ -55,7 +55,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo { var methodSymbol = (IMethodSymbol)context.Symbol; - if (methodSymbol.IsAssemblyInitializeMethod(assemblyInitializeAttributeSymbol) + if (methodSymbol.HasAttribute(assemblyInitializeAttributeSymbol) && !methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: true, allowGenericType: false, FixtureParameterMode.MustHaveTestContext, testContextSymbol, testClassAttributeSymbol, fixtureAllowInheritedTestClass: false, out bool isFixable)) { diff --git a/src/Analyzers/MSTest.Analyzers/ClassCleanupShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/ClassCleanupShouldBeValidAnalyzer.cs index 9137406b6b..0e693f68dc 100644 --- a/src/Analyzers/MSTest.Analyzers/ClassCleanupShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/ClassCleanupShouldBeValidAnalyzer.cs @@ -63,7 +63,7 @@ private static void AnalyzeSymbol( { var methodSymbol = (IMethodSymbol)context.Symbol; bool isInheritanceModeSet = methodSymbol.IsInheritanceModeSet(inheritanceBehaviorSymbol, classCleanupAttributeSymbol); - if (methodSymbol.IsClassInitializeMethod(classCleanupAttributeSymbol) + if (methodSymbol.HasAttribute(classCleanupAttributeSymbol) && (!methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: true, allowGenericType: isInheritanceModeSet, FixtureParameterMode.OptionalTestContext, testContextSymbol, testClassAttributeSymbol, fixtureAllowInheritedTestClass: true, out bool isFixable) diff --git a/src/Analyzers/MSTest.Analyzers/ClassInitializeShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/ClassInitializeShouldBeValidAnalyzer.cs index 0ef72850a0..88181fb2f3 100644 --- a/src/Analyzers/MSTest.Analyzers/ClassInitializeShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/ClassInitializeShouldBeValidAnalyzer.cs @@ -59,7 +59,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo { var methodSymbol = (IMethodSymbol)context.Symbol; bool isInheritanceModeSet = methodSymbol.IsInheritanceModeSet(inheritanceBehaviorSymbol, classInitializeAttributeSymbol); - if (methodSymbol.IsClassInitializeMethod(classInitializeAttributeSymbol) + if (methodSymbol.HasAttribute(classInitializeAttributeSymbol) && ((!methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: true, allowGenericType: isInheritanceModeSet, FixtureParameterMode.MustHaveTestContext, testContextSymbol, testClassAttributeSymbol, fixtureAllowInheritedTestClass: true, out bool isFixable)) diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/FixtureUtils.cs b/src/Analyzers/MSTest.Analyzers/Helpers/FixtureUtils.cs index 66353d82a6..d4846ee54e 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/FixtureUtils.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/FixtureUtils.cs @@ -12,24 +12,6 @@ namespace MSTest.Analyzers.Helpers; internal static class FixtureUtils { - public static bool IsAssemblyInitializeMethod(this IMethodSymbol methodSymbol, INamedTypeSymbol assemblyInitializeAttributeSymbol) - => methodSymbol.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, assemblyInitializeAttributeSymbol)); - - public static bool IsAssemblyCleanupMethod(this IMethodSymbol methodSymbol, INamedTypeSymbol assemblyCleanupAttributeSymbol) - => methodSymbol.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, assemblyCleanupAttributeSymbol)); - - public static bool IsClassInitializeMethod(this IMethodSymbol methodSymbol, INamedTypeSymbol classInitializeAttributeSymbol) - => methodSymbol.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, classInitializeAttributeSymbol)); - - public static bool IsClassCleanupMethod(this IMethodSymbol methodSymbol, INamedTypeSymbol classCleanupAttributeSymbol) - => methodSymbol.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, classCleanupAttributeSymbol)); - - public static bool IsTestInitializeMethod(this IMethodSymbol methodSymbol, INamedTypeSymbol testInitializeAttributeSymbol) - => methodSymbol.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, testInitializeAttributeSymbol)); - - public static bool IsTestCleanupMethod(this IMethodSymbol methodSymbol, INamedTypeSymbol testCleanupAttributeSymbol) - => methodSymbol.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, testCleanupAttributeSymbol)); - public static bool HasValidFixtureMethodSignature(this IMethodSymbol methodSymbol, INamedTypeSymbol? taskSymbol, INamedTypeSymbol? valueTaskSymbol, bool canDiscoverInternals, bool shouldBeStatic, bool allowGenericType, FixtureParameterMode fixtureParameterMode, diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/IMethodSymbolExtensions.cs b/src/Analyzers/MSTest.Analyzers/Helpers/IMethodSymbolExtensions.cs index 6d58c445e5..4ae6b7faff 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/IMethodSymbolExtensions.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/IMethodSymbolExtensions.cs @@ -9,6 +9,9 @@ namespace MSTest.Analyzers.Helpers; internal static class IMethodSymbolExtensions { + public static bool HasAttribute(this IMethodSymbol methodSymbol, INamedTypeSymbol attribute) + => methodSymbol.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, attribute)); + public static bool IsPublicAndHasCorrectResultantVisibility(this IMethodSymbol methodSymbol, bool canDiscoverInternals) { // Even when we allow discovering internals, MSTest engine only supports the method being declared as public. diff --git a/src/Analyzers/MSTest.Analyzers/PreferConstructorOverTestInitializeAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/PreferConstructorOverTestInitializeAnalyzer.cs index 61d03d2294..5895772f5d 100644 --- a/src/Analyzers/MSTest.Analyzers/PreferConstructorOverTestInitializeAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/PreferConstructorOverTestInitializeAnalyzer.cs @@ -51,7 +51,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo { var methodSymbol = (IMethodSymbol)context.Symbol; - if (methodSymbol.IsTestInitializeMethod(testInitAttributeSymbol) && methodSymbol.ReturnsVoid) + if (methodSymbol.HasAttribute(testInitAttributeSymbol) && methodSymbol.ReturnsVoid) { context.ReportDiagnostic(methodSymbol.CreateDiagnostic(Rule)); } diff --git a/src/Analyzers/MSTest.Analyzers/PreferDisposeOverTestCleanupAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/PreferDisposeOverTestCleanupAnalyzer.cs index 404d4cf7ca..fa126178e5 100644 --- a/src/Analyzers/MSTest.Analyzers/PreferDisposeOverTestCleanupAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/PreferDisposeOverTestCleanupAnalyzer.cs @@ -53,7 +53,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo { var methodSymbol = (IMethodSymbol)context.Symbol; - if (methodSymbol.IsTestCleanupMethod(testCleanupAttributeSymbol)) + if (methodSymbol.HasAttribute(testCleanupAttributeSymbol)) { // We want to report only if the TestCleanup method returns void or if IAsyncDisposable is available. if (iasyncDisposableSymbol is not null diff --git a/src/Analyzers/MSTest.Analyzers/TestCleanupShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/TestCleanupShouldBeValidAnalyzer.cs index e6efcf42ca..e6f4ea8199 100644 --- a/src/Analyzers/MSTest.Analyzers/TestCleanupShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/TestCleanupShouldBeValidAnalyzer.cs @@ -53,7 +53,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo INamedTypeSymbol? valueTaskSymbol, INamedTypeSymbol testClassAttributeSymbol, bool canDiscoverInternals) { var methodSymbol = (IMethodSymbol)context.Symbol; - if (methodSymbol.IsTestCleanupMethod(testCleanupAttributeSymbol) + if (methodSymbol.HasAttribute(testCleanupAttributeSymbol) && !methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: false, allowGenericType: true, FixtureParameterMode.MustNotHaveTestContext, testContextSymbol: null, testClassAttributeSymbol, fixtureAllowInheritedTestClass: true, out bool isFixable)) { diff --git a/src/Analyzers/MSTest.Analyzers/TestInitializeShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/TestInitializeShouldBeValidAnalyzer.cs index de98ece3e0..559d7e39b4 100644 --- a/src/Analyzers/MSTest.Analyzers/TestInitializeShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/TestInitializeShouldBeValidAnalyzer.cs @@ -53,7 +53,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo INamedTypeSymbol? valueTaskSymbol, INamedTypeSymbol testClassAttributeSymbol, bool canDiscoverInternals) { var methodSymbol = (IMethodSymbol)context.Symbol; - if (methodSymbol.IsTestInitializeMethod(testInitializeAttributeSymbol) + if (methodSymbol.HasAttribute(testInitializeAttributeSymbol) && !methodSymbol.HasValidFixtureMethodSignature(taskSymbol, valueTaskSymbol, canDiscoverInternals, shouldBeStatic: false, allowGenericType: true, FixtureParameterMode.MustNotHaveTestContext, testContextSymbol: null, testClassAttributeSymbol, fixtureAllowInheritedTestClass: true, out bool isFixable)) { From d7cf836c87637c9261f7cd075269183013453ee2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 20:52:34 +0100 Subject: [PATCH 209/273] [main] Bump MSTest from 3.8.0-preview.24630.3 to 3.8.0-preview.24631.6 (#4490) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 20a10dccf7..4cafa6d447 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -24,7 +24,7 @@ 1.1.3-beta1.24423.1 - 3.8.0-preview.24630.3 + 3.8.0-preview.24631.6 From 38ba48fb5bf655d29fa030ffe88137c7db706f0c Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 2 Jan 2025 20:52:56 +0100 Subject: [PATCH 210/273] [main] Update dependencies from microsoft/testanywhere (#4488) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 5dae748dab..309409e050 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -17,9 +17,9 @@ https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage d4a113f856a31bcdcbf6e08da8928961c98bb497 - + https://github.com/microsoft/testanywhere - 70a9fbe65deff4f8b3a8043a7ea5e2533b7e176e + 1b35871af094500bb7bf28aa23b61d7135e1fca2 diff --git a/eng/Versions.props b/eng/Versions.props index 1e7318a8f6..cfeb2dc685 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,6 +10,6 @@ 10.0.0-beta.24604.4 17.14.0-preview.24630.1 - 1.0.0-alpha.24629.1 + 1.0.0-alpha.24630.3 From dd0ac3288d1b88bd5559160fc53efc7769e32709 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 2 Jan 2025 20:55:26 +0100 Subject: [PATCH 211/273] Implement != operator for filtering (#4494) --- .../Requests/TreeNodeFilter/FilterOperator.cs | 5 --- .../Requests/TreeNodeFilter/OperatorKind.cs | 5 +++ .../Requests/TreeNodeFilter/TreeNodeFilter.cs | 37 ++++++++++++++++++- .../Requests/TreeNodeFilterTests.cs | 36 ++++++++++++++++++ 4 files changed, 76 insertions(+), 7 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/FilterOperator.cs b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/FilterOperator.cs index 9743f49f87..d518d7548f 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/FilterOperator.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/FilterOperator.cs @@ -19,9 +19,4 @@ internal enum FilterOperator /// Combine the following expressions with a logical OR. /// Or, - - /// - /// Filter the following expression by the given property. - /// - Equals, } diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/OperatorKind.cs b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/OperatorKind.cs index 051583489c..b9c7da2819 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/OperatorKind.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/OperatorKind.cs @@ -41,6 +41,11 @@ internal enum OperatorKind /// FilterEquals, + /// + /// Filter not equals operator. + /// + FilterNotEquals, + /// /// Operator used for combining multiple filters with a logical OR. /// diff --git a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs index 9bec02318e..9a81e683df 100644 --- a/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs +++ b/src/Platform/Microsoft.Testing.Platform/Requests/TreeNodeFilter/TreeNodeFilter.cs @@ -38,6 +38,7 @@ internal TreeNodeFilter(string filter) /// FILTER_EXPR = /// '(' FILTER_EXPR ')' /// | TOKEN '=' TOKEN + /// | TOKEN '!=' TOKEN /// | FILTER_EXPR OP FILTER_EXPR /// | TOKEN /// OP = '&' | '|' @@ -210,6 +211,13 @@ private static List ParseFilter(string filter) isPropAllowed = false; break; + case "!=": + operatorStack.Push(OperatorKind.FilterNotEquals); + + isOperatorAllowed = false; + isPropAllowed = false; + break; + default: expressionStack.Push(new ValueExpression(token)); @@ -311,7 +319,6 @@ private static void ProcessStackOperator(OperatorKind op, Stack FilterOperator.And, OperatorKind.Or => FilterOperator.Or, - OperatorKind.FilterEquals => FilterOperator.Equals, _ => throw ApplicationStateGuard.Unreachable(), }; @@ -319,6 +326,7 @@ private static void ProcessStackOperator(OperatorKind op, Stack TokenizeFilter(string filter) break; + case '!': + if (i + 1 < filter.Length && filter[i + 1] == '=') + { + if (lastStringTokenBuilder.Length > 0) + { + yield return lastStringTokenBuilder.ToString(); + lastStringTokenBuilder.Clear(); + } + + yield return "!="; + i++; + } + else + { + goto default; + } + + break; + default: lastStringTokenBuilder.Append(Regex.Escape(filter[i].ToString())); break; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs index f07a899ae9..f587f02457 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Requests/TreeNodeFilterTests.cs @@ -105,6 +105,42 @@ public void Parameters_PropertyCheck() Assert.IsFalse(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag())); } + [TestMethod] + public void Parameters_NegatedPropertyCheck() + { + TreeNodeFilter filter = new("/*.UnitTests[Tag!=Fast]"); + Assert.IsFalse(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag(new KeyValuePairStringProperty("Tag", "Fast")))); + Assert.IsTrue(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag(new KeyValuePairStringProperty("Tag", "Slow")))); + Assert.IsTrue(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag())); + } + + [TestMethod] + public void Parameters_NegatedPropertyCheckWithMatchAllFilter() + { + TreeNodeFilter filter = new("/**[Tag!=Fast]"); + Assert.IsFalse(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag(new KeyValuePairStringProperty("Tag", "Fast")))); + Assert.IsTrue(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag(new KeyValuePairStringProperty("Tag", "Slow")))); + Assert.IsTrue(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag())); + } + + [TestMethod] + public void Parameters_NegatedPropertyCheckCombinedWithAnd() + { + TreeNodeFilter filter = new("/*.UnitTests[(Tag!=Fast)&(Tag!=Slow)]"); + Assert.IsFalse(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag(new KeyValuePairStringProperty("Tag", "Fast")))); + Assert.IsFalse(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag(new KeyValuePairStringProperty("Tag", "Slow")))); + Assert.IsTrue(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag())); + } + + [TestMethod] + public void Parameters_NegatedPropertyCheckCombinedWithOr() + { + TreeNodeFilter filter = new("/*.UnitTests[(Tag!=Fast)|(Tag!=Slow)]"); + Assert.IsTrue(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag(new KeyValuePairStringProperty("Tag", "Fast")))); + Assert.IsTrue(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag(new KeyValuePairStringProperty("Tag", "Slow")))); + Assert.IsTrue(filter.MatchesFilter("/ProjectB.UnitTests", new PropertyBag())); + } + [TestMethod] public void Parameters_DisallowAtStart() => Assert.ThrowsException(() => _ = new TreeNodeFilter("/[Tag=Fast]")); From 60e7c87726c0f03f6e136cf6ffa9dac430f7e9e2 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 3 Jan 2025 20:52:01 +0100 Subject: [PATCH 212/273] Update ExpectedException codefix to use the new Assert.Throws[Exactly][Async] overloads (#4504) --- .../AvoidExpectedExceptionAttributeFixer.cs | 17 +++--- ...AvoidExpectedExceptionAttributeAnalyzer.cs | 4 +- ...ExpectedExceptionAttributeAnalyzerTests.cs | 54 +++++++++++++------ 3 files changed, 52 insertions(+), 23 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidExpectedExceptionAttributeFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidExpectedExceptionAttributeFixer.cs index cf08f96300..07191819bf 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidExpectedExceptionAttributeFixer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidExpectedExceptionAttributeFixer.cs @@ -42,10 +42,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) return; } - if (diagnostic.Properties.ContainsKey(DiagnosticDescriptorHelper.CannotFixPropertyKey)) - { - return; - } + bool allowDerivedTypes = diagnostic.Properties.ContainsKey(AvoidExpectedExceptionAttributeAnalyzer.AllowDerivedTypesKey); // Find the method declaration identified by the diagnostic. MethodDeclarationSyntax methodDeclaration = syntaxToken.Parent.AncestorsAndSelf().OfType().First(); @@ -84,7 +81,7 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) context.RegisterCodeFix( CodeAction.Create( title: CodeFixResources.UseAssertThrowsExceptionOnLastStatementFix, - createChangedDocument: c => WrapLastStatementWithAssertThrowsExceptionAsync(context.Document, methodDeclaration, attributeSyntax, exceptionTypeSymbol, c), + createChangedDocument: c => WrapLastStatementWithAssertThrowsExceptionAsync(context.Document, methodDeclaration, attributeSyntax, exceptionTypeSymbol, allowDerivedTypes, c), equivalenceKey: nameof(AvoidExpectedExceptionAttributeFixer)), diagnostic); } @@ -94,6 +91,7 @@ private static async Task WrapLastStatementWithAssertThrowsExceptionAs MethodDeclarationSyntax methodDeclaration, SyntaxNode attributeSyntax, ITypeSymbol exceptionTypeSymbol, + bool allowDerivedTypes, CancellationToken cancellationToken) { DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); @@ -123,7 +121,14 @@ private static async Task WrapLastStatementWithAssertThrowsExceptionAs SyntaxNode newStatement = generator.InvocationExpression( generator.MemberAccessExpression( generator.IdentifierName("Assert"), - generator.GenericName(containsAsyncCode ? "ThrowsExceptionAsync" : "ThrowsException", [exceptionTypeSymbol])), + generator.GenericName( + (containsAsyncCode, allowDerivedTypes) switch + { + (false, false) => "ThrowsExactly", + (false, true) => "Throws", + (true, false) => "ThrowsExactlyAsync", + (true, true) => "ThrowsAsync", + }, [exceptionTypeSymbol])), newLambdaExpression); if (containsAsyncCode) diff --git a/src/Analyzers/MSTest.Analyzers/AvoidExpectedExceptionAttributeAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AvoidExpectedExceptionAttributeAnalyzer.cs index 5762ba451c..c0f62dd22d 100644 --- a/src/Analyzers/MSTest.Analyzers/AvoidExpectedExceptionAttributeAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/AvoidExpectedExceptionAttributeAnalyzer.cs @@ -22,6 +22,8 @@ public sealed class AvoidExpectedExceptionAttributeAnalyzer : DiagnosticAnalyzer 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 const string AllowDerivedTypesKey = nameof(AllowDerivedTypesKey); + internal static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create( DiagnosticIds.AvoidExpectedExceptionAttributeRuleId, Title, @@ -59,7 +61,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo // Assert.ThrowsException checks the exact Exception type. So, we cannot offer a fix to ThrowsException if the user sets AllowDerivedTypes to true. context.ReportDiagnostic( allowsDerivedTypes - ? methodSymbol.CreateDiagnostic(Rule, properties: DiagnosticDescriptorHelper.CannotFixProperties) + ? methodSymbol.CreateDiagnostic(Rule, properties: ImmutableDictionary.Empty.Add(AllowDerivedTypesKey, null)) : methodSymbol.CreateDiagnostic(Rule)); } } diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs index f194c77ce6..ff8dc63b1a 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs @@ -79,15 +79,13 @@ public void TestMethod2() { } - [ExpectedException(typeof(System.Exception), AllowDerivedTypes = true)] [TestMethod] - public void [|TestMethod3|]() + public void TestMethod3() { } - [ExpectedException(typeof(System.Exception), "Some message", AllowDerivedTypes = true)] [TestMethod] - public void [|TestMethod4|]() + public void TestMethod4() { } @@ -108,11 +106,9 @@ public void TestMethod2() { fixedCode, }, - // ExpectedException with AllowDerivedTypes = True cannot be simply converted - // to Assert.ThrowsException as the semantics are different (same for custom attributes that may have some special semantics). - // For now, the user needs to manually fix this to use Assert.ThrowsException and specify the actual (exact) exception type. + // The codefix cannot fix MyExpectedException because it cannot detect the exception type. + // For now, the user needs to manually fix this. // We *could* provide a codefix that uses Assert.ThrowsException but that's most likely going to be wrong. - // If the user explicitly has AllowDerivedTypes, it's likely because he doesn't specify the exact exception type. // NOTE: For fixed state, the default is MarkupMode.IgnoreFixable, so we set // to Allow as we still have expected errors after applying the codefix. MarkupHandling = MarkupMode.Allow, @@ -138,6 +134,13 @@ public class TestClass { Console.WriteLine("Hello, world!"); } + + [ExpectedException(typeof(System.Exception), AllowDerivedTypes = true)] + [TestMethod] + public void [|TestMethod2|]() + { + Console.WriteLine("Hello, world!"); + } } """; @@ -151,7 +154,13 @@ public class TestClass [TestMethod] public void TestMethod() { - Assert.ThrowsException(() => Console.WriteLine("Hello, world!")); + Assert.ThrowsExactly(() => Console.WriteLine("Hello, world!")); + } + + [TestMethod] + public void TestMethod2() + { + Assert.Throws(() => Console.WriteLine("Hello, world!")); } } """; @@ -185,7 +194,7 @@ public class TestClass { [TestMethod] public void TestMethod() - => Assert.ThrowsException(() => Console.WriteLine("Hello, world!")); + => Assert.ThrowsExactly(() => Console.WriteLine("Hello, world!")); } """; @@ -225,7 +234,7 @@ public class TestClass [TestMethod] public void TestMethod() { - Assert.ThrowsException(() => GetNumber()); + Assert.ThrowsExactly(() => GetNumber()); } } """; @@ -262,7 +271,7 @@ public class TestClass private int GetNumber() => 0; [TestMethod] public void TestMethod() - => Assert.ThrowsException(() => GetNumber()); + => Assert.ThrowsExactly(() => GetNumber()); } """; @@ -286,6 +295,13 @@ public class TestClass { await Task.Delay(0); } + + [ExpectedException(typeof(System.Exception), AllowDerivedTypes = true)] + [TestMethod] + public async Task [|TestMethod2|]() + { + await Task.Delay(0); + } } """; @@ -300,7 +316,13 @@ public class TestClass [TestMethod] public async Task TestMethod() { - await Assert.ThrowsExceptionAsync(async () => await Task.Delay(0)); + await Assert.ThrowsExactlyAsync(async () => await Task.Delay(0)); + } + + [TestMethod] + public async Task TestMethod2() + { + await Assert.ThrowsAsync(async () => await Task.Delay(0)); } } """; @@ -336,7 +358,7 @@ public class TestClass { [TestMethod] public async Task TestMethod() - => await Assert.ThrowsExceptionAsync(async () => await Task.Delay(0)); + => await Assert.ThrowsExactlyAsync(async () => await Task.Delay(0)); } """; @@ -378,7 +400,7 @@ public class TestClass public async Task TestMethod() { await Task.Delay(0); - Assert.ThrowsException(() => M()); + Assert.ThrowsExactly(() => M()); } private static void M() => throw new Exception(); @@ -428,7 +450,7 @@ public class TestClass public async Task TestMethod() { Console.WriteLine("Hello, world!"); - await Assert.ThrowsExceptionAsync(async () => + await Assert.ThrowsExactlyAsync(async () => // In ideal world, it's best if the codefix can separate await M() to a // variable, then only wrap M(someVariable) in Assert.ThrowsException // Let's also have this comment serve as a test for trivia ;) From 950c90925cfc33c79256e4420d9248b11575e770 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Fri, 3 Jan 2025 20:55:08 +0100 Subject: [PATCH 213/273] Introduce interpolated string handler overloads for assertions (#4476) --- .../Assertions/Assert.AreEqual.cs | 715 +++++++++++++++--- .../Assertions/Assert.AreSame.cs | 168 +++- .../Assertions/Assert.IsInstanceOfType.cs | 331 +++++++- .../TestFramework/Assertions/Assert.IsNull.cs | 149 +++- .../TestFramework/Assertions/Assert.IsTrue.cs | 175 ++++- .../Assertions/Assert.ThrowsException.cs | 301 ++++++-- .../PublicAPI/PublicAPI.Unshipped.txt | 221 ++++++ .../PublicAPI/net/PublicAPI.Shipped.txt | 1 + .../PublicAPI/net/PublicAPI.Unshipped.txt | 33 + .../TestFramework/TestFramework.csproj | 3 + .../Assertions/AssertTests.AreEqualTests.cs | 160 ++++ .../Assertions/AssertTests.AreSame.cs | 133 ++++ .../AssertTests.IsInstanceOfTypeTests.cs | 92 ++- .../Assertions/AssertTests.IsNull.cs | 81 +- .../Assertions/AssertTests.IsTrueTests.cs | 237 +++++- .../Assertions/AssertTests.cs | 20 + .../TestContainer.cs | 42 + 17 files changed, 2629 insertions(+), 233 deletions(-) create mode 100644 src/TestFramework/TestFramework/PublicAPI/net/PublicAPI.Shipped.txt create mode 100644 src/TestFramework/TestFramework/PublicAPI/net/PublicAPI.Unshipped.txt create mode 100644 test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreSame.cs diff --git a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs index 2079f60160..274bc26248 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs @@ -1,6 +1,8 @@ // 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.ComponentModel; + namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// @@ -10,6 +12,356 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// public sealed partial class Assert { + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertAreEqualInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + private readonly object? _expected; + private readonly object? _actual; + + public AssertAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? expected, TArgument? actual, out bool shouldAppend) + { + _expected = expected!; + shouldAppend = AreEqualFailing(expected, actual); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _expected = expected; + _actual = actual; + } + } + + public AssertAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? expected, TArgument? actual, IEqualityComparer? comparer, out bool shouldAppend) + { + shouldAppend = AreEqualFailing(expected, actual, comparer); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _expected = expected; + _actual = actual; + } + } + + public AssertAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, IEquatable? expected, IEquatable? actual, out bool shouldAppend) + { + shouldAppend = AreEqualFailing(expected, actual); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _expected = expected; + _actual = actual; + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertAreEqualFailed(_expected, _actual, _builder.ToString()); + } + } + + public void AppendLiteral(string? value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertAreNotEqualInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + private readonly object? _notExpected; + private readonly object? _actual; + + public AssertAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? notExpected, TArgument? actual, out bool shouldAppend) + : this(literalLength, formattedCount, notExpected, actual, null, out shouldAppend) + { + } + + public AssertAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? notExpected, TArgument? actual, IEqualityComparer? comparer, out bool shouldAppend) + { + shouldAppend = AreNotEqualFailing(notExpected, actual, comparer); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _notExpected = notExpected; + _actual = actual; + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertAreNotEqualFailed(_notExpected, _actual, _builder.ToString()); + } + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertNonGenericAreEqualInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + private readonly Action? _failAction; + + public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, float expected, float actual, float delta, out bool shouldAppend) + { + shouldAppend = AreEqualFailing(expected, actual, delta); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _failAction = userMessage => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + } + } + + public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, decimal expected, decimal actual, decimal delta, out bool shouldAppend) + { + shouldAppend = AreEqualFailing(expected, actual, delta); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _failAction = userMessage => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + } + } + + public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, long expected, long actual, long delta, out bool shouldAppend) + { + shouldAppend = AreEqualFailing(expected, actual, delta); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _failAction = userMessage => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + } + } + + public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, double expected, double actual, double delta, out bool shouldAppend) + { + shouldAppend = AreEqualFailing(expected, actual, delta); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _failAction = userMessage => ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); + } + } + + public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, string? expected, string? actual, bool ignoreCase, out bool shouldAppend) + : this(literalLength, formattedCount, expected, actual, ignoreCase, CultureInfo.InvariantCulture, out shouldAppend) + { + } + + public AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, string? expected, string? actual, bool ignoreCase, [NotNull] CultureInfo? culture, out bool shouldAppend) + { + Guard.NotNull(culture); + shouldAppend = AreEqualFailing(expected, actual, ignoreCase, culture); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _failAction = userMessage => ThrowAssertAreEqualFailed(expected, actual, ignoreCase, culture, userMessage); + } + } + + internal void ComputeAssertion() + => _failAction?.Invoke(_builder!.ToString()); + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertNonGenericAreNotEqualInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + private readonly Action? _failAction; + + public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, float notExpected, float actual, float delta, out bool shouldAppend) + { + shouldAppend = AreNotEqualFailing(notExpected, actual, delta); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _failAction = userMessage => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + } + } + + public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, decimal notExpected, decimal actual, decimal delta, out bool shouldAppend) + { + shouldAppend = AreNotEqualFailing(notExpected, actual, delta); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _failAction = userMessage => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + } + } + + public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, long notExpected, long actual, long delta, out bool shouldAppend) + { + shouldAppend = AreNotEqualFailing(notExpected, actual, delta); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _failAction = userMessage => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + } + } + + public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, double notExpected, double actual, double delta, out bool shouldAppend) + { + shouldAppend = AreNotEqualFailing(notExpected, actual, delta); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _failAction = userMessage => ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); + } + } + + public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, string? notExpected, string? actual, bool ignoreCase, out bool shouldAppend) + : this(literalLength, formattedCount, notExpected, actual, ignoreCase, CultureInfo.InvariantCulture, out shouldAppend) + { + } + + public AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, string? notExpected, string? actual, bool ignoreCase, [NotNull] CultureInfo? culture, out bool shouldAppend) + { + Guard.NotNull(culture); + shouldAppend = AreNotEqualFailing(notExpected, actual, ignoreCase, culture); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + _failAction = userMessage => ThrowAssertAreNotEqualFailed(notExpected, actual, userMessage); + } + } + + internal void ComputeAssertion() + => _failAction?.Invoke(_builder!.ToString()); + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + /// /// Tests whether the specified values are equal and throws an exception /// if the two values are not equal. @@ -80,6 +432,12 @@ public static void AreEqual(T? expected, T? actual, IEqualityComparer? com public static void AreEqual(T? expected, T? actual, string? message) => AreEqual(expected, actual, null, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreEqual(T? expected, T? actual, [InterpolatedStringHandlerArgument(nameof(expected), nameof(actual))] ref AssertAreEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified values are equal and throws an exception /// if the two values are not equal. @@ -110,6 +468,12 @@ public static void AreEqual(T? expected, T? actual, string? message) public static void AreEqual(T? expected, T? actual, IEqualityComparer? comparer, string? message) => AreEqual(expected, actual, comparer, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreEqual(T? expected, T? actual, IEqualityComparer? comparer, [InterpolatedStringHandlerArgument(nameof(expected), nameof(actual), nameof(comparer))] ref AssertAreEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified values are equal and throws an exception /// if the two values are not equal. @@ -172,30 +536,13 @@ public static void AreEqual(T? expected, T? actual, [StringSyntax(StringSynta public static void AreEqual(T? expected, T? actual, IEqualityComparer? comparer, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - IEqualityComparer localComparer = comparer ?? EqualityComparer.Default; - if (localComparer.Equals(expected!, actual!)) + if (!AreEqualFailing(expected, actual, comparer)) { return; } string userMessage = BuildUserMessage(message, parameters); - string finalMessage = actual != null && expected != null && !actual.GetType().Equals(expected.GetType()) - ? string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualDifferentTypesFailMsg, - userMessage, - ReplaceNulls(expected), - expected.GetType().FullName, - ReplaceNulls(actual), - actual.GetType().FullName) - : string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualFailMsg, - userMessage, - ReplaceNulls(expected), - ReplaceNulls(actual)); - - ThrowAssertFailed("Assert.AreEqual", finalMessage); + ThrowAssertAreEqualFailed(expected, actual, userMessage); } /// @@ -244,6 +591,12 @@ public static void AreEqual(IEquatable? expected, IEquatable? actual) public static void AreEqual(IEquatable? expected, IEquatable? actual, string? message) => AreEqual(expected, actual, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreEqual(IEquatable? expected, IEquatable? actual, [InterpolatedStringHandlerArgument(nameof(expected), nameof(actual))] ref AssertAreEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified values are equal and throws an exception /// if the two values are not equal. @@ -272,17 +625,44 @@ public static void AreEqual(IEquatable? expected, IEquatable? actual, s /// public static void AreEqual(IEquatable? expected, IEquatable? actual, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (actual is null && expected is null) - { - return; - } - - if (actual?.Equals(expected) == true) + if (!AreEqualFailing(expected, actual)) { return; } string userMessage = BuildUserMessage(message, parameters); + ThrowAssertAreEqualFailed(expected, actual, userMessage); + } + + private static bool AreEqualFailing(T? expected, T? actual) + => AreEqualFailing(expected, actual, null); + + private static bool AreEqualFailing(T? expected, T? actual, IEqualityComparer? comparer) + => !(comparer ?? EqualityComparer.Default).Equals(expected!, actual!); + + private static bool AreEqualFailing(IEquatable? expected, IEquatable? actual) + => (actual is not null || expected is not null) && actual?.Equals(expected) != true; + + private static bool AreEqualFailing(string? expected, string? actual, bool ignoreCase, CultureInfo culture) + => CompareInternal(expected, actual, ignoreCase, culture) != 0; + + private static bool AreEqualFailing(float expected, float actual, float delta) + => float.IsNaN(expected) || float.IsNaN(actual) || float.IsNaN(delta) || + Math.Abs(expected - actual) > delta; + + private static bool AreEqualFailing(double expected, double actual, double delta) + => double.IsNaN(expected) || double.IsNaN(actual) || double.IsNaN(delta) || + Math.Abs(expected - actual) > delta; + + private static bool AreEqualFailing(decimal expected, decimal actual, decimal delta) + => Math.Abs(expected - actual) > delta; + + private static bool AreEqualFailing(long expected, long actual, long delta) + => Math.Abs(expected - actual) > delta; + + [DoesNotReturn] + private static void ThrowAssertAreEqualFailed(object? expected, object? actual, string userMessage) + { string finalMessage = actual != null && expected != null && !actual.GetType().Equals(expected.GetType()) ? string.Format( CultureInfo.CurrentCulture, @@ -298,6 +678,39 @@ public static void AreEqual(IEquatable? expected, IEquatable? actual, [ userMessage, ReplaceNulls(expected), ReplaceNulls(actual)); + ThrowAssertFailed("Assert.AreEqual", finalMessage); + } + + [DoesNotReturn] + private static void ThrowAssertAreEqualFailed(T expected, T actual, T delta, string userMessage) + where T : struct, IConvertible + { + string finalMessage = string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.AreEqualDeltaFailMsg, + userMessage, + expected.ToString(CultureInfo.CurrentCulture.NumberFormat), + actual.ToString(CultureInfo.CurrentCulture.NumberFormat), + delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); + ThrowAssertFailed("Assert.AreEqual", finalMessage); + } + + [DoesNotReturn] + private static void ThrowAssertAreEqualFailed(string? expected, string? actual, bool ignoreCase, CultureInfo culture, string userMessage) + { + string finalMessage = !ignoreCase && CompareInternal(expected, actual, ignoreCase, culture) == 0 + ? string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.AreEqualCaseFailMsg, + userMessage, + ReplaceNulls(expected), + ReplaceNulls(actual)) + : string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.AreEqualFailMsg, + userMessage, + ReplaceNulls(expected), + ReplaceNulls(actual)); ThrowAssertFailed("Assert.AreEqual", finalMessage); } @@ -374,6 +787,12 @@ public static void AreNotEqual(T? notExpected, T? actual, IEqualityComparer(T? notExpected, T? actual, string? message) => AreNotEqual(notExpected, actual, null, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreNotEqual(T? notExpected, T? actual, [InterpolatedStringHandlerArgument(nameof(notExpected), nameof(actual))] ref AssertAreNotEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified values are unequal and throws an exception /// if the two values are equal. @@ -404,6 +823,12 @@ public static void AreNotEqual(T? notExpected, T? actual, string? message) public static void AreNotEqual(T? notExpected, T? actual, IEqualityComparer? comparer, string? message) => AreNotEqual(notExpected, actual, comparer, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreNotEqual(T? notExpected, T? actual, IEqualityComparer? comparer, [InterpolatedStringHandlerArgument(nameof(notExpected), nameof(actual), nameof(comparer))] ref AssertAreNotEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified values are unequal and throws an exception /// if the two values are equal. @@ -466,20 +891,13 @@ public static void AreNotEqual(T? notExpected, T? actual, [StringSyntax(Strin public static void AreNotEqual(T? notExpected, T? actual, IEqualityComparer? comparer, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - IEqualityComparer localComparer = comparer ?? EqualityComparer.Default; - if (!localComparer.Equals(notExpected!, actual!)) + if (!AreNotEqualFailing(notExpected, actual, comparer)) { return; } string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreNotEqualFailMsg, - userMessage, - ReplaceNulls(notExpected), - ReplaceNulls(actual)); - ThrowAssertFailed("Assert.AreNotEqual", finalMessage); + ThrowAssertAreNotEqualFailed(notExpected, actual, userMessage); } /// @@ -531,6 +949,12 @@ public static void AreEqual(float expected, float actual, float delta) public static void AreEqual(float expected, float actual, float delta, string? message) => AreEqual(expected, actual, delta, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreEqual(float expected, float actual, float delta, [InterpolatedStringHandlerArgument(nameof(expected), nameof(actual), nameof(delta))] ref AssertNonGenericAreEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified floats are equal and throws an exception /// if they are not equal. @@ -561,18 +985,10 @@ public static void AreEqual(float expected, float actual, float delta, string? m public static void AreEqual(float expected, float actual, float delta, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (float.IsNaN(expected) || float.IsNaN(actual) || float.IsNaN(delta) || - Math.Abs(expected - actual) > delta) + if (AreEqualFailing(expected, actual, delta)) { string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualDeltaFailMsg, - userMessage, - expected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreEqual", finalMessage); + ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); } } @@ -625,6 +1041,12 @@ public static void AreNotEqual(float notExpected, float actual, float delta) public static void AreNotEqual(float notExpected, float actual, float delta, string? message) => AreNotEqual(notExpected, actual, delta, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreNotEqual(float notExpected, float actual, float delta, [InterpolatedStringHandlerArgument(nameof(notExpected), nameof(actual), nameof(delta))] ref AssertNonGenericAreNotEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified floats are unequal and throws an exception /// if they are equal. @@ -655,20 +1077,16 @@ public static void AreNotEqual(float notExpected, float actual, float delta, str public static void AreNotEqual(float notExpected, float actual, float delta, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (Math.Abs(notExpected - actual) <= delta) + if (AreNotEqualFailing(notExpected, actual, delta)) { string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreNotEqualDeltaFailMsg, - userMessage, - notExpected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreNotEqual", finalMessage); + ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); } } + private static bool AreNotEqualFailing(float notExpected, float actual, float delta) + => Math.Abs(notExpected - actual) <= delta; + /// /// Tests whether the specified decimals are equal and throws an exception /// if they are not equal. @@ -718,6 +1136,12 @@ public static void AreEqual(decimal expected, decimal actual, decimal delta) public static void AreEqual(decimal expected, decimal actual, decimal delta, string? message) => AreEqual(expected, actual, delta, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreEqual(decimal expected, decimal actual, decimal delta, [InterpolatedStringHandlerArgument(nameof(expected), nameof(actual), nameof(delta))] ref AssertNonGenericAreEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified decimals are equal and throws an exception /// if they are not equal. @@ -748,17 +1172,10 @@ public static void AreEqual(decimal expected, decimal actual, decimal delta, str public static void AreEqual(decimal expected, decimal actual, decimal delta, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (Math.Abs(expected - actual) > delta) + if (AreEqualFailing(expected, actual, delta)) { string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualDeltaFailMsg, - userMessage, - expected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreEqual", finalMessage); + ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); } } @@ -811,6 +1228,12 @@ public static void AreNotEqual(decimal notExpected, decimal actual, decimal delt public static void AreNotEqual(decimal notExpected, decimal actual, decimal delta, string? message) => AreNotEqual(notExpected, actual, delta, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreNotEqual(decimal notExpected, decimal actual, decimal delta, [InterpolatedStringHandlerArgument(nameof(notExpected), nameof(actual), nameof(delta))] ref AssertNonGenericAreNotEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified decimals are unequal and throws an exception /// if they are equal. @@ -841,20 +1264,16 @@ public static void AreNotEqual(decimal notExpected, decimal actual, decimal delt public static void AreNotEqual(decimal notExpected, decimal actual, decimal delta, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (Math.Abs(notExpected - actual) <= delta) + if (AreNotEqualFailing(notExpected, actual, delta)) { string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreNotEqualDeltaFailMsg, - userMessage, - notExpected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreNotEqual", finalMessage); + ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); } } + private static bool AreNotEqualFailing(decimal notExpected, decimal actual, decimal delta) + => Math.Abs(notExpected - actual) <= delta; + /// /// Tests whether the specified longs are equal and throws an exception /// if they are not equal. @@ -904,6 +1323,12 @@ public static void AreEqual(long expected, long actual, long delta) public static void AreEqual(long expected, long actual, long delta, string? message) => AreEqual(expected, actual, delta, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreEqual(long expected, long actual, long delta, [InterpolatedStringHandlerArgument(nameof(expected), nameof(actual), nameof(delta))] ref AssertNonGenericAreEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified longs are equal and throws an exception /// if they are not equal. @@ -934,17 +1359,10 @@ public static void AreEqual(long expected, long actual, long delta, string? mess public static void AreEqual(long expected, long actual, long delta, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (Math.Abs(expected - actual) > delta) + if (AreEqualFailing(expected, actual, delta)) { string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualDeltaFailMsg, - userMessage, - expected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreEqual", finalMessage); + ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); } } @@ -997,6 +1415,12 @@ public static void AreNotEqual(long notExpected, long actual, long delta) public static void AreNotEqual(long notExpected, long actual, long delta, string? message) => AreNotEqual(notExpected, actual, delta, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreNotEqual(long notExpected, long actual, long delta, [InterpolatedStringHandlerArgument(nameof(notExpected), nameof(actual), nameof(delta))] ref AssertNonGenericAreNotEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified longs are unequal and throws an exception /// if they are equal. @@ -1027,20 +1451,16 @@ public static void AreNotEqual(long notExpected, long actual, long delta, string public static void AreNotEqual(long notExpected, long actual, long delta, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (Math.Abs(notExpected - actual) <= delta) + if (AreNotEqualFailing(notExpected, actual, delta)) { string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreNotEqualDeltaFailMsg, - userMessage, - notExpected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreNotEqual", finalMessage); + ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); } } + private static bool AreNotEqualFailing(long notExpected, long actual, long delta) + => Math.Abs(notExpected - actual) <= delta; + /// /// Tests whether the specified doubles are equal and throws an exception /// if they are not equal. @@ -1089,6 +1509,12 @@ public static void AreEqual(double expected, double actual, double delta) public static void AreEqual(double expected, double actual, double delta, string? message) => AreEqual(expected, actual, delta, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreEqual(double expected, double actual, double delta, [InterpolatedStringHandlerArgument(nameof(expected), nameof(actual), nameof(delta))] ref AssertNonGenericAreEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified doubles are equal and throws an exception /// if they are not equal. @@ -1118,18 +1544,10 @@ public static void AreEqual(double expected, double actual, double delta, string public static void AreEqual(double expected, double actual, double delta, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (double.IsNaN(expected) || double.IsNaN(actual) || double.IsNaN(delta) || - Math.Abs(expected - actual) > delta) + if (AreEqualFailing(expected, actual, delta)) { string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualDeltaFailMsg, - userMessage, - expected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreEqual", finalMessage); + ThrowAssertAreEqualFailed(expected, actual, delta, userMessage); } } @@ -1182,6 +1600,12 @@ public static void AreNotEqual(double notExpected, double actual, double delta) public static void AreNotEqual(double notExpected, double actual, double delta, string? message) => AreNotEqual(notExpected, actual, delta, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreNotEqual(double notExpected, double actual, double delta, [InterpolatedStringHandlerArgument(nameof(notExpected), nameof(actual), nameof(delta))] ref AssertNonGenericAreNotEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified doubles are unequal and throws an exception /// if they are equal. @@ -1212,20 +1636,30 @@ public static void AreNotEqual(double notExpected, double actual, double delta, public static void AreNotEqual(double notExpected, double actual, double delta, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (Math.Abs(notExpected - actual) <= delta) + if (AreNotEqualFailing(notExpected, actual, delta)) { string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreNotEqualDeltaFailMsg, - userMessage, - notExpected.ToString(CultureInfo.CurrentCulture.NumberFormat), - actual.ToString(CultureInfo.CurrentCulture.NumberFormat), - delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); - ThrowAssertFailed("Assert.AreNotEqual", finalMessage); + ThrowAssertAreNotEqualFailed(notExpected, actual, delta, userMessage); } } + private static bool AreNotEqualFailing(double notExpected, double actual, double delta) + => Math.Abs(notExpected - actual) <= delta; + + [DoesNotReturn] + private static void ThrowAssertAreNotEqualFailed(T notExpected, T actual, T delta, string userMessage) + where T : struct, IConvertible + { + string finalMessage = string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.AreNotEqualDeltaFailMsg, + userMessage, + notExpected.ToString(CultureInfo.CurrentCulture.NumberFormat), + actual.ToString(CultureInfo.CurrentCulture.NumberFormat), + delta.ToString(CultureInfo.CurrentCulture.NumberFormat)); + ThrowAssertFailed("Assert.AreNotEqual", finalMessage); + } + /// /// Tests whether the specified strings are equal and throws an exception /// if they are not equal. The invariant culture is used for the comparison. @@ -1271,6 +1705,12 @@ public static void AreEqual(string? expected, string? actual, bool ignoreCase) public static void AreEqual(string? expected, string? actual, bool ignoreCase, string? message) => AreEqual(expected, actual, ignoreCase, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreEqual(string? expected, string? actual, bool ignoreCase, [InterpolatedStringHandlerArgument(nameof(expected), nameof(actual), nameof(ignoreCase))] ref AssertNonGenericAreEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified strings are equal and throws an exception /// if they are not equal. The invariant culture is used for the comparison. @@ -1353,6 +1793,16 @@ public static void AreEqual(string? expected, string? actual, bool ignoreCase, [NotNull] CultureInfo? culture, string? message) => AreEqual(expected, actual, ignoreCase, culture, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreEqual(string? expected, string? actual, bool ignoreCase, +#pragma warning restore IDE0060 // Remove unused parameter + [NotNull] CultureInfo? culture, [InterpolatedStringHandlerArgument(nameof(expected), nameof(actual), nameof(ignoreCase), nameof(culture))] ref AssertNonGenericAreEqualInterpolatedStringHandler message) + { + CheckParameterNotNull(culture, "Assert.AreEqual", nameof(culture), string.Empty); + message.ComputeAssertion(); + } + /// /// Tests whether the specified strings are equal and throws an exception /// if they are not equal. @@ -1385,28 +1835,13 @@ public static void AreEqual(string? expected, string? actual, bool ignoreCase, [NotNull] CultureInfo? culture, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { CheckParameterNotNull(culture, "Assert.AreEqual", "culture", string.Empty); - if (CompareInternal(expected, actual, ignoreCase, culture) == 0) + if (!AreEqualFailing(expected, actual, ignoreCase, culture)) { return; } string userMessage = BuildUserMessage(message, parameters); - string finalMessage = !ignoreCase && CompareInternal(expected, actual, ignoreCase, culture) == 0 - ? string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualCaseFailMsg, - userMessage, - ReplaceNulls(expected), - ReplaceNulls(actual)) - : string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreEqualFailMsg, - userMessage, - ReplaceNulls(expected), - ReplaceNulls(actual)); - - // Comparison failed. Check if it was a case-only failure. - ThrowAssertFailed("Assert.AreEqual", finalMessage); + ThrowAssertAreEqualFailed(expected, actual, ignoreCase, culture, userMessage); } /// @@ -1456,6 +1891,12 @@ public static void AreNotEqual(string? notExpected, string? actual, bool ignoreC public static void AreNotEqual(string? notExpected, string? actual, bool ignoreCase, string? message) => AreNotEqual(notExpected, actual, ignoreCase, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreNotEqual(string? notExpected, string? actual, bool ignoreCase, [InterpolatedStringHandlerArgument(nameof(notExpected), nameof(actual), nameof(ignoreCase))] ref AssertNonGenericAreNotEqualInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified strings are unequal and throws an exception /// if they are equal. The invariant culture is used for the comparison. @@ -1540,6 +1981,16 @@ public static void AreNotEqual(string? notExpected, string? actual, bool ignoreC CultureInfo? culture, string? message) => AreNotEqual(notExpected, actual, ignoreCase, culture, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreNotEqual(string? notExpected, string? actual, bool ignoreCase, +#pragma warning restore IDE0060 // Remove unused parameter + CultureInfo? culture, [InterpolatedStringHandlerArgument(nameof(notExpected), nameof(actual), nameof(ignoreCase), nameof(culture))] ref AssertNonGenericAreNotEqualInterpolatedStringHandler message) + { + CheckParameterNotNull(culture, "Assert.AreNotEqual", nameof(culture), string.Empty); + message.ComputeAssertion(); + } + /// /// Tests whether the specified strings are unequal and throws an exception /// if they are equal. @@ -1573,12 +2024,24 @@ public static void AreNotEqual(string? notExpected, string? actual, bool ignoreC CultureInfo? culture, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { CheckParameterNotNull(culture, "Assert.AreNotEqual", "culture", string.Empty); - if (CompareInternal(notExpected, actual, ignoreCase, culture) != 0) + if (!AreNotEqualFailing(notExpected, actual, ignoreCase, culture)) { return; } string userMessage = BuildUserMessage(message, parameters); + ThrowAssertAreNotEqualFailed(notExpected, actual, userMessage); + } + + private static bool AreNotEqualFailing(string? notExpected, string? actual, bool ignoreCase, CultureInfo culture) + => CompareInternal(notExpected, actual, ignoreCase, culture) == 0; + + private static bool AreNotEqualFailing(T? notExpected, T? actual, IEqualityComparer? comparer) + => (comparer ?? EqualityComparer.Default).Equals(notExpected!, actual!); + + [DoesNotReturn] + private static void ThrowAssertAreNotEqualFailed(object? notExpected, object? actual, string userMessage) + { string finalMessage = string.Format( CultureInfo.CurrentCulture, FrameworkMessages.AreNotEqualFailMsg, diff --git a/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs b/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs index b2fd9113d1..0a7799900d 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.AreSame.cs @@ -1,6 +1,8 @@ // 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.ComponentModel; + namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// @@ -10,6 +12,124 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// public sealed partial class Assert { + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertAreSameInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + private readonly TArgument? _expected; + private readonly TArgument? _actual; + + public AssertAreSameInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? expected, TArgument? actual, out bool shouldAppend) + { + _expected = expected; + _actual = actual; + shouldAppend = IsAreSameFailing(expected, actual); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertAreSameFailed(_expected, _actual, _builder.ToString()); + } + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertAreNotSameInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + + public AssertAreNotSameInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? notExpected, TArgument? actual, out bool shouldAppend) + { + shouldAppend = IsAreNotSameFailing(notExpected, actual); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertAreNotSameFailed(_builder.ToString()); + } + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + /// /// Tests whether the specified objects both refer to the same object and /// throws an exception if the two inputs do not refer to the same object. @@ -55,6 +175,12 @@ public static void AreSame(T? expected, T? actual) public static void AreSame(T? expected, T? actual, string? message) => AreSame(expected, actual, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreSame(T? expected, T? actual, [InterpolatedStringHandlerArgument(nameof(expected), nameof(actual))] ref AssertAreSameInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified objects both refer to the same object and /// throws an exception if the two inputs do not refer to the same object. @@ -82,23 +208,28 @@ public static void AreSame(T? expected, T? actual, string? message) /// public static void AreSame(T? expected, T? actual, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (ReferenceEquals(expected, actual)) + if (!IsAreSameFailing(expected, actual)) { return; } string userMessage = BuildUserMessage(message, parameters); - string finalMessage = userMessage; + ThrowAssertAreSameFailed(expected, actual, userMessage); + } + + private static bool IsAreSameFailing(T? expected, T? actual) + => !ReferenceEquals(expected, actual); - if (expected is ValueType) + [DoesNotReturn] + private static void ThrowAssertAreSameFailed(T? expected, T? actual, string userMessage) + { + string finalMessage = userMessage; + if (expected is ValueType && actual is ValueType) { - if (actual is ValueType) - { - finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.AreSameGivenValues, - userMessage); - } + finalMessage = string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.AreSameGivenValues, + userMessage); } ThrowAssertFailed("Assert.AreSame", finalMessage); @@ -151,6 +282,12 @@ public static void AreNotSame(T? notExpected, T? actual) public static void AreNotSame(T? notExpected, T? actual, string? message) => AreNotSame(notExpected, actual, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void AreNotSame(T? notExpected, T? actual, [InterpolatedStringHandlerArgument(nameof(notExpected), nameof(actual))] ref AssertAreNotSameInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified objects refer to different objects and /// throws an exception if the two inputs refer to the same object. @@ -179,9 +316,16 @@ public static void AreNotSame(T? notExpected, T? actual, string? message) /// public static void AreNotSame(T? notExpected, T? actual, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (ReferenceEquals(notExpected, actual)) + if (IsAreNotSameFailing(notExpected, actual)) { - ThrowAssertFailed("Assert.AreNotSame", BuildUserMessage(message, parameters)); + ThrowAssertAreNotSameFailed(BuildUserMessage(message, parameters)); } } + + private static bool IsAreNotSameFailing(T? notExpected, T? actual) + => ReferenceEquals(notExpected, actual); + + [DoesNotReturn] + private static void ThrowAssertAreNotSameFailed(string userMessage) + => ThrowAssertFailed("Assert.AreNotSame", userMessage); } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs index 84adbb12b5..63f62e38ba 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs @@ -1,6 +1,8 @@ // 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.ComponentModel; + namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// @@ -10,6 +12,246 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// public sealed partial class Assert { + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertIsInstanceOfTypeInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + private readonly object? _value; + private readonly Type? _expectedType; + + public AssertIsInstanceOfTypeInterpolatedStringHandler(int literalLength, int formattedCount, object? value, Type? expectedType, out bool shouldAppend) + { + _value = value; + _expectedType = expectedType; + shouldAppend = IsInstanceOfTypeFailing(value, expectedType); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertIsInstanceOfTypeFailed(_value, _expectedType, _builder.ToString()); + } + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertGenericIsInstanceOfTypeInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + private readonly object? _value; + + public AssertGenericIsInstanceOfTypeInterpolatedStringHandler(int literalLength, int formattedCount, object? value, out bool shouldAppend) + { + _value = value; + shouldAppend = IsInstanceOfTypeFailing(value, typeof(TArg)); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertIsInstanceOfTypeFailed(_value, typeof(TArg), _builder.ToString()); + } + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertIsNotInstanceOfTypeInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + private readonly object? _value; + private readonly Type? _wrongType; + + public AssertIsNotInstanceOfTypeInterpolatedStringHandler(int literalLength, int formattedCount, object? value, Type? wrongType, out bool shouldAppend) + { + _value = value; + _wrongType = wrongType; + shouldAppend = IsNotInstanceOfTypeFailing(value, wrongType); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertIsNotInstanceOfTypeFailed(_value, _wrongType, _builder.ToString()); + } + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + private readonly object? _value; + + public AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler(int literalLength, int formattedCount, object? value, out bool shouldAppend) + { + _value = value; + shouldAppend = IsNotInstanceOfTypeFailing(value, typeof(TArg)); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertIsNotInstanceOfTypeFailed(_value, typeof(TArg), _builder.ToString()); + } + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + /// /// Tests whether the specified object is an instance of the expected /// type and throws an exception if the expected type is not in the @@ -71,6 +313,14 @@ public static void IsInstanceOfType([NotNull] object? value, out T instance) public static void IsInstanceOfType([NotNull] object? value, [NotNull] Type? expectedType, string? message) => IsInstanceOfType(value, expectedType, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void IsInstanceOfType([NotNull] object? value, [NotNull] Type? expectedType, [InterpolatedStringHandlerArgument(nameof(value), nameof(expectedType))] ref AssertIsInstanceOfTypeInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter +#pragma warning disable CS8777 // Parameter must have a non-null value when exiting. - Not sure how to express the semantics to the compiler, but the implementation guarantees that. + => message.ComputeAssertion(); +#pragma warning restore CS8777 // Parameter must have a non-null value when exiting. + /// /// Tests whether the specified object is an instance of the generic /// type and throws an exception if the generic type is not in the @@ -80,6 +330,14 @@ public static void IsInstanceOfType([NotNull] object? value, [NotNull] Type? exp public static void IsInstanceOfType([NotNull] object? value, string? message) => IsInstanceOfType(value, typeof(T), message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void IsInstanceOfType([NotNull] object? value, [InterpolatedStringHandlerArgument(nameof(value))] ref AssertGenericIsInstanceOfTypeInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter +#pragma warning disable CS8777 // Parameter must have a non-null value when exiting. - Not sure how to express the semantics to the compiler, but the implementation guarantees that. + => message.ComputeAssertion(); +#pragma warning restore CS8777 // Parameter must have a non-null value when exiting. + /// /// Tests whether the specified object is an instance of the generic /// type and throws an exception if the generic type is not in the @@ -89,6 +347,15 @@ public static void IsInstanceOfType([NotNull] object? value, string? message) public static void IsInstanceOfType([NotNull] object? value, out T instance, string? message) => IsInstanceOfType(value, out instance, message, null); + /// + public static void IsInstanceOfType([NotNull] object? value, out T instance, [InterpolatedStringHandlerArgument(nameof(value))] ref AssertGenericIsInstanceOfTypeInterpolatedStringHandler message) +#pragma warning disable CS8777 // Parameter must have a non-null value when exiting. - Not sure how to express the semantics to the compiler, but the implementation guarantees that. + { + message.ComputeAssertion(); + instance = (T)value!; + } +#pragma warning restore CS8777 // Parameter must have a non-null value when exiting. + /// /// Tests whether the specified object is an instance of the expected /// type and throws an exception if the expected type is not in the @@ -116,23 +383,30 @@ public static void IsInstanceOfType([NotNull] object? value, out T instance, public static void IsInstanceOfType([NotNull] object? value, [NotNull] Type? expectedType, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (expectedType == null || value == null) + if (IsInstanceOfTypeFailing(value, expectedType)) { - ThrowAssertFailed("Assert.IsInstanceOfType", BuildUserMessage(message, parameters)); + ThrowAssertIsInstanceOfTypeFailed(value, expectedType, BuildUserMessage(message, parameters)); } + } - Type elementType = value.GetType(); - if (!expectedType.IsAssignableFrom(elementType)) + private static bool IsInstanceOfTypeFailing([NotNullWhen(false)] object? value, [NotNullWhen(false)] Type? expectedType) + => expectedType == null || value == null || !expectedType.IsAssignableFrom(value.GetType()); + + [DoesNotReturn] + private static void ThrowAssertIsInstanceOfTypeFailed(object? value, Type? expectedType, string userMessage) + { + string finalMessage = userMessage; + if (expectedType is not null && value is not null) { - string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( + finalMessage = string.Format( CultureInfo.CurrentCulture, FrameworkMessages.IsInstanceOfFailMsg, userMessage, expectedType.ToString(), value.GetType().ToString()); - ThrowAssertFailed("Assert.IsInstanceOfType", finalMessage); } + + ThrowAssertFailed("Assert.IsInstanceOfType", finalMessage); } /// @@ -210,6 +484,14 @@ public static void IsNotInstanceOfType(object? value) public static void IsNotInstanceOfType(object? value, [NotNull] Type? wrongType, string? message) => IsNotInstanceOfType(value, wrongType, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void IsNotInstanceOfType(object? value, [NotNull] Type? wrongType, [InterpolatedStringHandlerArgument(nameof(value), nameof(wrongType))] ref AssertIsNotInstanceOfTypeInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter +#pragma warning disable CS8777 // Parameter must have a non-null value when exiting. - Not sure how to express the semantics to the compiler, but the implementation guarantees that. + => message.ComputeAssertion(); +#pragma warning restore CS8777 // Parameter must have a non-null value when exiting. + /// /// Tests whether the specified object is not an instance of the wrong generic /// type and throws an exception if the specified type is in the @@ -219,6 +501,12 @@ public static void IsNotInstanceOfType(object? value, [NotNull] Type? wrongType, public static void IsNotInstanceOfType(object? value, string? message) => IsNotInstanceOfType(value, typeof(T), message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void IsNotInstanceOfType(object? value, [InterpolatedStringHandlerArgument(nameof(value))] AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified object is not an instance of the wrong /// type and throws an exception if the specified type is in the @@ -246,29 +534,32 @@ public static void IsNotInstanceOfType(object? value, string? message) public static void IsNotInstanceOfType(object? value, [NotNull] Type? wrongType, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (wrongType == null) + if (IsNotInstanceOfTypeFailing(value, wrongType)) { - ThrowAssertFailed("Assert.IsNotInstanceOfType", BuildUserMessage(message, parameters)); + ThrowAssertIsNotInstanceOfTypeFailed(value, wrongType, BuildUserMessage(message, parameters)); } + } - // Null is not an instance of any type. - if (value == null) - { - return; - } + private static bool IsNotInstanceOfTypeFailing(object? value, [NotNullWhen(false)] Type? wrongType) + => wrongType is null || + // Null is not an instance of any type. + (value is not null && wrongType.IsAssignableFrom(value.GetType())); - Type elementType = value.GetType(); - if (wrongType.IsAssignableFrom(elementType)) + [DoesNotReturn] + private static void ThrowAssertIsNotInstanceOfTypeFailed(object? value, Type? wrongType, string userMessage) + { + string finalMessage = userMessage; + if (wrongType is not null) { - string userMessage = BuildUserMessage(message, parameters); - string finalMessage = string.Format( + finalMessage = string.Format( CultureInfo.CurrentCulture, FrameworkMessages.IsNotInstanceOfFailMsg, userMessage, wrongType.ToString(), - value.GetType().ToString()); - ThrowAssertFailed("Assert.IsNotInstanceOfType", finalMessage); + value!.GetType().ToString()); } + + ThrowAssertFailed("Assert.IsNotInstanceOfType", finalMessage); } /// diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs index 96df80dd1d..74dd9a5e51 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsNull.cs @@ -1,6 +1,8 @@ // 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.ComponentModel; + namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// @@ -10,6 +12,120 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// public sealed partial class Assert { + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertIsNullInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + + public AssertIsNullInterpolatedStringHandler(int literalLength, int formattedCount, object? value, out bool shouldAppend) + { + shouldAppend = IsNullFailing(value); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertIsNullFailed(_builder.ToString()); + } + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertIsNotNullInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + + public AssertIsNotNullInterpolatedStringHandler(int literalLength, int formattedCount, object? value, out bool shouldAppend) + { + shouldAppend = IsNotNullFailing(value); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertIsNotNullFailed(_builder.ToString()); + } + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + /// /// Tests whether the specified object is null and throws an exception /// if it is not. @@ -40,6 +156,12 @@ public static void IsNull(object? value) public static void IsNull(object? value, string? message) => IsNull(value, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void IsNull(object? value, [InterpolatedStringHandlerArgument(nameof(value))] ref AssertIsNullInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified object is null and throws an exception /// if it is not. @@ -59,12 +181,17 @@ public static void IsNull(object? value, string? message) /// public static void IsNull(object? value, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (value != null) + if (IsNullFailing(value)) { - ThrowAssertFailed("Assert.IsNull", BuildUserMessage(message, parameters)); + ThrowAssertIsNullFailed(BuildUserMessage(message, parameters)); } } + private static bool IsNullFailing(object? value) => value is not null; + + private static void ThrowAssertIsNullFailed(string message) + => ThrowAssertFailed("Assert.IsNull", message); + /// /// Tests whether the specified object is non-null and throws an exception /// if it is null. @@ -95,6 +222,14 @@ public static void IsNotNull([NotNull] object? value) public static void IsNotNull([NotNull] object? value, string? message) => IsNotNull(value, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void IsNotNull([NotNull] object? value, [InterpolatedStringHandlerArgument(nameof(value))] ref AssertIsNotNullInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter +#pragma warning disable CS8777 // Parameter must have a non-null value when exiting. - Not sure how to express the semantics to the compiler, but the implementation guarantees that. + => message.ComputeAssertion(); +#pragma warning restore CS8777 // Parameter must have a non-null value when exiting. + /// /// Tests whether the specified object is non-null and throws an exception /// if it is null. @@ -114,9 +249,15 @@ public static void IsNotNull([NotNull] object? value, string? message) /// public static void IsNotNull([NotNull] object? value, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (value == null) + if (IsNotNullFailing(value)) { - ThrowAssertFailed("Assert.IsNotNull", BuildUserMessage(message, parameters)); + ThrowAssertIsNotNullFailed(BuildUserMessage(message, parameters)); } } + + private static bool IsNotNullFailing([NotNullWhen(false)] object? value) => value is null; + + [DoesNotReturn] + private static void ThrowAssertIsNotNullFailed(string message) + => ThrowAssertFailed("Assert.IsNotNull", message); } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs index 62e96b5470..53815e5b36 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsTrue.cs @@ -1,6 +1,8 @@ // 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.ComponentModel; + namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// @@ -10,6 +12,120 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// public sealed partial class Assert { + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertIsTrueInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + + public AssertIsTrueInterpolatedStringHandler(int literalLength, int formattedCount, bool? condition, out bool shouldAppend) + { + shouldAppend = IsTrueFailing(condition); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertIsTrueFailed(_builder.ToString()); + } + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertIsFalseInterpolatedStringHandler + { + private readonly StringBuilder? _builder; + + public AssertIsFalseInterpolatedStringHandler(int literalLength, int formattedCount, bool? condition, out bool shouldAppend) + { + shouldAppend = IsFalseFailing(condition); + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal void ComputeAssertion() + { + if (_builder is not null) + { + ThrowAssertIsFalseFailed(_builder.ToString()); + } + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + /// /// Tests whether the specified condition is true and throws an exception /// if the condition is false. @@ -53,6 +169,12 @@ public static void IsTrue([DoesNotReturnIf(false)] bool? condition) public static void IsTrue([DoesNotReturnIf(false)] bool condition, string? message) => IsTrue(condition, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void IsTrue([DoesNotReturnIf(false)] bool condition, [InterpolatedStringHandlerArgument(nameof(condition))] ref AssertIsTrueInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified condition is true and throws an exception /// if the condition is false. @@ -70,6 +192,12 @@ public static void IsTrue([DoesNotReturnIf(false)] bool condition, string? messa public static void IsTrue([DoesNotReturnIf(false)] bool? condition, string? message) => IsTrue(condition, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void IsTrue([DoesNotReturnIf(false)] bool? condition, [InterpolatedStringHandlerArgument(nameof(condition))] ref AssertIsTrueInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified condition is true and throws an exception /// if the condition is false. @@ -90,9 +218,9 @@ public static void IsTrue([DoesNotReturnIf(false)] bool? condition, string? mess public static void IsTrue([DoesNotReturnIf(false)] bool condition, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (!condition) + if (IsTrueFailing(condition)) { - ThrowAssertFailed("Assert.IsTrue", BuildUserMessage(message, parameters)); + ThrowAssertIsTrueFailed(BuildUserMessage(message, parameters)); } } @@ -116,12 +244,21 @@ public static void IsTrue([DoesNotReturnIf(false)] bool condition, [StringSyntax public static void IsTrue([DoesNotReturnIf(false)] bool? condition, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (condition is false or null) + if (IsTrueFailing(condition)) { - ThrowAssertFailed("Assert.IsTrue", BuildUserMessage(message, parameters)); + ThrowAssertIsTrueFailed(BuildUserMessage(message, parameters)); } } + private static bool IsTrueFailing(bool? condition) + => condition is false or null; + + private static bool IsTrueFailing(bool condition) + => !condition; + + private static void ThrowAssertIsTrueFailed(string message) + => ThrowAssertFailed("Assert.IsTrue", message); + /// /// Tests whether the specified condition is false and throws an exception /// if the condition is true. @@ -165,6 +302,12 @@ public static void IsFalse([DoesNotReturnIf(true)] bool? condition) public static void IsFalse([DoesNotReturnIf(true)] bool condition, string? message) => IsFalse(condition, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void IsFalse([DoesNotReturnIf(true)] bool condition, [InterpolatedStringHandlerArgument(nameof(condition))] ref AssertIsFalseInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified condition is false and throws an exception /// if the condition is true. @@ -182,6 +325,12 @@ public static void IsFalse([DoesNotReturnIf(true)] bool condition, string? messa public static void IsFalse([DoesNotReturnIf(true)] bool? condition, string? message) => IsFalse(condition, message, null); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static void IsFalse([DoesNotReturnIf(true)] bool? condition, [InterpolatedStringHandlerArgument(nameof(condition))] ref AssertIsFalseInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + => message.ComputeAssertion(); + /// /// Tests whether the specified condition is false and throws an exception /// if the condition is true. @@ -202,9 +351,9 @@ public static void IsFalse([DoesNotReturnIf(true)] bool? condition, string? mess public static void IsFalse([DoesNotReturnIf(true)] bool condition, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (condition) + if (IsFalseFailing(condition)) { - ThrowAssertFailed("Assert.IsFalse", BuildUserMessage(message, parameters)); + ThrowAssertIsFalseFailed(BuildUserMessage(message, parameters)); } } @@ -228,9 +377,19 @@ public static void IsFalse([DoesNotReturnIf(true)] bool condition, [StringSyntax public static void IsFalse([DoesNotReturnIf(true)] bool? condition, [StringSyntax(StringSyntaxAttribute.CompositeFormat)] string? message, params object?[]? parameters) { - if (condition is true or null) + if (IsFalseFailing(condition)) { - ThrowAssertFailed("Assert.IsFalse", BuildUserMessage(message, parameters)); + ThrowAssertIsFalseFailed(BuildUserMessage(message, parameters)); } } + + private static bool IsFalseFailing(bool? condition) + => condition is true or null; + + private static bool IsFalseFailing(bool condition) + => condition; + + [DoesNotReturn] + private static void ThrowAssertIsFalseFailed(string userMessage) + => ThrowAssertFailed("Assert.IsFalse", userMessage); } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs b/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs index e926389093..66efac037d 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs @@ -12,6 +12,140 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// public sealed partial class Assert { + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertNonStrictThrowsInterpolatedStringHandler + where TException : Exception + { + private readonly StringBuilder? _builder; + private readonly ThrowsExceptionState _state; + + public AssertNonStrictThrowsInterpolatedStringHandler(int literalLength, int formattedCount, Action action, out bool shouldAppend) + { + _state = IsThrowsFailing(action, isStrictType: false, "Throws"); + shouldAppend = _state.FailAction is not null; + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal TException ComputeAssertion() + { + if (_state.FailAction is not null) + { + _state.FailAction(_builder!.ToString()); + } + else + { + return (TException)_state.ExceptionWhenNotFailing!; + } + + // This will not hit, but need it for compiler. + return null!; + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters + } + + [InterpolatedStringHandler] + [EditorBrowsable(EditorBrowsableState.Never)] + public readonly struct AssertThrowsExactlyInterpolatedStringHandler + where TException : Exception + { + private readonly StringBuilder? _builder; + private readonly ThrowsExceptionState _state; + + public AssertThrowsExactlyInterpolatedStringHandler(int literalLength, int formattedCount, Action action, out bool shouldAppend) + { + _state = IsThrowsFailing(action, isStrictType: true, "ThrowsExactly"); + shouldAppend = _state.FailAction is not null; + if (shouldAppend) + { + _builder = new StringBuilder(literalLength + formattedCount); + } + } + + internal TException ComputeAssertion() + { + if (_state.FailAction is not null) + { + _state.FailAction(_builder!.ToString()); + } + else + { + return (TException)_state.ExceptionWhenNotFailing!; + } + + // This will not hit, but need it for compiler. + return null!; + } + + public void AppendLiteral(string value) => _builder!.Append(value); + + public void AppendFormatted(T value) => AppendFormatted(value, format: null); + +#if NETCOREAPP3_1_OR_GREATER + public void AppendFormatted(ReadOnlySpan value) => _builder!.Append(value); + +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(ReadOnlySpan value, int alignment = 0, string? format = null) => AppendFormatted(value.ToString(), alignment, format); +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads +#endif + + // NOTE: All the overloads involving format and/or alignment are not super efficient. + // This code path is only for when an assert is failing, so that's not the common scenario + // and should be okay if not very optimized. + // A more efficient implementation that can be used for .NET 6 and later is to delegate the work to + // the BCL's StringBuilder.AppendInterpolatedStringHandler + public void AppendFormatted(T value, string? format) => _builder!.AppendFormat(null, $"{{0:{format}}}", value); + + public void AppendFormatted(T value, int alignment) => _builder!.AppendFormat(null, $"{{0,{alignment}}}", value); + + public void AppendFormatted(T value, int alignment, string? format) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(string? value) => _builder!.Append(value); + +#pragma warning disable RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning disable RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + public void AppendFormatted(string? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); + + public void AppendFormatted(object? value, int alignment = 0, string? format = null) => _builder!.AppendFormat(null, $"{{0,{alignment}:{format}}}", value); +#pragma warning restore RS0026 // Do not add multiple public overloads with optional parameters +#pragma warning restore RS0027 // API with optional parameter(s) should have the most parameters amongst its public overloads + } + /// /// Asserts that the delegate throws an exception of type /// (or derived type) and throws AssertFailedException if code does not throws exception or throws @@ -39,6 +173,13 @@ public static TException Throws(Action action, string message = "", where TException : Exception => ThrowsException(action, isStrictType: false, message, parameters: messageArgs); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static TException Throws(Action action, [InterpolatedStringHandlerArgument(nameof(action))] ref AssertNonStrictThrowsInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + where TException : Exception + => message.ComputeAssertion(); + /// /// Asserts that the delegate throws an exception of type /// (and not of derived type) and throws AssertFailedException if code does not throws exception or throws @@ -66,6 +207,13 @@ public static TException ThrowsExactly(Action action, string message where TException : Exception => ThrowsException(action, isStrictType: true, message, parameters: messageArgs); + /// +#pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 + public static TException ThrowsExactly(Action action, [InterpolatedStringHandlerArgument(nameof(action))] ref AssertThrowsExactlyInterpolatedStringHandler message) +#pragma warning restore IDE0060 // Remove unused parameter + where TException : Exception + => message.ComputeAssertion(); + /// /// Tests whether the code specified by delegate throws exact given exception /// of type (and not of derived type) and throws AssertFailedException @@ -229,41 +377,18 @@ private static TException ThrowsException(Action action, bool isStri Guard.NotNull(action); Guard.NotNull(message); - string userMessage, finalMessage; - try + ThrowsExceptionState state = IsThrowsFailing(action, isStrictType, assertMethodName); + if (state.FailAction is not null) { - action(); + state.FailAction(BuildUserMessage(message, parameters)); } - catch (Exception ex) + else { - bool isExceptionOfType = isStrictType - ? typeof(TException) == ex.GetType() - : ex is TException; - if (!isExceptionOfType) - { - userMessage = BuildUserMessage(message, parameters); - finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.WrongExceptionThrown, - userMessage, - typeof(TException), - ex.GetType()); - ThrowAssertFailed("Assert." + assertMethodName, finalMessage); - } - - return (TException)ex; + return (TException)state.ExceptionWhenNotFailing!; } - userMessage = BuildUserMessage(message, parameters); - finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.NoExceptionThrown, - userMessage, - typeof(TException)); - ThrowAssertFailed("Assert." + assertMethodName, finalMessage); - // This will not hit, but need it for compiler. - return null; + return null!; } /// @@ -398,7 +523,23 @@ private static async Task ThrowsExceptionAsync(Func(action, isStrictType, assertMethodName).ConfigureAwait(false); + if (state.FailAction is not null) + { + state.FailAction(BuildUserMessage(message, parameters)); + } + else + { + return (TException)state.ExceptionWhenNotFailing!; + } + + // This will not hit, but need it for compiler. + return null!; + } + + private static async Task IsThrowsAsyncFailingAsync(Func action, bool isStrictType, string assertMethodName) + where TException : Exception + { try { await action().ConfigureAwait(false); @@ -409,30 +550,88 @@ private static async Task ThrowsExceptionAsync(Func + { + string finalMessage = string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.WrongExceptionThrown, + userMessage, + typeof(TException), + ex.GetType()); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + }); + } + + return ThrowsExceptionState.CreateFailingState(failAction: userMessage => + { + string finalMessage = string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.NoExceptionThrown, + userMessage, + typeof(TException)); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + }); + } - return (TException)ex; + private static ThrowsExceptionState IsThrowsFailing(Action action, bool isStrictType, string assertMethodName) + where TException : Exception + { + try + { + action(); } + catch (Exception ex) + { + bool isExceptionOfType = isStrictType + ? typeof(TException) == ex.GetType() + : ex is TException; - userMessage = BuildUserMessage(message, parameters); - finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.NoExceptionThrown, - userMessage, - typeof(TException)); - ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + return isExceptionOfType + ? ThrowsExceptionState.CreateNotFailingState(ex) + : ThrowsExceptionState.CreateFailingState(userMessage => + { + string finalMessage = string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.WrongExceptionThrown, + userMessage, + typeof(TException), + ex.GetType()); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + }); + } - // This will not hit, but need it for compiler. - return null!; + return ThrowsExceptionState.CreateFailingState(failAction: userMessage => + { + string finalMessage = string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.NoExceptionThrown, + userMessage, + typeof(TException)); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + }); + } + + private readonly struct ThrowsExceptionState + { + public Exception? ExceptionWhenNotFailing { get; } + + public Action? FailAction { get; } + + private ThrowsExceptionState(Exception? exceptionWhenNotFailing, Action? failAction) + { + // If the assert is failing, failAction should be non-null, and exceptionWhenNotFailing should be null. + // If the assert is not failing, exceptionWhenNotFailing should be non-null, and failAction should be null. + Debug.Assert(exceptionWhenNotFailing is null ^ failAction is null, "Exactly one of exceptionWhenNotFailing and failAction should be null."); + ExceptionWhenNotFailing = exceptionWhenNotFailing; + FailAction = failAction; + } + + public static ThrowsExceptionState CreateFailingState(Action failAction) + => new(exceptionWhenNotFailing: null, failAction); + + public static ThrowsExceptionState CreateNotFailingState(Exception exception) + => new(exception, failAction: null); } } diff --git a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt index 3ceaf8e88e..9572aa2c29 100644 --- a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt @@ -1,4 +1,193 @@ #nullable enable +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AppendLiteral(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AssertAreEqualInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AssertAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, System.IEquatable? expected, System.IEquatable? actual, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AssertAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? expected, TArgument? actual, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AssertAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? expected, TArgument? actual, System.Collections.Generic.IEqualityComparer? comparer, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AssertAreNotEqualInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AssertAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? notExpected, TArgument? actual, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AssertAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? notExpected, TArgument? actual, System.Collections.Generic.IEqualityComparer? comparer, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AssertAreNotSameInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AssertAreNotSameInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? notExpected, TArgument? actual, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AssertAreSameInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AssertAreSameInterpolatedStringHandler(int literalLength, int formattedCount, TArgument? expected, TArgument? actual, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AssertGenericIsInstanceOfTypeInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AssertGenericIsInstanceOfTypeInterpolatedStringHandler(int literalLength, int formattedCount, object? value, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler(int literalLength, int formattedCount, object? value, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AssertIsFalseInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AssertIsFalseInterpolatedStringHandler(int literalLength, int formattedCount, bool? condition, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AssertIsInstanceOfTypeInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AssertIsInstanceOfTypeInterpolatedStringHandler(int literalLength, int formattedCount, object? value, System.Type? expectedType, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AssertIsNotInstanceOfTypeInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AssertIsNotInstanceOfTypeInterpolatedStringHandler(int literalLength, int formattedCount, object? value, System.Type? wrongType, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AssertIsNotNullInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AssertIsNotNullInterpolatedStringHandler(int literalLength, int formattedCount, object? value, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AssertIsNullInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AssertIsNullInterpolatedStringHandler(int literalLength, int formattedCount, object? value, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AssertIsTrueInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AssertIsTrueInterpolatedStringHandler(int literalLength, int formattedCount, bool? condition, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AssertNonGenericAreEqualInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, decimal expected, decimal actual, decimal delta, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, double expected, double actual, double delta, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, float expected, float actual, float delta, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, long expected, long actual, long delta, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, string? expected, string? actual, bool ignoreCase, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AssertNonGenericAreEqualInterpolatedStringHandler(int literalLength, int formattedCount, string? expected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AssertNonGenericAreNotEqualInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, decimal notExpected, decimal actual, decimal delta, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, double notExpected, double actual, double delta, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, float notExpected, float actual, float delta, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, long notExpected, long actual, long delta, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, string? notExpected, string? actual, bool ignoreCase, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AssertNonGenericAreNotEqualInterpolatedStringHandler(int literalLength, int formattedCount, string? notExpected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AssertNonStrictThrowsInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AssertNonStrictThrowsInterpolatedStringHandler(int literalLength, int formattedCount, System.Action! action, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AppendFormatted(object? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AppendFormatted(string? value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AppendFormatted(string? value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AppendFormatted(T value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AppendFormatted(T value, int alignment) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AppendFormatted(T value, int alignment, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AppendFormatted(T value, string? format) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AppendLiteral(string! value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AssertThrowsExactlyInterpolatedStringHandler() -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AssertThrowsExactlyInterpolatedStringHandler(int literalLength, int formattedCount, System.Action! action, out bool shouldAppend) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType dynamicDataSourceType) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, System.Type! dynamicDataDeclaringType) -> void @@ -6,7 +195,39 @@ Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAtt Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.AutoDetect = 2 -> Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType *REMOVED*Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType dynamicDataSourceType = Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Property) -> void *REMOVED*Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, System.Type! dynamicDataDeclaringType, Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType dynamicDataSourceType = Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Property) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(decimal expected, decimal actual, decimal delta, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(double expected, double actual, double delta, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(float expected, float actual, float delta, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(long expected, long actual, long delta, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(string? expected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(System.IEquatable? expected, System.IEquatable? actual, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(T? expected, T? actual, System.Collections.Generic.IEqualityComparer? comparer, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(decimal notExpected, decimal actual, decimal delta, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(double notExpected, double actual, double delta, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(float notExpected, float actual, float delta, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(long notExpected, long actual, long delta, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(string? notExpected, string? actual, bool ignoreCase, System.Globalization.CultureInfo? culture, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotEqual(T? notExpected, T? actual, System.Collections.Generic.IEqualityComparer? comparer, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreNotSame(T? notExpected, T? actual, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreSame(T? expected, T? actual, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool condition, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsFalse(bool? condition, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, System.Type? expectedType, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, out T instance, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsInstanceOfType(object? value, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value, System.Type? wrongType, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotInstanceOfType(object? value, Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNotNull(object? value, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsNull(object? value, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool condition, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool? condition, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler message) -> void +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Throws(System.Action! action, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler message) -> TException! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Throws(System.Action! action, string! message = "", params object![]! messageArgs) -> TException! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsAsync(System.Func! action, string! message = "", params object![]! messageArgs) -> System.Threading.Tasks.Task! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactly(System.Action! action, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler message) -> TException! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactly(System.Action! action, string! message = "", params object![]! messageArgs) -> TException! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactlyAsync(System.Func! action, string! message = "", params object![]! messageArgs) -> System.Threading.Tasks.Task! diff --git a/src/TestFramework/TestFramework/PublicAPI/net/PublicAPI.Shipped.txt b/src/TestFramework/TestFramework/PublicAPI/net/PublicAPI.Shipped.txt new file mode 100644 index 0000000000..7dc5c58110 --- /dev/null +++ b/src/TestFramework/TestFramework/PublicAPI/net/PublicAPI.Shipped.txt @@ -0,0 +1 @@ +#nullable enable diff --git a/src/TestFramework/TestFramework/PublicAPI/net/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework/PublicAPI/net/PublicAPI.Unshipped.txt new file mode 100644 index 0000000000..9a182b770a --- /dev/null +++ b/src/TestFramework/TestFramework/PublicAPI/net/PublicAPI.Unshipped.txt @@ -0,0 +1,33 @@ +#nullable enable +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreEqualInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotEqualInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreNotSameInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertAreSameInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertGenericIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsFalseInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsInstanceOfTypeInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotInstanceOfTypeInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNotNullInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsNullInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreNotEqualInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AppendFormatted(System.ReadOnlySpan value, int alignment = 0, string? format = null) -> void diff --git a/src/TestFramework/TestFramework/TestFramework.csproj b/src/TestFramework/TestFramework/TestFramework.csproj index 8f67b0069d..79ae688ade 100644 --- a/src/TestFramework/TestFramework/TestFramework.csproj +++ b/src/TestFramework/TestFramework/TestFramework.csproj @@ -14,6 +14,9 @@ + + + diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs index e059628875..4760984225 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs @@ -290,6 +290,166 @@ public void AreEqualUsingDynamicsDoesNotFail() #pragma warning restore IDE0004 + public void GenericAreEqual_InterpolatedString_EqualValues_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreEqual(o, o, $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task GenericAreEqual_InterpolatedString_DifferentValues_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreEqual(0, 1, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreEqual failed. Expected:<0>. Actual:<1>. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void GenericAreNotEqual_InterpolatedString_DifferentValues_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreNotEqual(0, 1, $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task GenericAreNotEqual_InterpolatedString_SameValues_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreNotEqual(0, 0, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreNotEqual failed. Expected any value except:<0>. Actual:<0>. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void FloatAreEqual_InterpolatedString_EqualValues_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreEqual(1.0f, 1.1f, delta: 0.2f, $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task FloatAreEqual_InterpolatedString_DifferentValues_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreEqual(1.0f, 1.1f, 0.001f, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreEqual failed. Expected a difference no greater than <0.001> between expected value <1> and actual value <1.1>. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void FloatAreNotEqual_InterpolatedString_DifferentValues_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreNotEqual(1.0f, 1.1f, 0.001f, $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task FloatAreNotEqual_InterpolatedString_SameValues_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreNotEqual(1.0f, 1.1f, 0.2f, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreNotEqual failed. Expected a difference greater than <0.2> between expected value <1> and actual value <1.1>. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void DecimalAreEqual_InterpolatedString_EqualValues_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreEqual(1.0m, 1.1m, delta: 0.2m, $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task DecimalAreEqual_InterpolatedString_DifferentValues_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreEqual(1.0m, 1.1m, 0.001m, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreEqual failed. Expected a difference no greater than <0.001> between expected value <1.0> and actual value <1.1>. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void DecimalAreNotEqual_InterpolatedString_DifferentValues_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreNotEqual(1.0m, 1.1m, 0.001m, $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task DecimalAreNotEqual_InterpolatedString_SameValues_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreNotEqual(1.0m, 1.1m, 0.2m, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreNotEqual failed. Expected a difference greater than <0.2> between expected value <1.0> and actual value <1.1>. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void LongAreEqual_InterpolatedString_EqualValues_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreEqual(1L, 2L, delta: 1L, $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task LongAreEqual_InterpolatedString_DifferentValues_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreEqual(1L, 2L, 0L, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreEqual failed. Expected a difference no greater than <0> between expected value <1> and actual value <2>. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void LongAreNotEqual_InterpolatedString_DifferentValues_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreNotEqual(1L, 2L, 0L, $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task LongAreNotEqual_InterpolatedString_SameValues_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreNotEqual(1L, 2L, 1L, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreNotEqual failed. Expected a difference greater than <1> between expected value <1> and actual value <2>. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void DoubleAreEqual_InterpolatedString_EqualValues_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreEqual(1.0d, 1.1d, delta: 0.2d, $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task DoubleAreEqual_InterpolatedString_DifferentValues_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreEqual(1.0d, 1.1d, 0.001d, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreEqual failed. Expected a difference no greater than <0.001> between expected value <1> and actual value <1.1>. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void DoubleAreNotEqual_InterpolatedString_DifferentValues_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreNotEqual(1.0d, 1.1d, 0.001d, $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task DoubleAreNotEqual_InterpolatedString_SameValues_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreNotEqual(1.0d, 1.1d, 0.2d, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreNotEqual failed. Expected a difference greater than <0.2> between expected value <1> and actual value <1.1>. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + private CultureInfo? GetCultureInfo() => CultureInfo.CurrentCulture; private class TypeOverridesEquals diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreSame.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreSame.cs new file mode 100644 index 0000000000..eaced7c334 --- /dev/null +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreSame.cs @@ -0,0 +1,133 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#nullable enable + +using Microsoft.VisualStudio.TestTools.UnitTesting; + +namespace Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests; + +public partial class AssertTests +{ + public void AreSame_PassSameObject_ShouldPass() + { + object o = new(); + Assert.AreSame(o, o); + } + + public void AreSame_PassDifferentObject_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreSame(new object(), new object())); + Verify(ex.Message == "Assert.AreSame failed. "); + } + + public void AreSame_StringMessage_PassSameObject_ShouldPass() + { + object o = new(); + Assert.AreSame(o, o, "User-provided message"); + } + + public void AreSame_StringMessage_PassDifferentObject_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreSame(new object(), new object(), "User-provided message")); + Verify(ex.Message == "Assert.AreSame failed. User-provided message"); + } + + public void AreSame_InterpolatedString_PassSameObject_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreSame(o, o, $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task AreSame_InterpolatedString_PassDifferentObject_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreSame(new object(), new object(), $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreSame failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void AreSame_MessageArgs_PassSameObject_ShouldPass() + { + object o = new(); + Assert.AreSame(o, o, "User-provided message: {0}", new object().GetType()); + } + + public void AreSame_MessageArgs_PassDifferentObject_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreSame(new object(), new object(), "User-provided message: System.Object type: {0}", new object().GetType())); + Verify(ex.Message == "Assert.AreSame failed. User-provided message: System.Object type: System.Object"); + } + + public void AreNotSame_PassDifferentObject_ShouldPass() + => Assert.AreNotSame(new object(), new object()); + + public void AreSame_BothAreValueTypes_ShouldFailWithSpecializedMessage() + { + Exception ex = VerifyThrows(() => Assert.AreSame(1, 1)); + Verify(ex.Message == "Assert.AreSame failed. Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). "); + } + + public void AreSame_StringMessage_BothAreValueTypes_ShouldFailWithSpecializedMessage() + { + Exception ex = VerifyThrows(() => Assert.AreSame(1, 1, "User-provided message")); + Verify(ex.Message == "Assert.AreSame failed. Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). User-provided message"); + } + + public void AreSame_InterpolatedString_BothAreValueTypes_ShouldFailWithSpecializedMessage() + { + Exception ex = VerifyThrows(() => Assert.AreSame(1, 1, $"User-provided message {new object().GetType()}")); + Verify(ex.Message == "Assert.AreSame failed. Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). User-provided message System.Object"); + } + + public void AreSame_MessageArgs_BothAreValueTypes_ShouldFailWithSpecializedMessage() + { + Exception ex = VerifyThrows(() => Assert.AreSame(1, 1, "User-provided message {0}", new object().GetType())); + Verify(ex.Message == "Assert.AreSame failed. Do not pass value types to AreSame(). Values converted to Object will never be the same. Consider using AreEqual(). User-provided message System.Object"); + } + + public void AreNotSame_PassSameObject_ShouldFail() + { + object o = new(); + Exception ex = VerifyThrows(() => Assert.AreNotSame(o, o)); + Verify(ex.Message == "Assert.AreNotSame failed. "); + } + + public void AreNotSame_StringMessage_PassDifferentObject_ShouldPass() + => Assert.AreNotSame(new object(), new object(), "User-provided message"); + + public void AreNotSame_StringMessage_PassSameObject_ShouldFail() + { + object o = new(); + Exception ex = VerifyThrows(() => Assert.AreNotSame(o, o, "User-provided message")); + Verify(ex.Message == "Assert.AreNotSame failed. User-provided message"); + } + + public void AreNotSame_InterpolatedString_PassDifferentObject_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.AreNotSame(new object(), new object(), $"User-provided message: {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task AreNotSame_InterpolatedString_PassSameObject_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.AreNotSame(o, o, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.AreNotSame failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void AreNotSame_MessageArgs_PassDifferentObject_ShouldPass() + => Assert.AreNotSame(new object(), new object(), "User-provided message: {0}", new object().GetType()); + + public void AreNotSame_MessageArgs_PassSameObject_ShouldFail() + { + object o = new(); + Exception ex = VerifyThrows(() => Assert.AreNotSame(o, o, "User-provided message: System.Object type: {0}", new object().GetType())); + Verify(ex.Message == "Assert.AreNotSame failed. User-provided message: System.Object type: System.Object"); + } +} diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs index fc2d51bf56..4ec85f34d3 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsInstanceOfTypeTests.cs @@ -10,16 +10,81 @@ namespace Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests; [SuppressMessage("Usage", "CA2263:Prefer generic overload when type is known", Justification = "We want to test also the non-generic API")] public partial class AssertTests { - public void InstanceOfTypeShouldFailWhenValueIsNull() => - VerifyThrows(() => Assert.IsInstanceOfType(null, typeof(AssertTests))); + public void InstanceOfTypeShouldFailWhenValueIsNull() + { + Exception ex = VerifyThrows(() => Assert.IsInstanceOfType(null, typeof(AssertTests))); + Verify(ex.Message == "Assert.IsInstanceOfType failed. "); + } + + public void InstanceOfTypeShouldFailWhenTypeIsNull() + { + Exception ex = VerifyThrows(() => Assert.IsInstanceOfType(5, null)); + Verify(ex.Message == "Assert.IsInstanceOfType failed. "); + } - public void InstanceOfTypeShouldFailWhenTypeIsNull() => - VerifyThrows(() => Assert.IsInstanceOfType(5, null)); + public void InstanceOfTypeShouldFailWhenTypeIsMismatched() + { + Exception ex = VerifyThrows(() => Assert.IsInstanceOfType(5, typeof(string))); + Verify(ex.Message == "Assert.IsInstanceOfType failed. Expected type:. Actual type:."); + } public void InstanceOfTypeShouldPassOnSameInstance() => Assert.IsInstanceOfType(5, typeof(int)); public void InstanceOfTypeShouldPassOnHigherInstance() => Assert.IsInstanceOfType(5, typeof(object)); + public void InstanceOfType_WithStringMessage_ShouldFailWhenValueIsNull() + { + Exception ex = VerifyThrows(() => Assert.IsInstanceOfType(null, typeof(AssertTests), "User-provided message")); + Verify(ex.Message == "Assert.IsInstanceOfType failed. User-provided message"); + } + + public void InstanceOfType_WithStringMessage_ShouldFailWhenTypeIsNull() + { + Exception ex = VerifyThrows(() => Assert.IsInstanceOfType(5, null, "User-provided message")); + Verify(ex.Message == "Assert.IsInstanceOfType failed. User-provided message"); + } + + public void InstanceOfType_WithStringMessage_ShouldFailWhenTypeIsMismatched() + { + Exception ex = VerifyThrows(() => Assert.IsInstanceOfType(5, typeof(string), "User-provided message")); + Verify(ex.Message == "Assert.IsInstanceOfType failed. User-provided message Expected type:. Actual type:."); + } + + public void InstanceOfType_WithStringMessage_ShouldPassWhenTypeIsCorrect() + => Assert.IsInstanceOfType(5, typeof(int), "User-provided message"); + + public async Task InstanceOfType_WithInterpolatedString_ShouldFailWhenValueIsNull() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.IsInstanceOfType(null, typeof(AssertTests), $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.IsInstanceOfType failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void InstanceOfType_WithInterpolatedString_ShouldFailWhenTypeIsNull() + { + DummyClassTrackingToStringCalls o = new(); + Exception ex = VerifyThrows(() => Assert.IsInstanceOfType(5, null, $"User-provided message {o}")); + Verify(ex.Message == "Assert.IsInstanceOfType failed. User-provided message DummyClassTrackingToStringCalls"); + Verify(o.WasToStringCalled); + } + + public void InstanceOfType_WithInterpolatedString_ShouldFailWhenTypeIsMismatched() + { + DummyClassTrackingToStringCalls o = new(); + Exception ex = VerifyThrows(() => Assert.IsInstanceOfType(5, typeof(string), $"User-provided message {o}")); + Verify(ex.Message == "Assert.IsInstanceOfType failed. User-provided message DummyClassTrackingToStringCalls Expected type:. Actual type:."); + Verify(o.WasToStringCalled); + } + + public void InstanceOfType_WithInterpolatedString_ShouldPassWhenTypeIsCorrect() + { + DummyClassTrackingToStringCalls o = new(); + Assert.IsInstanceOfType(5, typeof(int), $"User-provided message {o}"); + Verify(!o.WasToStringCalled); + } + public void InstanceNotOfTypeShouldFailWhenValueIsNull() => Assert.IsNotInstanceOfType(null, typeof(object)); public void InstanceNotOfTypeShouldFailWhenTypeIsNull() => @@ -30,8 +95,17 @@ public void InstanceNotOfTypeShouldFailWhenTypeIsNull() => public void InstanceNotOfTypeShouldPassOnSubInstance() => Assert.IsNotInstanceOfType(new object(), typeof(int)); [TestMethod] - public void IsInstanceOfTypeUsingGenericType_WhenValueIsNull_Fails() => - VerifyThrows(() => Assert.IsInstanceOfType(null)); + public void IsInstanceOfTypeUsingGenericType_WhenValueIsNull_Fails() + { + Exception ex = VerifyThrows(() => Assert.IsInstanceOfType(null)); + Verify(ex.Message == "Assert.IsInstanceOfType failed. "); + } + + public void IsInstanceOfTypeUsingGenericType_WhenTypeMismatch_Fails() + { + Exception ex = VerifyThrows(() => Assert.IsInstanceOfType(5)); + Verify(ex.Message == "Assert.IsInstanceOfType failed. Expected type:. Actual type:."); + } [TestMethod] public void IsInstanceOfTypeUsingGenericTypeWithOutParameter_WhenValueIsNull_Fails() @@ -41,6 +115,12 @@ public void IsInstanceOfTypeUsingGenericTypeWithOutParameter_WhenValueIsNull_Fai Verify(assertTests is null); } + public void IsInstanceOfTypeUsingGenericTypeWithOutParameter_WhenTypeMismatch_Fails() + { + Exception ex = VerifyThrows(() => Assert.IsInstanceOfType(5, out _)); + Verify(ex.Message == "Assert.IsInstanceOfType failed. Expected type:. Actual type:."); + } + [TestMethod] public void IsInstanceOfTypeUsingGenericType_OnSameInstance_DoesNotThrow() => Assert.IsInstanceOfType(5); diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsNull.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsNull.cs index bec3b88580..15eb6d2249 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsNull.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsNull.cs @@ -7,10 +7,53 @@ using TestFramework.ForTestingMSTest; -namespace Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests.Assertions; +namespace Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests; public partial class AssertTests : TestContainer { + public void IsNull_PassNull_ShouldPass() + => Assert.IsNull(null); + + public void IsNull_PassNonNull_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.IsNull(new object())); + Verify(ex.Message == "Assert.IsNull failed. "); + } + + public void IsNull_StringMessage_PassNull_ShouldPass() + => Assert.IsNull(null, "User-provided message"); + + public void IsNull_StringMessage_PassNonNull_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.IsNull(new object(), "User-provided message")); + Verify(ex.Message == "Assert.IsNull failed. User-provided message"); + } + + public void IsNull_InterpolatedString_PassNull_ShouldPass() + { + DummyClassTrackingToStringCalls o = new(); + Assert.IsNull(null, $"User-provided message {o}"); + Verify(!o.WasToStringCalled); + } + + public async Task IsNull_InterpolatedString_PassNonNull_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.IsNull(new object(), $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.IsNull failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void IsNull_MessageFormat_PassNull_ShouldPass() + => Assert.IsNull(null, "User-provided message {0}", new object().GetType()); + + public void IsNull_MessageFormat_PassNonNull_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.IsNull(new object(), "User-provided message {0}", new object().GetType())); + Verify(ex.Message == "Assert.IsNull failed. User-provided message System.Object"); + } + public void IsNotNull_WhenNonNullNullableValue_DoesNotThrowAndLearnNotNull() { object? obj = GetObj(); @@ -25,6 +68,15 @@ public void IsNotNull_WhenNonNullNullableValueAndMessage_DoesNotThrowAndLearnNot _ = obj.ToString(); // No potential NRE warning } + public void IsNotNull_WhenNonNullNullableValueAndInterpolatedStringMessage_DoesNotThrowAndLearnNotNull() + { + object? obj = GetObj(); + DummyClassTrackingToStringCalls o = new(); + Assert.IsNotNull(obj, $"my message {o}"); + Verify(!o.WasToStringCalled); + _ = obj.ToString(); // No potential NRE warning + } + public void IsNotNull_WhenNonNullNullableValueAndCompositeMessage_DoesNotThrowAndLearnNotNull() { object? obj = GetObj(); @@ -32,5 +84,30 @@ public void IsNotNull_WhenNonNullNullableValueAndCompositeMessage_DoesNotThrowAn _ = obj.ToString(); // No potential NRE warning } - private object? GetObj() => new(); + public void IsNotNull_PassNull_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.IsNotNull(null)); + Verify(ex.Message == "Assert.IsNotNull failed. "); + } + + public void IsNotNull_StringMessage_PassNonNull_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.IsNotNull(null, "User-provided message")); + Verify(ex.Message == "Assert.IsNotNull failed. User-provided message"); + } + + public async Task IsNotNull_InterpolatedString_PassNonNull_ShouldFail() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.IsNotNull(null, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.IsNotNull failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + Verify(o.WasToStringCalled); + } + + public void IsNotNull_MessageFormat_PassNonNull_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.IsNotNull(null, "User-provided message {0}", new object().GetType())); + Verify(ex.Message == "Assert.IsNotNull failed. User-provided message System.Object"); + } } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsTrueTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsTrueTests.cs index 437a0919f9..3cf8d1ea23 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsTrueTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.IsTrueTests.cs @@ -7,18 +7,247 @@ namespace Microsoft.VisualStudio.TestPlatform.TestFramework.UnitTests; public partial class AssertTests { - public void IsFalseNullableBooleansShouldFailWithNull() + public void IsFalseNullableBooleanShouldFailWithNull() { bool? nullBool = null; Exception ex = VerifyThrows(() => Assert.IsFalse(nullBool)); - Verify(ex.Message.Contains("Assert.IsFalse failed")); + Verify(ex.Message == "Assert.IsFalse failed. "); } - public void IsTrueNullableBooleansShouldFailWithNull() + public void IsFalseNullableBooleanShouldFailWithTrue() + { + bool? nullBool = true; + Exception ex = VerifyThrows(() => Assert.IsFalse(nullBool)); + Verify(ex.Message == "Assert.IsFalse failed. "); + } + + public void IsFalseNullableBooleanShouldNotFailWithFalse() + { + bool? nullBool = false; + Assert.IsFalse(nullBool); + } + + public void IsFalseBooleanShouldFailWithTrue() + { + Exception ex = VerifyThrows(() => Assert.IsFalse(true)); + Verify(ex.Message == "Assert.IsFalse failed. "); + } + + public void IsFalseBooleanShouldNotFailWithFalse() + => Assert.IsFalse(false); + + public void IsFalseNullableBooleanStringMessageShouldFailWithNull() { bool? nullBool = null; + Exception ex = VerifyThrows(() => Assert.IsFalse(nullBool, "User-provided message")); + Verify(ex.Message == "Assert.IsFalse failed. User-provided message"); + } + public void IsFalseNullableBooleanStringMessageShouldFailWithTrue() + { + bool? nullBool = true; + Exception ex = VerifyThrows(() => Assert.IsFalse(nullBool, "User-provided message")); + Verify(ex.Message == "Assert.IsFalse failed. User-provided message"); + } + + public void IsFalseNullableBooleanStringMessageShouldNotFailWithFalse() + { + bool? nullBool = false; + Assert.IsFalse(nullBool, "User-provided message"); + } + + public void IsFalseBooleanStringMessageShouldFailWithTrue() + { + Exception ex = VerifyThrows(() => Assert.IsFalse(true, "User-provided message")); + Verify(ex.Message == "Assert.IsFalse failed. User-provided message"); + } + + public void IsFalseBooleanStringMessageShouldNotFailWithFalse() + => Assert.IsFalse(false, "User-provided message"); + + public async Task IsFalseNullableBooleanInterpolatedStringMessageShouldFailWithNull() + { + bool? nullBool = null; + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.IsFalse(nullBool, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.IsFalse failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + } + + public async Task IsFalseNullableBooleanInterpolatedStringMessageShouldFailWithTrue() + { + bool? nullBool = true; + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.IsFalse(nullBool, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.IsFalse failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + } + + public void IsFalseNullableBooleanInterpolatedStringMessageShouldNotFailWithFalse() + { + bool? nullBool = false; + Assert.IsFalse(nullBool, $"User-provided message. Input: {nullBool}"); + } + + public async Task IsFalseBooleanInterpolatedStringMessageShouldFailWithTrue() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.IsFalse(true, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.IsFalse failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + } + + public void IsFalseBooleanInterpolatedStringMessageShouldNotFailWithFalse() + => Assert.IsFalse(false, $"User-provided message. Input: {false}"); + + public void IsFalseNullableBooleanMessageArgsShouldFailWithNull() + { + bool? nullBool = null; + Exception ex = VerifyThrows(() => Assert.IsFalse(nullBool, "User-provided message. Input: {0}", nullBool)); + Verify(ex.Message == "Assert.IsFalse failed. User-provided message. Input: "); + } + + public void IsFalseNullableBooleanMessageArgsShouldFailWithTrue() + { + bool? nullBool = true; + Exception ex = VerifyThrows(() => Assert.IsFalse(nullBool, "User-provided message. Input: {0}", nullBool)); + Verify(ex.Message == "Assert.IsFalse failed. User-provided message. Input: True"); + } + + public void IsFalseNullableBooleanMessageArgsShouldNotFailWithFalse() + { + bool? nullBool = false; + Assert.IsFalse(nullBool, "User-provided message. Input: {0}", nullBool); + } + + public void IsFalseBooleanMessageArgsShouldFailWithTrue() + { + Exception ex = VerifyThrows(() => Assert.IsFalse(true, "User-provided message. Input: {0}", true)); + Verify(ex.Message == "Assert.IsFalse failed. User-provided message. Input: True"); + } + + public void IsFalseBooleanMessageArgsShouldNotFailWithFalse() + => Assert.IsFalse(false, "User-provided message. Input: {0}", false); + + public void IsTrueNullableBooleanShouldFailWithNull() + { + bool? nullBool = null; Exception ex = VerifyThrows(() => Assert.IsTrue(nullBool)); - Verify(ex.Message.Contains("Assert.IsTrue failed")); + Verify(ex.Message == "Assert.IsTrue failed. "); } + + public void IsTrueNullableBooleanShouldFailWithFalse() + { + bool? nullBool = false; + Exception ex = VerifyThrows(() => Assert.IsTrue(nullBool)); + Verify(ex.Message == "Assert.IsTrue failed. "); + } + + public void IsTrueNullableBooleanShouldNotFailWithTrue() + { + bool? nullBool = true; + Assert.IsTrue(nullBool); + } + + public void IsTrueBooleanShouldFailWithFalse() + { + Exception ex = VerifyThrows(() => Assert.IsTrue(false)); + Verify(ex.Message == "Assert.IsTrue failed. "); + } + + public void IsTrueBooleanShouldNotFailWithTrue() + => Assert.IsTrue(true); + + public void IsTrueNullableBooleanStringMessageShouldFailWithNull() + { + bool? nullBool = null; + Exception ex = VerifyThrows(() => Assert.IsTrue(nullBool, "User-provided message")); + Verify(ex.Message == "Assert.IsTrue failed. User-provided message"); + } + + public void IsTrueNullableBooleanStringMessageShouldFailWithFalse() + { + bool? nullBool = false; + Exception ex = VerifyThrows(() => Assert.IsTrue(nullBool, "User-provided message")); + Verify(ex.Message == "Assert.IsTrue failed. User-provided message"); + } + + public void IsTrueNullableBooleanStringMessageShouldNotFailWithTrue() + { + bool? nullBool = true; + Assert.IsTrue(nullBool, "User-provided message"); + } + + public void IsTrueBooleanStringMessageShouldFailWithFalse() + { + Exception ex = VerifyThrows(() => Assert.IsTrue(false, "User-provided message")); + Verify(ex.Message == "Assert.IsTrue failed. User-provided message"); + } + + public void IsTrueBooleanStringMessageShouldNotFailWithTrue() + => Assert.IsTrue(true, "User-provided message"); + + public async Task IsTrueNullableBooleanInterpolatedStringMessageShouldFailWithNull() + { + bool? nullBool = null; + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.IsTrue(nullBool, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.IsTrue failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + } + + public async Task IsTrueNullableBooleanInterpolatedStringMessageShouldFailWithFalse() + { + bool? nullBool = false; + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.IsTrue(nullBool, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.IsTrue failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + } + + public void IsTrueNullableBooleanInterpolatedStringMessageShouldNotFailWithTrue() + { + bool? nullBool = true; + Assert.IsTrue(nullBool, $"User-provided message. Input: {nullBool}"); + } + + public async Task IsTrueBooleanInterpolatedStringMessageShouldFailWithFalse() + { + DummyClassTrackingToStringCalls o = new(); + DateTime dateTime = DateTime.Now; + Exception ex = await VerifyThrowsAsync(async () => Assert.IsTrue(false, $"User-provided message. {o}, {o,35}, {await GetHelloStringAsync()}, {new DummyIFormattable()}, {dateTime:tt}, {dateTime,5:tt}")); + Verify(ex.Message == $"Assert.IsTrue failed. User-provided message. DummyClassTrackingToStringCalls, DummyClassTrackingToStringCalls, Hello, DummyIFormattable.ToString(), {string.Format(null, "{0:tt}", dateTime)}, {string.Format(null, "{0,5:tt}", dateTime)}"); + } + + public void IsTrueBooleanInterpolatedStringMessageShouldNotFailWithTrue() + => Assert.IsTrue(true, $"User-provided message. Input: {true}"); + + public void IsTrueNullableBooleanMessageArgsShouldFailWithNull() + { + bool? nullBool = null; + Exception ex = VerifyThrows(() => Assert.IsTrue(nullBool, "User-provided message. Input: {0}", nullBool)); + Verify(ex.Message == "Assert.IsTrue failed. User-provided message. Input: "); + } + + public void IsTrueNullableBooleanMessageArgsShouldFailWithFalse() + { + bool? nullBool = false; + Exception ex = VerifyThrows(() => Assert.IsTrue(nullBool, "User-provided message. Input: {0}", nullBool)); + Verify(ex.Message == "Assert.IsTrue failed. User-provided message. Input: False"); + } + + public void IsTrueNullableBooleanMessageArgsShouldNotFailWithTrue() + { + bool? nullBool = true; + Assert.IsTrue(nullBool, "User-provided message. Input: {0}", nullBool); + } + + public void IsTrueBooleanMessageArgsShouldFailWithFalse() + { + Exception ex = VerifyThrows(() => Assert.IsTrue(false, "User-provided message. Input: {0}", false)); + Verify(ex.Message == "Assert.IsTrue failed. User-provided message. Input: False"); + } + + public void IsTrueBooleanMessageArgsShouldNotFailWithTrue() + => Assert.IsTrue(true, "User-provided message. Input: {0}", true); } diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs index 8b3584fc46..49cdeb4897 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.cs @@ -39,4 +39,24 @@ public void BuildUserMessageDoesNotThrowWhenMessageContainsInvalidStringFormatCo Verify(message == "{"); } #endregion + + private static Task GetHelloStringAsync() + => Task.FromResult("Hello"); + + private sealed class DummyClassTrackingToStringCalls + { + public bool WasToStringCalled { get; private set; } + + public override string ToString() + { + WasToStringCalled = true; + return nameof(DummyClassTrackingToStringCalls); + } + } + + private sealed class DummyIFormattable : IFormattable + { + public string ToString(string format, IFormatProvider formatProvider) + => "DummyIFormattable.ToString()"; + } } diff --git a/test/Utilities/TestFramework.ForTestingMSTest/TestContainer.cs b/test/Utilities/TestFramework.ForTestingMSTest/TestContainer.cs index 0c85b5f063..5c4cd8aff2 100644 --- a/test/Utilities/TestFramework.ForTestingMSTest/TestContainer.cs +++ b/test/Utilities/TestFramework.ForTestingMSTest/TestContainer.cs @@ -80,6 +80,26 @@ public static Exception VerifyThrows( return null; } + public static async Task VerifyThrowsAsync( + Func taskGetter, + [CallerArgumentExpression(nameof(taskGetter))] string? expression = default, + [CallerMemberName] string? caller = default, + [CallerFilePath] string? filePath = default, + [CallerLineNumber] int lineNumber = default) + { + try + { + await taskGetter(); + } + catch (Exception ex) + { + return ex; + } + + Throw(expression, caller, filePath, lineNumber); + return null; + } + public static T VerifyThrows( Action action, [CallerArgumentExpression(nameof(action))] @@ -102,6 +122,28 @@ public static T VerifyThrows( return null; } + public static async Task VerifyThrowsAsync( + Func taskGetter, + [CallerArgumentExpression(nameof(taskGetter))] + string? expression = default, + [CallerMemberName] string? caller = default, + [CallerFilePath] string? filePath = default, + [CallerLineNumber] int lineNumber = default) + where T : Exception + { + try + { + await taskGetter(); + } + catch (T ex) + { + return ex; + } + + Throw(expression, caller, filePath, lineNumber); + return null; + } + public static void Fail( [CallerMemberName] string? caller = default, [CallerFilePath] string? filePath = default, From f2886eb3b0517f465ae7e35e62df135014e7c0d7 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sat, 4 Jan 2025 10:41:26 +0100 Subject: [PATCH 214/273] [main] Update dependencies from microsoft/testanywhere (#4499) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 309409e050..7a9e0a79c0 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -17,9 +17,9 @@ https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage d4a113f856a31bcdcbf6e08da8928961c98bb497 - + https://github.com/microsoft/testanywhere - 1b35871af094500bb7bf28aa23b61d7135e1fca2 + 2a22637b3897dea2062a1ca574817772bc9346f5 diff --git a/eng/Versions.props b/eng/Versions.props index cfeb2dc685..ef78047a82 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,6 +10,6 @@ 10.0.0-beta.24604.4 17.14.0-preview.24630.1 - 1.0.0-alpha.24630.3 + 1.0.0-alpha.25053.2 From 0b65aa24e50933fcc7aa063943ae8712bd7b40c6 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sat, 4 Jan 2025 10:42:03 +0100 Subject: [PATCH 215/273] Add analyzer for value type usage with Assert.AreSame (#4493) --- .../AnalyzerReleases.Unshipped.md | 7 +- ...voidAssertAreSameWithValueTypesAnalyzer.cs | 78 +++++++++++++++++++ .../MSTest.Analyzers/Helpers/DiagnosticIds.cs | 1 + .../MSTest.Analyzers/PublicAPI.Unshipped.txt | 4 + .../MSTest.Analyzers/Resources.Designer.cs | 27 +++++++ src/Analyzers/MSTest.Analyzers/Resources.resx | 11 ++- .../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 ++++ ...ssertAreSameWithValueTypesAnalyzerTests.cs | 60 ++++++++++++++ 20 files changed, 381 insertions(+), 2 deletions(-) create mode 100644 src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs create mode 100644 test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs diff --git a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md index 6eea619003..2bbee99456 100644 --- a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md +++ b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md @@ -1,2 +1,7 @@ -; Unshipped analyzer release +; Unshipped analyzer release ; https://github.com/dotnet/roslyn-analyzers/blob/main/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md +### New Rules + +Rule ID | Category | Severity | Notes +--------|----------|----------|------- +MSTEST0038 | `Usage` | Warning | AvoidAssertAreSameWithValueTypesAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0038) diff --git a/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs new file mode 100644 index 0000000000..fc6a8b0fec --- /dev/null +++ b/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs @@ -0,0 +1,78 @@ +// 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 Microsoft.CodeAnalysis.Operations; + +using MSTest.Analyzers.Helpers; +using MSTest.Analyzers.RoslynAnalyzerHelpers; + +namespace MSTest.Analyzers; + +/// +/// MSTEST0025: . +/// +[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] +public sealed class AvoidAssertAreSameWithValueTypesAnalyzer : DiagnosticAnalyzer +{ + private static readonly LocalizableResourceString Title = new(nameof(Resources.AvoidAssertAreSameWithValueTypesTitle), Resources.ResourceManager, typeof(Resources)); + private static readonly LocalizableResourceString MessageFormat = new(nameof(Resources.AvoidAssertAreSameWithValueTypesMessageFormat), Resources.ResourceManager, typeof(Resources)); + private static readonly LocalizableResourceString Description = new(nameof(Resources.AvoidAssertAreSameWithValueTypesDescription), Resources.ResourceManager, typeof(Resources)); + + internal static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create( + DiagnosticIds.AvoidAssertAreSameWithValueTypesRuleId, + Title, + MessageFormat, + Description, + Category.Usage, + DiagnosticSeverity.Warning, + isEnabledByDefault: true); + + public override ImmutableArray SupportedDiagnostics { get; } + = ImmutableArray.Create(Rule); + + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + + context.RegisterCompilationStartAction(context => + { + Compilation compilation = context.Compilation; + INamedTypeSymbol? assertSymbol = compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingAssert); + if (assertSymbol is not null) + { + context.RegisterOperationAction(context => AnalyzeOperation(context, assertSymbol), OperationKind.Invocation); + } + }); + } + + private static void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol assertSymbol) + { + var operation = (IInvocationOperation)context.Operation; + IMethodSymbol targetMethod = operation.TargetMethod; + if (targetMethod.Name != "AreSame" || + !assertSymbol.Equals(operation.TargetMethod.ContainingType, SymbolEqualityComparer.Default)) + { + return; + } + + IArgumentOperation? argExpected = operation.Arguments.FirstOrDefault(arg => arg.Parameter?.Ordinal == 0); + IArgumentOperation? argActual = operation.Arguments.FirstOrDefault(arg => arg.Parameter?.Ordinal == 1); + if (argExpected is null || argActual is null) + { + return; + } + + if (argExpected.Value.WalkDownConversion().Type?.IsValueType == true || + argActual.Value.WalkDownConversion().Type?.IsValueType == true) + { + context.ReportDiagnostic(operation.CreateDiagnostic(Rule)); + } + } +} diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs b/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs index 79c269bbe8..7c92ad22ca 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs @@ -42,4 +42,5 @@ internal static class DiagnosticIds public const string UseDeploymentItemWithTestMethodOrTestClassRuleId = "MSTEST0035"; public const string DoNotUseShadowingRuleId = "MSTEST0036"; public const string UseProperAssertMethodsRuleId = "MSTEST0037"; + public const string AvoidAssertAreSameWithValueTypesRuleId = "MSTEST0038"; } diff --git a/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt b/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt index 7dc5c58110..3f880fefe8 100644 --- a/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt +++ b/src/Analyzers/MSTest.Analyzers/PublicAPI.Unshipped.txt @@ -1 +1,5 @@ #nullable enable +MSTest.Analyzers.AvoidAssertAreSameWithValueTypesAnalyzer +MSTest.Analyzers.AvoidAssertAreSameWithValueTypesAnalyzer.AvoidAssertAreSameWithValueTypesAnalyzer() -> void +override MSTest.Analyzers.AvoidAssertAreSameWithValueTypesAnalyzer.Initialize(Microsoft.CodeAnalysis.Diagnostics.AnalysisContext! context) -> void +override MSTest.Analyzers.AvoidAssertAreSameWithValueTypesAnalyzer.SupportedDiagnostics.get -> System.Collections.Immutable.ImmutableArray diff --git a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs index 7ebb84e567..8b7c3bc0da 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs @@ -180,6 +180,33 @@ internal static string AssertionArgsShouldBePassedInCorrectOrderTitle { } } + /// + /// Looks up a localized string similar to Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens.. + /// + internal static string AvoidAssertAreSameWithValueTypesDescription { + get { + return ResourceManager.GetString("AvoidAssertAreSameWithValueTypesDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. + /// + internal static string AvoidAssertAreSameWithValueTypesMessageFormat { + get { + return ResourceManager.GetString("AvoidAssertAreSameWithValueTypesMessageFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Don't use 'Assert.AreSame' with value types. + /// + internal static string AvoidAssertAreSameWithValueTypesTitle { + get { + return ResourceManager.GetString("AvoidAssertAreSameWithValueTypesTitle", resourceCulture); + } + } + /// /// 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.. /// diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx index 064eb11cd9..93e6d7f3da 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.resx +++ b/src/Analyzers/MSTest.Analyzers/Resources.resx @@ -543,4 +543,13 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - + + Don't use 'Assert.AreSame' with value types + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index c00244ab27..6e330b099f 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -117,6 +117,21 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: Argumenty kontrolního výrazu musí být předány ve správném pořadí + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. Preferujte Assert.ThrowsException nebo Assert.ThrowsExceptionAsync před [ExpectedException], protože zajišťuje, že očekávanou výjimku vyvolá pouze očekávané volání. Rozhraní API assert také poskytují větší flexibilitu a umožňují vyhodnocovat další vlastnosti výjimky. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 1096835671..e8158f968a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -117,6 +117,21 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte Assertionsargumente sollten in der richtigen Reihenfolge übergeben werden. + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. „Assert.ThrowsException“ oder „Assert.ThrowsExceptionAsync“ gegenüber „[ExpectedException]“ bevorzugen, da dadurch sichergestellt wird, dass nur der erwartete Aufruf die erwartete Ausnahme auslöst. Die Assert-APIs bieten außerdem mehr Flexibilität und ermöglichen es Ihnen, zusätzliche Eigenschaften der Ausführung zu bestätigen. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 0df0f975dd..d906f03e01 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -117,6 +117,21 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: Los argumentos de aserción deben pasarse en el orden correcto + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. Preferir "Assert.ThrowsException" o "Assert.ThrowsExceptionAsync" en lugar de '[ExpectedException]' ya que garantiza que solo la llamada esperada inicia la excepción esperada. Las API de aserción también proporcionan más flexibilidad y le permiten declarar propiedades adicionales de la ejecución. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index a35f7d47a4..5007193e4a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -117,6 +117,21 @@ Le type doit être une classe Les arguments d’assertion doivent être passés dans l’ordre approprié + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. Préférez « Assert.ThrowsException » ou « Assert.ThrowsExceptionAsync » à « [ExpectedException] », car cela assure que seul l’appel attendu lève l’exception attendue. Les API d’assertion offrent également plus de flexibilité et vous permettent de déclarer des propriétés supplémentaires de l’exception. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index 5673cca759..04e4eab6eb 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -117,6 +117,21 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: Gli argomenti dell'asserzione devono essere passati nell'ordine corretto + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. Preferisci 'Assert.ThrowsException' o 'Assert.ThrowsExceptionAsync' a '[ExpectedException]', perché garantisce che solo la chiamata prevista lanci l'eccezione prevista. Le API di asserzione forniscono anche una maggiore flessibilità e consentono l’asserzione delle proprietà aggiuntive dell'eccezione. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 0ff2e8bd4f..ef8201b9f2 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -117,6 +117,21 @@ The type declaring these methods should also respect the following rules: アサーション引数は正しい順序で渡す必要があります + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. '[ExpectedException]' よりも 'Assert.ThrowsException' または 'Assert.ThrowsExceptionAsync' を優先します。これは、予期された呼び出しのみが予期された例外をスローするようにするためです。アサート API も柔軟性が高く、例外の追加プロパティをアサートできます。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 1ae3a6c497..01418be2c5 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -117,6 +117,21 @@ The type declaring these methods should also respect the following rules: 어설션 인수는 올바른 순서로 전달되어야 합니다. + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. 예상되는 호출만 예상되는 예외를 throw하도록 보장하는 '[ExpectedException]'보다 'Assert.ThrowsException' 또는 'Assert.ThrowsExceptionAsync'를 사용하는 것이 좋습니다. 또한 Assert API는 더 많은 유연성을 제공하고 예외의 추가 속성을 어설션할 수 있도록 합니다. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 73ec8d0837..71f8dc79e2 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -117,6 +117,21 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu Argumenty asercji powinny być przekazywane w poprawnej kolejności + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. Preferuj element „Assert.ThrowsException” lub „Assert.ThrowsExceptionAsync” niż „[ExpectedException]”, ponieważ gwarantuje, że tylko oczekiwane wywołanie zgłosi oczekiwany wyjątek. Interfejsy API potwierdzenia zapewniają również większą elastyczność i pozwalają na potwierdzenie dodatkowych właściwości wyjątku. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 31c0643151..07cc18781f 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -117,6 +117,21 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: Os argumentos de asserção devem ser passados na ordem correta + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. Prefira 'Assert.ThrowsException' ou 'Assert.ThrowsExceptionAsync' '[ExpectedException]', pois isso garante que somente a chamada esperada lance a exceção esperada. As APIs assert também fornecem mais flexibilidade e permitem declarar propriedades extras da exceção. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index b9ce60a39d..ec3a3f092e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -120,6 +120,21 @@ The type declaring these methods should also respect the following rules: Аргументы проверочных утверждений должны передаваться в правильном порядке + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. Предпочитайте "Assert.ThrowsException" или "Assert.ThrowsExceptionAsync" вместо "[ExpectedException]", так как это гарантирует, что только ожидаемый вызов приводит к ожидаемому исключению. API-интерфейсы утверждения также обеспечивают дополнительную гибкость и позволяют утверждать дополнительные свойства исключения. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index a2552a12f6..efebdd5ad3 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -117,6 +117,21 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: Onay deyimi bağımsız değişkenleri doğru sıralama düzeninde geçirilmelidir + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. Yalnızca beklenen çağrının beklenen özel durumu oluşturmasını sağladığı için '[ExpectedException]' yerine 'Assert.ThrowsException' veya 'Assert.ThrowsExceptionAsync' tercih edin. Onaylama API'leri de daha fazla esneklik sağlar ve özel durumun ek özelliklerini onaylamanıza izin verir. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 6fa047a137..2c8a1b9bc0 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -117,6 +117,21 @@ The type declaring these methods should also respect the following rules: 应按正确的顺序传递断言参数 + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. 首选 "Assert.ThrowsException" 或 "Assert.ThrowsExceptionAsync" 而不是 "[ExpectedException]",因为它确保只有预期调用才会引发预期异常。断言 API 还提供更多的灵活性,并允许你断言异常的额外属性。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 9251582b4d..c8c3516c3c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -117,6 +117,21 @@ The type declaring these methods should also respect the following rules: 應該以正確的順序傳遞判斷提示引數 + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + + + + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + + + + Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' with value types + + 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. 偏好 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' 而非 '[ExpectedException]',因為它可確保只有預期的呼叫會擲出預期的例外狀況。判斷提示 API 也提供更多彈性,並允許您斷言例外狀況的額外屬性。 diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs new file mode 100644 index 0000000000..42c8306e5e --- /dev/null +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs @@ -0,0 +1,60 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using VerifyCS = MSTest.Analyzers.Test.CSharpCodeFixVerifier< + MSTest.Analyzers.AvoidAssertAreSameWithValueTypesAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace MSTest.Analyzers.UnitTests; + +[TestClass] +public sealed class AvoidAssertAreSameWithValueTypesAnalyzerTests +{ + [TestMethod] + public async Task UseAssertAreSameWithValueTypes_Diagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void TestMethod() + { + // Both are value types + [|Assert.AreSame(0, 0)|]; + [|Assert.AreSame(0, 0, "Message")|]; + [|Assert.AreSame(0, 0, "Message {0}", "Arg")|]; + [|Assert.AreSame(message: "Message", expected: 0, actual: 0)|]; + + [|Assert.AreSame(0, 0)|]; + [|Assert.AreSame(0, 0, "Message")|]; + [|Assert.AreSame(0, 0, "Message {0}", "Arg")|]; + [|Assert.AreSame(message: "Message", expected: 0, actual: 0)|]; + + // Expected is value type. This is always-failing assert. + [|Assert.AreSame("0", 0)|]; + [|Assert.AreSame("0", 0, "Message")|]; + [|Assert.AreSame("0", 0, "Message {0}", "Arg")|]; + [|Assert.AreSame(message: "Message", expected: "0", actual: 0)|]; + + // Actual is value type. This is always-failing assert. + [|Assert.AreSame(0, "0")|]; + [|Assert.AreSame(0, "0", "Message")|]; + [|Assert.AreSame(0, "0", "Message {0}", "Arg")|]; + [|Assert.AreSame(message: "Message", expected: 0, actual: "0")|]; + + // Both are reference types. No diagnostic. + Assert.AreSame("0", "0"); + Assert.AreSame("0", "0", "Message"); + Assert.AreSame("0", "0", "Message {0}", "Arg"); + Assert.AreSame(message: "Message", expected: "0", actual: "0"); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } +} From 5f134f587bb05ef5b98507a05e3c29dfae31f0da Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sat, 4 Jan 2025 10:43:39 +0100 Subject: [PATCH 216/273] Allow DynamicData source to be on base types (#4482) --- .../DynamicDataOperations.cs | 46 +++++- .../MSTest.TestAdapter/Execution/TypeCache.cs | 5 +- .../SourceGeneratedReflectionOperations.cs | 19 ++- .../Interfaces/IReflectionOperations2.cs | 4 +- .../Services/ReflectionOperations2.cs | 14 +- .../DynamicDataShouldBeValidAnalyzer.cs | 59 +++++++- .../Parameterized tests/DynamicDataTests.cs | 18 ++- .../Parameterized tests/DynamicDataTests.cs | 16 ++ .../DynamicDataTests.cs | 139 ++++++++++++------ .../DynamicDataShouldBeValidAnalyzerTests.cs | 71 +++++++++ 10 files changed, 318 insertions(+), 73 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs b/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs index d78223016c..954b9b435e 100644 --- a/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/DynamicDataOperations.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// 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.VisualStudio.TestTools.UnitTesting; @@ -19,11 +19,11 @@ public IEnumerable GetData(Type? _dynamicDataDeclaringType, DynamicDat { case DynamicDataSourceType.AutoDetect: #pragma warning disable IDE0045 // Convert to conditional expression - it becomes less readable. - if (PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredProperty(_dynamicDataDeclaringType, _dynamicDataSourceName) is { } dynamicDataPropertyInfo) + if (GetPropertyConsideringInheritance(_dynamicDataDeclaringType, _dynamicDataSourceName) is { } dynamicDataPropertyInfo) { obj = GetDataFromProperty(dynamicDataPropertyInfo); } - else if (PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredMethod(_dynamicDataDeclaringType, _dynamicDataSourceName) is { } dynamicDataMethodInfo) + else if (GetMethodConsideringInheritance(_dynamicDataDeclaringType, _dynamicDataSourceName) is { } dynamicDataMethodInfo) { obj = GetDataFromMethod(dynamicDataMethodInfo); } @@ -35,14 +35,14 @@ public IEnumerable GetData(Type? _dynamicDataDeclaringType, DynamicDat break; case DynamicDataSourceType.Property: - PropertyInfo property = PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredProperty(_dynamicDataDeclaringType, _dynamicDataSourceName) + PropertyInfo property = GetPropertyConsideringInheritance(_dynamicDataDeclaringType, _dynamicDataSourceName) ?? throw new ArgumentNullException($"{DynamicDataSourceType.Property} {_dynamicDataSourceName}"); obj = GetDataFromProperty(property); break; case DynamicDataSourceType.Method: - MethodInfo method = PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredMethod(_dynamicDataDeclaringType, _dynamicDataSourceName) + MethodInfo method = GetMethodConsideringInheritance(_dynamicDataDeclaringType, _dynamicDataSourceName) ?? throw new ArgumentNullException($"{DynamicDataSourceType.Method} {_dynamicDataSourceName}"); obj = GetDataFromMethod(method); @@ -251,4 +251,40 @@ private static bool IsTupleOrValueTuple(Type type, out int tupleSize) return false; } #endif + + private static PropertyInfo? GetPropertyConsideringInheritance(Type type, string propertyName) + { + // NOTE: Don't use GetRuntimeProperty. It considers inheritance only for instance properties. + Type? currentType = type; + while (currentType is not null) + { + PropertyInfo? property = PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredProperty(currentType, propertyName); + if (property is not null) + { + return property; + } + + currentType = currentType.BaseType; + } + + return null; + } + + private static MethodInfo? GetMethodConsideringInheritance(Type type, string methodName) + { + // NOTE: Don't use GetRuntimeMethod. It considers inheritance only for instance methods. + Type? currentType = type; + while (currentType is not null) + { + MethodInfo? method = PlatformServiceProvider.Instance.ReflectionOperations.GetDeclaredMethod(currentType, methodName); + if (method is not null) + { + return method; + } + + currentType = currentType.BaseType; + } + + return null; + } } diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index 5e76ac275a..66f0f1d5c5 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -370,7 +370,7 @@ private TestClassInfo CreateClassInfo(Type classType, TestMethod testMethod) { try { - PropertyInfo? testContextProperty = PlatformServiceProvider.Instance.ReflectionOperations.GetRuntimeProperty(classType, TestContextPropertyName); + PropertyInfo? testContextProperty = PlatformServiceProvider.Instance.ReflectionOperations.GetRuntimeProperty(classType, TestContextPropertyName, includeNonPublic: false); if (testContextProperty == null) { // that's okay may be the property was not defined @@ -810,7 +810,8 @@ private MethodInfo GetMethodInfoForTestMethod(TestMethod testMethod, TestClassIn else if (methodBase != null) { Type[] parameters = methodBase.GetParameters().Select(i => i.ParameterType).ToArray(); - testMethodInfo = PlatformServiceProvider.Instance.ReflectionOperations.GetRuntimeMethod(methodBase.DeclaringType!, methodBase.Name, parameters); + // TODO: Should we pass true for includeNonPublic? + testMethodInfo = PlatformServiceProvider.Instance.ReflectionOperations.GetRuntimeMethod(methodBase.DeclaringType!, methodBase.Name, parameters, includeNonPublic: false); } return testMethodInfo is null diff --git a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs index 16bd0f9454..d66a4db69a 100644 --- a/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs +++ b/src/Adapter/MSTest.TestAdapter/SourceGeneration/SourceGeneratedReflectionOperations.cs @@ -61,7 +61,7 @@ public PropertyInfo[] GetDeclaredProperties(Type type) => ReflectionDataProvider.TypeProperties[type]; public PropertyInfo? GetDeclaredProperty(Type type, string propertyName) - => GetRuntimeProperty(type, propertyName); + => GetRuntimeProperty(type, propertyName, includeNonPublic: true); public Type[] GetDefinedTypes(Assembly assembly) => ReflectionDataProvider.Types; @@ -69,14 +69,25 @@ public Type[] GetDefinedTypes(Assembly assembly) public MethodInfo[] GetRuntimeMethods(Type type) => ReflectionDataProvider.TypeMethods[type]; - public MethodInfo? GetRuntimeMethod(Type declaringType, string methodName, Type[] parameters) => throw new NotImplementedException(); + public MethodInfo? GetRuntimeMethod(Type declaringType, string methodName, Type[] parameters, bool includeNonPublic) + { + IEnumerable runtimeMethods = GetRuntimeMethods(declaringType) + .Where( + m => m.Name == methodName && + m.GetParameters().Select(pi => pi.ParameterType).SequenceEqual(parameters) && + (includeNonPublic || m.IsPublic)); + return runtimeMethods.SingleOrDefault(); + } - public PropertyInfo? GetRuntimeProperty(Type classType, string propertyName) + public PropertyInfo? GetRuntimeProperty(Type classType, string propertyName, bool includeNonPublic) { Dictionary type = ReflectionDataProvider.TypePropertiesByName[classType]; // We as asking for TestContext here, it may not be there. - return type.TryGetValue(propertyName, out PropertyInfo? propertyInfo) ? propertyInfo : null; + PropertyInfo? property = type.TryGetValue(propertyName, out PropertyInfo? propertyInfo) ? propertyInfo : null; + return !includeNonPublic && (property?.GetMethod?.IsPublic == true || property?.SetMethod?.IsPublic == true) + ? null + : property; } public Type? GetType(string typeName) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs index 0036e00cbb..f7fc969270 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IReflectionOperations2.cs @@ -19,9 +19,9 @@ internal interface IReflectionOperations2 : IReflectionOperations MethodInfo[] GetRuntimeMethods(Type type); - MethodInfo? GetRuntimeMethod(Type declaringType, string methodName, Type[] parameters); + MethodInfo? GetRuntimeMethod(Type declaringType, string methodName, Type[] parameters, bool includeNonPublic); - PropertyInfo? GetRuntimeProperty(Type classType, string propertyName); + PropertyInfo? GetRuntimeProperty(Type classType, string propertyName, bool includeNonPublic); Type? GetType(string typeName); diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs index acce42de99..98d475b99b 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/ReflectionOperations2.cs @@ -45,11 +45,15 @@ public Type[] GetDefinedTypes(Assembly assembly) public MethodInfo[] GetRuntimeMethods(Type type) => type.GetMethods(Everything); - public MethodInfo? GetRuntimeMethod(Type declaringType, string methodName, Type[] parameters) - => declaringType.GetRuntimeMethod(methodName, parameters); - - public PropertyInfo? GetRuntimeProperty(Type classType, string testContextPropertyName) - => classType.GetProperty(testContextPropertyName); + public MethodInfo? GetRuntimeMethod(Type declaringType, string methodName, Type[] parameters, bool includeNonPublic) + => includeNonPublic + ? declaringType.GetMethod(methodName, Everything, null, parameters, null) + : declaringType.GetMethod(methodName, parameters); + + public PropertyInfo? GetRuntimeProperty(Type classType, string testContextPropertyName, bool includeNonPublic) + => includeNonPublic + ? classType.GetProperty(testContextPropertyName, Everything) + : classType.GetProperty(testContextPropertyName); public Type? GetType(string typeName) => Type.GetType(typeName); diff --git a/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs index acc5aeab60..d43862282d 100644 --- a/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/DynamicDataShouldBeValidAnalyzer.cs @@ -138,6 +138,48 @@ private static void AnalyzeAttribute(SymbolAnalysisContext context, AttributeDat AnalyzeDisplayNameSource(context, attributeData, attributeSyntax, methodSymbol, methodInfoTypeSymbol); } + private static (ISymbol? Member, bool AreTooMany) TryGetMember(INamedTypeSymbol declaringType, string memberName) + { + INamedTypeSymbol? currentType = declaringType; + while (currentType is not null) + { + (ISymbol? Member, bool AreTooMany) result = TryGetMemberCore(currentType, memberName); + if (result.Member is not null || result.AreTooMany) + { + return result; + } + + // Only continue to look at base types if the member is not found on the current type and we are not hit by "too many methods" rule. + currentType = currentType.BaseType; + } + + return (null, false); + + static (ISymbol? Member, bool AreTooMany) TryGetMemberCore(INamedTypeSymbol declaringType, string memberName) + { + // If we cannot find the member on the given type, report a diagnostic. + if (declaringType.GetMembers(memberName) is { Length: 0 } potentialMembers) + { + return (null, false); + } + + ISymbol? potentialProperty = potentialMembers.FirstOrDefault(m => m.Kind == SymbolKind.Property); + if (potentialProperty is not null) + { + return (potentialProperty, false); + } + + IEnumerable candidateMethods = potentialMembers.Where(m => m.Kind == SymbolKind.Method); + if (candidateMethods.Count() > 1) + { + // If there are multiple methods with the same name, report a diagnostic. This is not a supported scenario. + return (null, true); + } + + return (candidateMethods.FirstOrDefault() ?? potentialMembers[0], false); + } + } + private static void AnalyzeDataSource(SymbolAnalysisContext context, AttributeData attributeData, SyntaxNode attributeSyntax, IMethodSymbol methodSymbol, INamedTypeSymbol dynamicDataSourceTypeSymbol, INamedTypeSymbol ienumerableTypeSymbol) { @@ -173,22 +215,23 @@ private static void AnalyzeDataSource(SymbolAnalysisContext context, AttributeDa return; } - // If we cannot find the member on the given type, report a diagnostic. - if (declaringType.GetMembers(memberName) is { Length: 0 } potentialMembers) + (ISymbol? member, bool areTooMany) = TryGetMember(declaringType, memberName); + + if (areTooMany) { - context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(MemberNotFoundRule, declaringType.Name, memberName)); + // If there are multiple methods with the same name and all are parameterless, report a diagnostic. This is not a supported scenario. + // Note: This is likely to happen only when they differ in arity (for example, one is non-generic and the other is generic). + context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(FoundTooManyMembersRule, declaringType.Name, memberName)); return; } - // If there are multiple members with the same name, report a diagnostic. This is not a supported scenario. - if (potentialMembers.Length > 1) + if (member is null) { - context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(FoundTooManyMembersRule, declaringType.Name, memberName)); + // If we cannot find the member on the given type, report a diagnostic. + context.ReportDiagnostic(attributeSyntax.CreateDiagnostic(MemberNotFoundRule, declaringType.Name, memberName)); return; } - ISymbol member = potentialMembers[0]; - switch (member.Kind) { case SymbolKind.Property: diff --git a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs index 44dc75da83..06d74ed0c7 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/Parameterized tests/DynamicDataTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// 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; @@ -25,14 +25,22 @@ public void ExecuteDynamicDataTests() VerifyE2E.TestsPassed( testResults, "DynamicDataTest_SourceProperty (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyFromBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyShadowingBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourcePropertyAuto (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAutoFromBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAutoShadowingBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "Custom DynamicDataTestMethod DynamicDataTest_SourcePropertyOtherType_CustomDisplayName with 2 parameters", "Custom DynamicDataTestMethod DynamicDataTest_SourceMethodOtherType_CustomDisplayName with 2 parameters", "UserDynamicDataTestMethod DynamicDataTest_SourcePropertyOtherType_CustomDisplayNameOtherType with 2 parameters", "Custom DynamicDataTestMethod DynamicDataTest_SourceMethod_CustomDisplayName with 2 parameters", "UserDynamicDataTestMethod DynamicDataTest_SourceMethodOtherType_CustomDisplayNameOtherType with 2 parameters", "DynamicDataTest_SourceMethod (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodFromBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodShadowingBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourceMethodAuto (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAutoFromBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAutoShadowingBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "UserDynamicDataTestMethod DynamicDataTest_SourcePropertyOtherType_CustomDisplayNameOtherType with 2 parameters", "StackOverflowException_Example (DataSourceTestProject.DynamicDataTests+ExampleTestCase)", "Custom DynamicDataTestMethod DynamicDataTest_SourceProperty_CustomDisplayName with 2 parameters", @@ -48,11 +56,19 @@ public void ExecuteDynamicDataTests() "UserDynamicDataTestMethod DynamicDataTest_SourceProperty_CustomDisplayNameOtherType with 2 parameters", "UserDynamicDataTestMethod DynamicDataTest_SourceProperty_CustomDisplayNameOtherType with 2 parameters", "DynamicDataTest_SourceMethod (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodFromBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodShadowingBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourceMethodAuto (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAutoFromBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAutoShadowingBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "Custom DynamicDataTestMethod DynamicDataTest_SourcePropertyOtherType_CustomDisplayName with 2 parameters", "UserDynamicDataTestMethod DynamicDataTest_SourceMethodOtherType_CustomDisplayNameOtherType with 2 parameters", "DynamicDataTest_SourceProperty (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyFromBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyShadowingBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourcePropertyAuto (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAutoFromBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAutoShadowingBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourcePropertyOtherType (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "Custom DynamicDataTestMethod DynamicDataTest_SourceMethod_CustomDisplayName with 2 parameters", "MethodWithOverload (\"1\",1)", diff --git a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs index d04d431f5a..ab9083a04b 100644 --- a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs +++ b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/Parameterized tests/DynamicDataTests.cs @@ -20,12 +20,28 @@ public void ExecuteDynamicDataTests() ValidatePassedTests( "DynamicDataTest_SourceMethod (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourceMethod (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodFromBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodFromBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodShadowingBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodShadowingBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourceMethodAuto (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourceMethodAuto (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAutoFromBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAutoFromBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAutoShadowingBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourceMethodAutoShadowingBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourceProperty (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourceProperty (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyFromBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyFromBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyShadowingBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyShadowingBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourcePropertyAuto (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", "DynamicDataTest_SourcePropertyAuto (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAutoFromBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAutoFromBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAutoShadowingBase (\"John;Doe\",LibProjectReferencedByDataSourceTest.User)", + "DynamicDataTest_SourcePropertyAutoShadowingBase (\"Jane;Doe\",LibProjectReferencedByDataSourceTest.User)", "Custom DynamicDataTestMethod DynamicDataTest_SourceMethod_CustomDisplayName with 2 parameters", "Custom DynamicDataTestMethod DynamicDataTest_SourceMethod_CustomDisplayName with 2 parameters", "Custom DynamicDataTestMethod DynamicDataTest_SourceProperty_CustomDisplayName with 2 parameters", diff --git a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs index 88668e8b42..2bd7372e62 100644 --- a/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs +++ b/test/IntegrationTests/TestAssets/DynamicDataTestProject/DynamicDataTests.cs @@ -12,25 +12,113 @@ namespace DataSourceTestProject; +public abstract class DynamicDataTestsBase +{ + public static IEnumerable GetDataFromBase() + { + yield return + [ + "John;Doe", + new User() + { + FirstName = "John", + LastName = "Doe", + } + ]; + + yield return + [ + "Jane;Doe", + new User() + { + FirstName = "Jane", + LastName = "Doe", + } + ]; + } + + public static IEnumerable DataFromBase + { + get + { + yield return + [ + "John;Doe", + new User() + { + FirstName = "John", + LastName = "Doe", + } + ]; + + yield return + [ + "Jane;Doe", + new User() + { + FirstName = "Jane", + LastName = "Doe", + } + ]; + } + } + + public static IEnumerable DataShadowingBase => throw new NotImplementedException(); + + public static IEnumerable GetDataShadowingBase() => throw new NotImplementedException(); +} + [TestClass] -public class DynamicDataTests +public class DynamicDataTests : DynamicDataTestsBase { [DataTestMethod] [DynamicData(nameof(GetParseUserData), DynamicDataSourceType.Method)] public void DynamicDataTest_SourceMethod(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + [DataTestMethod] + [DynamicData(nameof(GetDataFromBase), DynamicDataSourceType.Method)] + public void DynamicDataTest_SourceMethodFromBase(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + + [DataTestMethod] + [DynamicData(nameof(GetDataShadowingBase), DynamicDataSourceType.Method)] + public void DynamicDataTest_SourceMethodShadowingBase(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + [DataTestMethod] [DynamicData(nameof(GetParseUserData))] public void DynamicDataTest_SourceMethodAuto(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + [DataTestMethod] + [DynamicData(nameof(GetDataFromBase))] + public void DynamicDataTest_SourceMethodAutoFromBase(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + + [DataTestMethod] + [DynamicData(nameof(GetDataShadowingBase))] + public void DynamicDataTest_SourceMethodAutoShadowingBase(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + [DataTestMethod] [DynamicData(nameof(ParseUserData), DynamicDataSourceType.Property)] public void DynamicDataTest_SourceProperty(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + [DataTestMethod] + [DynamicData(nameof(DataFromBase), DynamicDataSourceType.Property)] + public void DynamicDataTest_SourcePropertyFromBase(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + + [DataTestMethod] + [DynamicData(nameof(DataShadowingBase), DynamicDataSourceType.Property)] + public void DynamicDataTest_SourcePropertyShadowingBase(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + [DataTestMethod] [DynamicData(nameof(ParseUserData))] public void DynamicDataTest_SourcePropertyAuto(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + [DataTestMethod] + [DynamicData(nameof(DataFromBase))] + public void DynamicDataTest_SourcePropertyAutoFromBase(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + + [DataTestMethod] + [DynamicData(nameof(DataShadowingBase))] + public void DynamicDataTest_SourcePropertyAutoShadowingBase(string userData, User expectedUser) => ParseAndAssert(userData, expectedUser); + [DataTestMethod] [DynamicData(nameof(GetParseUserData), DynamicDataSourceType.Method, DynamicDataDisplayName = nameof(GetCustomDynamicDataDisplayName))] @@ -117,54 +205,13 @@ private static void ParseAndAssert(string userData, User expectedUser) Assert.AreEqual(user.LastName, expectedUser.LastName); } - public static IEnumerable GetParseUserData() - { - yield return - [ - "John;Doe", - new User() - { - FirstName = "John", - LastName = "Doe", - } - ]; + public static new IEnumerable GetDataShadowingBase() => GetDataFromBase(); - yield return - [ - "Jane;Doe", - new User() - { - FirstName = "Jane", - LastName = "Doe", - } - ]; - } + public static IEnumerable GetParseUserData() => GetDataFromBase(); - public static IEnumerable ParseUserData - { - get - { - yield return - [ - "John;Doe", - new User() - { - FirstName = "John", - LastName = "Doe", - } - ]; + public static IEnumerable ParseUserData => DataFromBase; - yield return - [ - "Jane;Doe", - new User() - { - FirstName = "Jane", - LastName = "Doe", - } - ]; - } - } + public static new IEnumerable DataShadowingBase => DataFromBase; public static string GetCustomDynamicDataDisplayName(MethodInfo methodInfo, object[] data) => $"Custom DynamicDataTestMethod {methodInfo.Name} with {data.Length} parameters"; diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs index d57bf15a77..5cc4064392 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/DynamicDataShouldBeValidAnalyzerTests.cs @@ -815,6 +815,77 @@ public void TestMethod2(object[] o) await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] + public async Task MemberIsShadowingBase_NoDiagnostic() + { + string code = """ + using System; + using System.Collections.Generic; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + public abstract class MyTestClassBase + { + public static IEnumerable Data => new List(); + public static IEnumerable GetData() => new List(); + } + + [TestClass] + public class MyTestClass : MyTestClassBase + { + [DynamicData("Data")] + [TestMethod] + public void TestMethod1(object[] o) + { + } + + [DynamicData("GetData", DynamicDataSourceType.Method)] + [TestMethod] + public void TestMethod2(object[] o) + { + } + + public static IEnumerable Data => new List(); + public static IEnumerable GetData() => new List(); + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code); + } + + [TestMethod] + public async Task MemberIsFromBase_NoDiagnostic() + { + string code = """ + using System; + using System.Collections.Generic; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + public abstract class MyTestClassBase + { + public static IEnumerable Data => new List(); + public static IEnumerable GetData() => new List(); + } + + [TestClass] + public class MyTestClass : MyTestClassBase + { + [DynamicData("Data")] + [TestMethod] + public void TestMethod1(object[] o) + { + } + + [DynamicData("GetData", DynamicDataSourceType.Method)] + [TestMethod] + public void TestMethod2(object[] o) + { + } + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code); + } + [TestMethod] public async Task MethodHasParameters_Diagnostic() { From b1e4e1128dab4c9f110a2fdd6b0c7c6203531dd6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 4 Jan 2025 11:02:43 +0100 Subject: [PATCH 217/273] [main] Bump MSTest from 3.8.0-preview.24631.6 to 3.8.0-preview.25052.2 (#4500) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 4cafa6d447..cebcb8dc0e 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -24,7 +24,7 @@ 1.1.3-beta1.24423.1 - 3.8.0-preview.24631.6 + 3.8.0-preview.25052.2 From 8643e6b51055e2d6acfe9a3b9477745d90746d05 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Sun, 5 Jan 2025 20:57:03 +0100 Subject: [PATCH 218/273] [main] Update dependencies from microsoft/testanywhere (#4517) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 7a9e0a79c0..b44dccb766 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -17,9 +17,9 @@ https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage d4a113f856a31bcdcbf6e08da8928961c98bb497 - + https://github.com/microsoft/testanywhere - 2a22637b3897dea2062a1ca574817772bc9346f5 + 038b4b79d9a55eecf37065fb30e41946a5933cf1 diff --git a/eng/Versions.props b/eng/Versions.props index ef78047a82..92ddb497d1 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,6 +10,6 @@ 10.0.0-beta.24604.4 17.14.0-preview.24630.1 - 1.0.0-alpha.25053.2 + 1.0.0-alpha.25054.1 From 919af5da418fd26403784ef142504217d11420d8 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Sun, 5 Jan 2025 20:58:20 +0100 Subject: [PATCH 219/273] Mark TestMethodOptions.Executor as non-nullable (#4518) --- .../Execution/TestMethodRunner.cs | 19 +++---------------- .../MSTest.TestAdapter/Execution/TypeCache.cs | 11 ++++++----- .../ObjectModel/TestMethodOptions.cs | 2 +- 3 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs index 562bb7376e..7ce5f213d1 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs @@ -65,7 +65,7 @@ public TestMethodRunner(TestMethodInfo testMethodInfo, TestMethod testMethod, IT internal UnitTestResult[] Execute(string initializationLogs, string initializationErrorLogs, string initializationTrace, string initializationTestContextMessages) { bool isSTATestClass = AttributeComparer.IsDerived(_testMethodInfo.Parent.ClassAttribute); - bool isSTATestMethod = _testMethodInfo.TestMethodOptions.Executor is not null && AttributeComparer.IsDerived(_testMethodInfo.TestMethodOptions.Executor); + bool isSTATestMethod = AttributeComparer.IsDerived(_testMethodInfo.TestMethodOptions.Executor); bool isSTARequested = isSTATestClass || isSTATestMethod; bool isWindowsOS = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); if (isSTARequested && isWindowsOS && Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) @@ -163,20 +163,7 @@ internal UnitTestResult[] RunTestMethod() List results = []; if (_testMethodInfo.TestMethodOptions.Executor == null) { - PlatformServiceProvider.Instance.AdapterTraceLogger.LogError( - "Not able to get executor for method {0}.{1}", - _testMethodInfo.TestClassName, - _testMethodInfo.TestMethodName); - - TestResult emptyResult = new() - { - Outcome = UTF.UnitTestOutcome.Unknown, - TestFailureException = new TestFailedException(UnitTestOutcome.Error, Resource.UTA_NoTestResult), - }; - _testContext.SetOutcome(emptyResult.Outcome); - - results.Add(emptyResult); - return results.ToUnitTestResults(); + throw ApplicationStateGuard.Unreachable(); } bool isDataDriven = false; @@ -424,7 +411,7 @@ private TestResult[] ExecuteTest(TestMethodInfo testMethodInfo) { try { - return _testMethodInfo.TestMethodOptions.Executor!.Execute(testMethodInfo); + return _testMethodInfo.TestMethodOptions.Executor.Execute(testMethodInfo); } catch (Exception ex) { diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index 66f0f1d5c5..e1df709c48 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -743,7 +743,7 @@ private TestMethodInfo ResolveTestMethodInfoForDiscovery(TestMethod testMethod, MethodInfo methodInfo = GetMethodInfoForTestMethod(testMethod, testClassInfo); // Let's build a fake options type as it won't be used. - return new TestMethodInfo(methodInfo, testClassInfo, new(TimeoutInfo.FromTimeout(-1), null, null, false, null)); + return new TestMethodInfo(methodInfo, testClassInfo, new(TimeoutInfo.FromTimeout(-1), null, null, false, null!)); } /// @@ -752,14 +752,15 @@ private TestMethodInfo ResolveTestMethodInfoForDiscovery(TestMethod testMethod, /// The method info. /// The test class info. /// Test Method Attribute. - private TestMethodAttribute? GetTestMethodAttribute(MethodInfo methodInfo, TestClassInfo testClassInfo) + private TestMethodAttribute GetTestMethodAttribute(MethodInfo methodInfo, TestClassInfo testClassInfo) { - // Get the derived TestMethod attribute from reflection - TestMethodAttribute? testMethodAttribute = _reflectionHelper.GetFirstDerivedAttributeOrDefault(methodInfo, inherit: false); + // Get the derived TestMethod attribute from reflection. + // It should be non-null as it was already validated by IsValidTestMethod. + TestMethodAttribute testMethodAttribute = _reflectionHelper.GetFirstDerivedAttributeOrDefault(methodInfo, inherit: false)!; // Get the derived TestMethod attribute from Extended TestClass Attribute // If the extended TestClass Attribute doesn't have extended TestMethod attribute then base class returns back the original testMethod Attribute - testMethodAttribute = testClassInfo.ClassAttribute.GetTestMethodAttribute(testMethodAttribute!) ?? testMethodAttribute; + testMethodAttribute = testClassInfo.ClassAttribute.GetTestMethodAttribute(testMethodAttribute) ?? testMethodAttribute; return testMethodAttribute; } diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs index 1c87933a6a..8908f84556 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs @@ -10,4 +10,4 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; /// /// A facade service for options passed to a test method. /// -internal sealed record TestMethodOptions(TimeoutInfo TimeoutInfo, ExpectedExceptionBaseAttribute? ExpectedException, ITestContext? TestContext, bool CaptureDebugTraces, TestMethodAttribute? Executor); +internal sealed record TestMethodOptions(TimeoutInfo TimeoutInfo, ExpectedExceptionBaseAttribute? ExpectedException, ITestContext? TestContext, bool CaptureDebugTraces, TestMethodAttribute Executor); From f1532a26adb7d37c8ca646ad151e41dab6d3c1fe Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:57:56 +0100 Subject: [PATCH 220/273] [main] Update dependencies from microsoft/testanywhere (#4520) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index b44dccb766..4115df9640 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -17,9 +17,9 @@ https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage d4a113f856a31bcdcbf6e08da8928961c98bb497 - + https://github.com/microsoft/testanywhere - 038b4b79d9a55eecf37065fb30e41946a5933cf1 + 631611080534165fca1733e7e31e7aeee417cdcc diff --git a/eng/Versions.props b/eng/Versions.props index 92ddb497d1..3dd1f2ee94 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,6 +10,6 @@ 10.0.0-beta.24604.4 17.14.0-preview.24630.1 - 1.0.0-alpha.25054.1 + 1.0.0-alpha.25055.2 From 91e0c92e6edb1e29a9a8993b8e7a6485af698654 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:59:04 +0100 Subject: [PATCH 221/273] [main] Bump MSTest from 3.8.0-preview.25052.2 to 3.8.0-preview.25055.1 (#4522) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index cebcb8dc0e..1e0580fb96 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -24,7 +24,7 @@ 1.1.3-beta1.24423.1 - 3.8.0-preview.25052.2 + 3.8.0-preview.25055.1 From f049f230cba35d5f87f2dadb4881fdcfa8f38ecf Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 6 Jan 2025 11:41:13 +0100 Subject: [PATCH 222/273] Move ExpectedException attribute resolution out of TypeCache/ReflectHelper (#4505) --- .../Execution/TestMethodInfo.cs | 56 +++++- .../MSTest.TestAdapter/Execution/TypeCache.cs | 5 +- .../Helpers/ReflectHelper.cs | 50 ----- .../ObjectModel/TestMethodOptions.cs | 2 +- .../Execution/TestMethodInfoTests.cs | 173 +++++++++++++++--- .../Execution/TestMethodRunnerTests.cs | 4 +- .../Execution/TypeCacheTests.cs | 38 ---- .../Helpers/ReflectHelperTests.cs | 51 ------ 8 files changed, 209 insertions(+), 170 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs index aec6cdcd0a..3b61f1aae0 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs @@ -45,6 +45,7 @@ internal TestMethodInfo( TestMethod = testMethod; Parent = parent; TestMethodOptions = testMethodOptions; + ExpectedException = ResolveExpectedException(); } /// @@ -89,6 +90,8 @@ internal TestMethodInfo( /// internal TestMethodOptions TestMethodOptions { get; } + internal ExpectedExceptionBaseAttribute? ExpectedException { get; set; /*set for testing only*/ } + public Attribute[]? GetAllAttributes(bool inherit) => ReflectHelper.Instance.GetDerivedAttributes(TestMethod, inherit).ToArray(); public TAttributeType[] GetAttributes(bool inherit) @@ -212,6 +215,51 @@ public virtual TestResult Invoke(object?[]? arguments) return newParameters; } + /// + /// Resolves the expected exception attribute. The function will try to + /// get all the expected exception attributes defined for a testMethod. + /// + /// + /// The expected exception attribute found for this test. Null if not found. + /// + private ExpectedExceptionBaseAttribute? ResolveExpectedException() + { + IEnumerable expectedExceptions; + + try + { + expectedExceptions = ReflectHelper.Instance.GetDerivedAttributes(TestMethod, inherit: true); + } + catch (Exception ex) + { + // If construction of the attribute throws an exception, indicate that there was an + // error when trying to run the test + string errorMessage = string.Format( + CultureInfo.CurrentCulture, + Resource.UTA_ExpectedExceptionAttributeConstructionException, + Parent.ClassType.FullName, + TestMethod.Name, + ex.GetFormattedExceptionMessage()); + throw new TypeInspectionException(errorMessage); + } + + // Verify that there is only one attribute (multiple attributes derived from + // ExpectedExceptionBaseAttribute are not allowed on a test method) + // This is needed EVEN IF the attribute doesn't allow multiple. + // See https://github.com/microsoft/testfx/issues/4331 + if (expectedExceptions.Count() > 1) + { + string errorMessage = string.Format( + CultureInfo.CurrentCulture, + Resource.UTA_MultipleExpectedExceptionsOnTestMethod, + Parent.ClassType.FullName, + TestMethod.Name); + throw new TypeInspectionException(errorMessage); + } + + return expectedExceptions.FirstOrDefault(); + } + /// /// Execute test without timeout. /// @@ -303,11 +351,11 @@ private TestResult ExecuteInternal(object?[]? arguments, CancellationTokenSource // if the user specified that the test was going to throw an exception, and // it did not, we should fail the test // We only perform this check if the test initialize passes and the test method is actually run. - if (hasTestInitializePassed && !isExceptionThrown && TestMethodOptions.ExpectedException != null) + if (hasTestInitializePassed && !isExceptionThrown && ExpectedException is { } expectedException) { result.TestFailureException = new TestFailedException( ObjectModelUnitTestOutcome.Failed, - TestMethodOptions.ExpectedException.NoExceptionMessage); + expectedException.NoExceptionMessage); result.Outcome = UTF.UnitTestOutcome.Failed; } } @@ -342,7 +390,7 @@ private bool IsExpectedException(Exception ex, TestResult result) // if the user specified an expected exception, we need to check if this // exception was thrown. If it was thrown, we should pass the test. In // case a different exception was thrown, the test is seen as failure - if (TestMethodOptions.ExpectedException == null) + if (ExpectedException == null) { return false; } @@ -352,7 +400,7 @@ private bool IsExpectedException(Exception ex, TestResult result) { // If the expected exception attribute's Verify method returns, then it // considers this exception as expected, so the test passed - TestMethodOptions.ExpectedException.Verify(ex); + ExpectedException.Verify(ex); return true; } catch (Exception verifyEx) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index e1df709c48..5d96f9e6f4 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -729,8 +729,7 @@ private TestMethodInfo ResolveTestMethodInfo(TestMethod testMethod, TestClassInf MethodInfo methodInfo = GetMethodInfoForTestMethod(testMethod, testClassInfo); TimeoutInfo timeout = GetTestTimeout(methodInfo, testMethod); - ExpectedExceptionBaseAttribute? expectedExceptionAttribute = _reflectionHelper.ResolveExpectedExceptionHelper(methodInfo, testMethod); - var testMethodOptions = new TestMethodOptions(timeout, expectedExceptionAttribute, testContext, captureDebugTraces, GetTestMethodAttribute(methodInfo, testClassInfo)); + var testMethodOptions = new TestMethodOptions(timeout, testContext, captureDebugTraces, GetTestMethodAttribute(methodInfo, testClassInfo)); var testMethodInfo = new TestMethodInfo(methodInfo, testClassInfo, testMethodOptions); SetCustomProperties(testMethodInfo, testContext); @@ -743,7 +742,7 @@ private TestMethodInfo ResolveTestMethodInfoForDiscovery(TestMethod testMethod, MethodInfo methodInfo = GetMethodInfoForTestMethod(testMethod, testClassInfo); // Let's build a fake options type as it won't be used. - return new TestMethodInfo(methodInfo, testClassInfo, new(TimeoutInfo.FromTimeout(-1), null, null, false, null!)); + return new TestMethodInfo(methodInfo, testClassInfo, new(TimeoutInfo.FromTimeout(-1), null, false, null!)); } /// diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs index cc361ee215..7dcd86d56d 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/ReflectHelper.cs @@ -4,7 +4,6 @@ using System.Security; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; -using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -87,55 +86,6 @@ public virtual bool IsNonDerivedAttributeDefined(MemberInfo memberIn return false; } - /// - /// Resolves the expected exception attribute. The function will try to - /// get all the expected exception attributes defined for a testMethod. - /// - /// The MethodInfo instance. - /// The test method. - /// - /// The expected exception attribute found for this test. Null if not found. - /// - public virtual ExpectedExceptionBaseAttribute? ResolveExpectedExceptionHelper(MethodInfo methodInfo, TestMethod testMethod) - { - DebugEx.Assert(methodInfo != null, "MethodInfo should be non-null"); - - IEnumerable expectedExceptions; - - try - { - expectedExceptions = GetDerivedAttributes(methodInfo, inherit: true); - } - catch (Exception ex) - { - // If construction of the attribute throws an exception, indicate that there was an - // error when trying to run the test - string errorMessage = string.Format( - CultureInfo.CurrentCulture, - Resource.UTA_ExpectedExceptionAttributeConstructionException, - testMethod.FullClassName, - testMethod.Name, - ex.GetFormattedExceptionMessage()); - throw new TypeInspectionException(errorMessage); - } - - // Verify that there is only one attribute (multiple attributes derived from - // ExpectedExceptionBaseAttribute are not allowed on a test method) - // This is needed EVEN IF the attribute doesn't allow multiple. - // See https://github.com/microsoft/testfx/issues/4331 - if (expectedExceptions.Count() > 1) - { - string errorMessage = string.Format( - CultureInfo.CurrentCulture, - Resource.UTA_MultipleExpectedExceptionsOnTestMethod, - testMethod.FullClassName, - testMethod.Name); - throw new TypeInspectionException(errorMessage); - } - - return expectedExceptions.FirstOrDefault(); - } - /// /// Returns object to be used for controlling lifetime, null means infinite lifetime. /// diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs index 8908f84556..8b1804ce83 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethodOptions.cs @@ -10,4 +10,4 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; /// /// A facade service for options passed to a test method. /// -internal sealed record TestMethodOptions(TimeoutInfo TimeoutInfo, ExpectedExceptionBaseAttribute? ExpectedException, ITestContext? TestContext, bool CaptureDebugTraces, TestMethodAttribute Executor); +internal sealed record TestMethodOptions(TimeoutInfo TimeoutInfo, ITestContext? TestContext, bool CaptureDebugTraces, TestMethodAttribute Executor); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs index 84fcb95c57..a884c94ffe 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// 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.VisualStudio.TestPlatform.MSTest.TestAdapter; @@ -58,7 +58,7 @@ public TestMethodInfoTests() _testContextImplementation = new TestContextImplementation(testMethod, new ThreadSafeStringWriter(null, "test"), new Dictionary()); _testClassInfo = new TestClassInfo(typeof(DummyTestClass), _constructorInfo, true, _testContextProperty, _classAttribute, _testAssemblyInfo); _expectedException = new UTF.ExpectedExceptionAttribute(typeof(DivideByZeroException)); - _testMethodOptions = new TestMethodOptions(TimeoutInfo.FromTimeout(3600 * 1000), null, _testContextImplementation, false, _testMethodAttribute); + _testMethodOptions = new TestMethodOptions(TimeoutInfo.FromTimeout(3600 * 1000), _testContextImplementation, false, _testMethodAttribute); _testMethodInfo = new TestMethodInfo( _methodInfo, @@ -501,7 +501,7 @@ public void TestMethodInfoInvokeWhenTestThrowsReturnsExpectedResult() _testClassInfo.TestInitializeMethod.Name, "System.ArgumentException: Some exception message ---> System.InvalidOperationException: Inner exception message"); - var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions with { ExpectedException = _expectedException }); + var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions) { ExpectedException = _expectedException }; // Act. UTF.TestResult result = testMethodInfo.Invoke(null); @@ -526,7 +526,7 @@ public void TestInitialize_WhenTestReturnsTaskFromException_DisplayProperExcepti // Arrange. DummyTestClass.TestInitializeMethodBodyAsync = async classInstance => await Task.FromException(new Exception("Outer", new InvalidOperationException("Inner"))); _testClassInfo.TestInitializeMethod = typeof(DummyTestClass).GetMethod("DummyTestInitializeMethodAsync"); - var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions with { ExpectedException = _expectedException }); + var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions) { ExpectedException = _expectedException }; // Act. UTF.TestResult result = testMethodInfo.Invoke(null); @@ -562,7 +562,7 @@ public void TestMethodInfoInvokeWhenTestThrowsAssertFailReturnsExpectedResult() _testClassInfo.TestInitializeMethod.Name, "Assert.Fail failed. dummyFailMessage"); - var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions with { ExpectedException = _expectedException }); + var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions) { ExpectedException = _expectedException }; // Act. UTF.TestResult result = testMethodInfo.Invoke(null); @@ -593,7 +593,7 @@ public void TestMethodInfoInvokeWhenTestThrowsAssertInconclusiveReturnsExpectedR _testClassInfo.TestInitializeMethod.Name, "Assert.Inconclusive failed. dummyFailMessage"); - var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions with { ExpectedException = _expectedException }); + var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions) { ExpectedException = _expectedException }; // Act. UTF.TestResult result = testMethodInfo.Invoke(null); @@ -1003,7 +1003,7 @@ public void TestMethodInfoInvokeShouldNotCallTestCleanupIfClassSetContextThrows( public void TestMethodInfoInvokeShouldSetResultAsPassedIfExpectedExceptionIsThrown() { DummyTestClass.TestMethodBody = o => throw new DivideByZeroException(); - var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions with { ExpectedException = _expectedException }); + var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions) { ExpectedException = _expectedException }; UTF.TestResult result = testMethodInfo.Invoke(null); @@ -1013,7 +1013,7 @@ public void TestMethodInfoInvokeShouldSetResultAsPassedIfExpectedExceptionIsThro public void TestMethodInfoInvokeShouldSetResultAsFailedIfExceptionDifferentFromExpectedExceptionIsThrown() { DummyTestClass.TestMethodBody = o => throw new IndexOutOfRangeException(); - var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions with { ExpectedException = _expectedException }); + var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions) { ExpectedException = _expectedException }; UTF.TestResult result = testMethodInfo.Invoke(null); @@ -1026,7 +1026,7 @@ public void TestMethodInfoInvokeShouldSetResultAsFailedIfExceptionDifferentFromE public void TestMethodInfoInvokeShouldSetResultAsFailedWhenExceptionIsExpectedButIsNotThrown() { DummyTestClass.TestMethodBody = o => { return; }; - var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions with { ExpectedException = _expectedException }); + var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions) { ExpectedException = _expectedException }; UTF.TestResult result = testMethodInfo.Invoke(null); Verify(result.Outcome == UTF.UnitTestOutcome.Failed); string message = "Test method did not throw expected exception System.DivideByZeroException."; @@ -1036,7 +1036,7 @@ public void TestMethodInfoInvokeShouldSetResultAsFailedWhenExceptionIsExpectedBu public void TestMethodInfoInvokeShouldSetResultAsInconclusiveWhenExceptionIsAssertInconclusiveException() { DummyTestClass.TestMethodBody = o => throw new UTF.AssertInconclusiveException(); - var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions with { ExpectedException = _expectedException }); + var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions) { ExpectedException = _expectedException }; UTF.TestResult result = testMethodInfo.Invoke(null); Verify(result.Outcome == UTF.UnitTestOutcome.Inconclusive); string message = "Exception of type 'Microsoft.VisualStudio.TestTools.UnitTesting.AssertInconclusiveException' was thrown."; @@ -1055,7 +1055,7 @@ public void TestMethodInfoInvokeShouldSetTestOutcomeBeforeTestCleanup() } }; _testClassInfo.TestCleanupMethod = typeof(DummyTestClass).GetMethod("DummyTestCleanupMethod"); - var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions with { ExpectedException = _expectedException }); + var testMethodInfo = new TestMethodInfo(_methodInfo, _testClassInfo, _testMethodOptions) { ExpectedException = _expectedException }; UTF.TestResult result = testMethodInfo.Invoke(null); @@ -1068,7 +1068,10 @@ public void HandleMethodExceptionShouldInvokeVerifyOfCustomExpectedException() var method = new TestMethodInfo( _methodInfo, _testClassInfo, - _testMethodOptions with { ExpectedException = customExpectedException, TimeoutInfo = TimeoutInfo.FromTimeout(0) }); + _testMethodOptions with { TimeoutInfo = TimeoutInfo.FromTimeout(0) }) + { + ExpectedException = customExpectedException, + }; DummyTestClass.TestMethodBody = o => throw new DivideByZeroException(); UTF.TestResult result = method.Invoke(null); @@ -1082,7 +1085,10 @@ public void HandleMethodExceptionShouldSetOutcomeAsFailedIfVerifyOfExpectedExcep var method = new TestMethodInfo( _methodInfo, _testClassInfo, - _testMethodOptions with { ExpectedException = customExpectedException, TimeoutInfo = TimeoutInfo.FromTimeout(0) }); + _testMethodOptions with { TimeoutInfo = TimeoutInfo.FromTimeout(0) }) + { + ExpectedException = customExpectedException, + }; DummyTestClass.TestMethodBody = o => throw new DivideByZeroException(); UTF.TestResult result = method.Invoke(null); @@ -1096,7 +1102,10 @@ public void HandleMethodExceptionShouldSetOutcomeAsInconclusiveIfVerifyOfExpecte var method = new TestMethodInfo( _methodInfo, _testClassInfo, - _testMethodOptions with { ExpectedException = customExpectedException, TimeoutInfo = TimeoutInfo.FromTimeout(0) }); + _testMethodOptions with { TimeoutInfo = TimeoutInfo.FromTimeout(0) }) + { + ExpectedException = customExpectedException, + }; DummyTestClass.TestMethodBody = o => throw new UTF.AssertInconclusiveException(); UTF.TestResult result = method.Invoke(null); @@ -1111,7 +1120,10 @@ public void HandleMethodExceptionShouldInvokeVerifyOfDerivedCustomExpectedExcept var method = new TestMethodInfo( _methodInfo, _testClassInfo, - _testMethodOptions with { ExpectedException = derivedCustomExpectedException, TimeoutInfo = TimeoutInfo.FromTimeout(0) }); + _testMethodOptions with { TimeoutInfo = TimeoutInfo.FromTimeout(0) }) + { + ExpectedException = derivedCustomExpectedException, + }; DummyTestClass.TestMethodBody = o => throw new DivideByZeroException(); UTF.TestResult result = method.Invoke(null); @@ -1128,7 +1140,10 @@ public void VerifyShouldNotThrowIfThrownExceptionCanBeAssignedToExpectedExceptio var method = new TestMethodInfo( _methodInfo, _testClassInfo, - _testMethodOptions with { ExpectedException = expectedException, TimeoutInfo = TimeoutInfo.FromTimeout(0) }); + _testMethodOptions with { TimeoutInfo = TimeoutInfo.FromTimeout(0) }) + { + ExpectedException = expectedException, + }; DummyTestClass.TestMethodBody = o => throw new DivideByZeroException(); UTF.TestResult result = method.Invoke(null); @@ -1144,7 +1159,10 @@ public void VerifyShouldThrowExceptionIfThrownExceptionCannotBeAssignedToExpecte var method = new TestMethodInfo( _methodInfo, _testClassInfo, - _testMethodOptions with { ExpectedException = expectedException, TimeoutInfo = TimeoutInfo.FromTimeout(0) }); + _testMethodOptions with { TimeoutInfo = TimeoutInfo.FromTimeout(0) }) + { + ExpectedException = expectedException, + }; DummyTestClass.TestMethodBody = o => throw new ArgumentNullException(); UTF.TestResult result = method.Invoke(null); @@ -1163,7 +1181,10 @@ public void VerifyShouldRethrowExceptionIfThrownExceptionIsAssertFailedException var method = new TestMethodInfo( _methodInfo, _testClassInfo, - _testMethodOptions with { ExpectedException = expectedException, TimeoutInfo = TimeoutInfo.FromTimeout(0) }); + _testMethodOptions with { TimeoutInfo = TimeoutInfo.FromTimeout(0) }) + { + ExpectedException = expectedException, + }; DummyTestClass.TestMethodBody = o => throw new UTF.AssertFailedException(); UTF.TestResult result = method.Invoke(null); @@ -1181,7 +1202,10 @@ public void VerifyShouldRethrowExceptionIfThrownExceptionIsAssertInconclusiveExc var method = new TestMethodInfo( _methodInfo, _testClassInfo, - _testMethodOptions with { ExpectedException = expectedException, TimeoutInfo = TimeoutInfo.FromTimeout(0) }); + _testMethodOptions with { TimeoutInfo = TimeoutInfo.FromTimeout(0) }) + { + ExpectedException = expectedException, + }; DummyTestClass.TestMethodBody = o => throw new UTF.AssertInconclusiveException(); UTF.TestResult result = method.Invoke(null); @@ -1196,7 +1220,10 @@ public void VerifyShouldThrowIfThrownExceptionIsNotSameAsExpectedException() var method = new TestMethodInfo( _methodInfo, _testClassInfo, - _testMethodOptions with { ExpectedException = expectedException, TimeoutInfo = TimeoutInfo.FromTimeout(0) }); + _testMethodOptions with { TimeoutInfo = TimeoutInfo.FromTimeout(0) }) + { + ExpectedException = expectedException, + }; DummyTestClass.TestMethodBody = o => throw new DivideByZeroException(); UTF.TestResult result = method.Invoke(null); @@ -1212,7 +1239,10 @@ public void VerifyShouldRethrowIfThrownExceptionIsAssertExceptionWhichIsNotSameA var method = new TestMethodInfo( _methodInfo, _testClassInfo, - _testMethodOptions with { ExpectedException = expectedException, TimeoutInfo = TimeoutInfo.FromTimeout(0) }); + _testMethodOptions with { TimeoutInfo = TimeoutInfo.FromTimeout(0) }) + { + ExpectedException = expectedException, + }; DummyTestClass.TestMethodBody = o => throw new UTF.AssertInconclusiveException(); UTF.TestResult result = method.Invoke(null); @@ -1221,6 +1251,71 @@ public void VerifyShouldRethrowIfThrownExceptionIsAssertExceptionWhichIsNotSameA Verify(result.Outcome == UTF.UnitTestOutcome.Inconclusive); } + public void ResolveExpectedExceptionShouldThrowWhenAttributeIsDefinedTwice_DifferentConcreteType() + { + MethodInfo testMethodInfo = typeof(DummyTestClassForExpectedException).GetMethod(nameof(DummyTestClassForExpectedException.DummyTestMethod1)); + TestClassInfo classInfo = new( + typeof(DummyTestClassForExpectedException), + typeof(DummyTestClassForExpectedException).GetConstructor(Array.Empty()), + isParameterlessConstructor: true, + null, + new UTF.TestClassAttribute(), + new TestAssemblyInfo(typeof(DummyTestClassForExpectedException).Assembly)); + + TypeInspectionException ex = UTF.Assert.ThrowsException(() => new TestMethodInfo(testMethodInfo, classInfo, _testMethodOptions)); + UTF.Assert.AreEqual("The test method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestMethodInfoTests+DummyTestClassForExpectedException.DummyTestMethod1 has multiple attributes derived from ExpectedExceptionBaseAttribute defined on it. Only one such attribute is allowed.", ex.Message); + } + + public void ResolveExpectedExceptionShouldThrowWhenAttributeIsDefinedTwice_SameConcreteType() + { + MethodInfo testMethodInfo = typeof(DummyTestClassForExpectedException).GetMethod(nameof(DummyTestClassForExpectedException.DummyTestMethod1)); + TestClassInfo classInfo = new( + typeof(DummyTestClassForExpectedException), + typeof(DummyTestClassForExpectedException).GetConstructor(Array.Empty()), + isParameterlessConstructor: true, + null, + new UTF.TestClassAttribute(), + new TestAssemblyInfo(typeof(DummyTestClassForExpectedException).Assembly)); + + TypeInspectionException ex = UTF.Assert.ThrowsException(() => new TestMethodInfo(testMethodInfo, classInfo, _testMethodOptions)); + UTF.Assert.AreEqual("The test method Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.Execution.TestMethodInfoTests+DummyTestClassForExpectedException.DummyTestMethod1 has multiple attributes derived from ExpectedExceptionBaseAttribute defined on it. Only one such attribute is allowed.", ex.Message); + } + + public void ResolveExpectedExceptionHelperShouldReturnExpectedExceptionAttributeIfPresent() + { + Type type = typeof(DummyTestClassForExpectedException); + MethodInfo methodInfo = type.GetMethod(nameof(DummyTestClassForExpectedException.TestMethodWithExpectedException)); + TestClassInfo classInfo = new( + typeof(DummyTestClassForExpectedException), + typeof(DummyTestClassForExpectedException).GetConstructor(Array.Empty()), + isParameterlessConstructor: true, + null, + new UTF.TestClassAttribute(), + new TestAssemblyInfo(typeof(DummyTestClassForExpectedException).Assembly)); + + var testMethodInfo = new TestMethodInfo(methodInfo, classInfo, _testMethodOptions); + + Verify(testMethodInfo.ExpectedException is not null); + Verify(((UTF.ExpectedExceptionAttribute)testMethodInfo.ExpectedException).ExceptionType == typeof(DivideByZeroException)); + } + + public void ResolveExpectedExceptionHelperShouldReturnNullIfExpectedExceptionAttributeIsNotPresent() + { + Type type = typeof(DummyTestClassForExpectedException); + MethodInfo methodInfo = type.GetMethod(nameof(DummyTestClassForExpectedException.TestMethodWithoutExpectedException)); + TestClassInfo classInfo = new( + typeof(DummyTestClassForExpectedException), + typeof(DummyTestClassForExpectedException).GetConstructor(Array.Empty()), + isParameterlessConstructor: true, + null, + new UTF.TestClassAttribute(), + new TestAssemblyInfo(typeof(DummyTestClassForExpectedException).Assembly)); + + var testMethodInfo = new TestMethodInfo(methodInfo, classInfo, _testMethodOptions); + + Verify(testMethodInfo.ExpectedException is null); + } + #endregion #region TestMethod invoke setup order @@ -1621,6 +1716,42 @@ protected internal override void Verify(Exception exception) #endregion + public class DummyTestClassForExpectedException + { + private class MyExpectedException1Attribute : UTF.ExpectedExceptionBaseAttribute + { + protected internal override void Verify(Exception exception) => throw new NotImplementedException(); + } + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] + public class MyExpectedException2Attribute : UTF.ExpectedExceptionBaseAttribute + { + protected internal override void Verify(Exception exception) => throw new NotImplementedException(); + } + + [UTF.ExpectedException(typeof(Exception))] + [MyExpectedException1] + + public void DummyTestMethod1() + { + } + + [MyExpectedException2] + [MyExpectedException2] + public void DummyTestMethod2() + { + } + + [UTF.ExpectedException(typeof(DivideByZeroException))] + public void TestMethodWithExpectedException() + { + } + + public void TestMethodWithoutExpectedException() + { + } + } + #if NET6_0_OR_GREATER public class DummyTestClassWithAsyncDisposable : IAsyncDisposable { diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs index d5c4fe1939..8231ee2497 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs @@ -43,7 +43,7 @@ public TestMethodRunnerTests() _testContextImplementation = new TestContextImplementation(_testMethod, new ThreadSafeStringWriter(null, "test"), new Dictionary()); _testClassInfo = GetTestClassInfo(); - _testMethodOptions = new TestMethodOptions(TimeoutInfo.FromTimeout(200), null, _testContextImplementation, false, _testMethodAttribute); + _testMethodOptions = new TestMethodOptions(TimeoutInfo.FromTimeout(200), _testContextImplementation, false, _testMethodAttribute); // Reset test hooks DummyTestClass.TestConstructorMethodBody = () => { }; @@ -151,7 +151,7 @@ public void RunTestMethodForMultipleResultsReturnMultipleResults() new TestResult { Outcome = UTF.UnitTestOutcome.Failed }, ]); - var localTestMethodOptions = new TestMethodOptions(TimeoutInfo.FromTimeout(200), null, _testContextImplementation, false, testMethodAttributeMock.Object); + var localTestMethodOptions = new TestMethodOptions(TimeoutInfo.FromTimeout(200), _testContextImplementation, false, testMethodAttributeMock.Object); var testMethodInfo = new TestableTestMethodInfo(_methodInfo, _testClassInfo, localTestMethodOptions, null); var testMethodRunner = new TestMethodRunner(testMethodInfo, _testMethod, _testContextImplementation); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs index 9ee66388d7..36f83f5d95 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs @@ -1319,44 +1319,6 @@ public void AssemblyInfoListWithExecutableCleanupMethodsShouldReturnAssemblyInfo #region ResolveExpectedExceptionHelper tests - public void ResolveExpectedExceptionHelperShouldReturnExpectedExceptionAttributeIfPresent() - { - Type type = typeof(DummyTestClassWithTestMethods); - MethodInfo methodInfo = type.GetMethod("TestMethodWithExpectedException"); - var testMethod = new TestMethod(methodInfo.Name, type.FullName, "A", isAsync: false); - ExpectedExceptionAttribute expectedException = new(typeof(DivideByZeroException)); - - _mockReflectHelper.Setup(rh => rh.IsNonDerivedAttributeDefined(methodInfo, false)) - .Returns(true); - _mockReflectHelper.Setup(rh => rh.ResolveExpectedExceptionHelper(methodInfo, testMethod)).Returns(expectedException); - - TestMethodInfo testMethodInfo = _typeCache.GetTestMethodInfo( - testMethod, - new TestContextImplementation(testMethod, new ThreadSafeStringWriter(null, "test"), new Dictionary()), - false); - - Verify(expectedException == testMethodInfo.TestMethodOptions.ExpectedException); - } - - public void ResolveExpectedExceptionHelperShouldReturnNullIfExpectedExceptionAttributeIsNotPresent() - { - Type type = typeof(DummyTestClassWithTestMethods); - MethodInfo methodInfo = type.GetMethod("TestMethod"); - var testMethod = new TestMethod(methodInfo.Name, type.FullName, "A", isAsync: false); - - _mockReflectHelper.Setup(rh => rh.IsNonDerivedAttributeDefined(methodInfo, false)) - .Returns(true); - - TestMethodInfo testMethodInfo = _typeCache.GetTestMethodInfo( - testMethod, - new TestContextImplementation(testMethod, new ThreadSafeStringWriter(null, "test"), new Dictionary()), - false); - - ExpectedExceptionAttribute expectedException = new(typeof(DivideByZeroException)); - - Verify(testMethodInfo.TestMethodOptions.ExpectedException is null); - } - public void ResolveExpectedExceptionHelperShouldThrowIfMultipleExpectedExceptionAttributesArePresent() { Type type = typeof(DummyTestClassWithTestMethods); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs index f4efd9a523..54a001d1e8 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Helpers/ReflectHelperTests.cs @@ -3,7 +3,6 @@ using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers; -using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.TestableImplementations; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -283,30 +282,6 @@ public void GettingAttributesShouldNotReturnInheritedAttributesWhenAskingForNonI Verify(nonInheritedAttributes.Length == 1); } - public void ResolveExpectedExceptionShouldThrowWhenAttributeIsDefinedTwice_DifferentConcreteType() - { - MethodInfo testMethodInfo = typeof(DummyTestClass).GetMethod(nameof(DummyTestClass.DummyTestMethod1)); - - // Don't mock. Use the real ReflectionOperations2. - _testablePlatformServiceProvider.MockReflectionOperations = null; - - TypeInspectionException ex = Assert.ThrowsException( - () => ReflectHelper.Instance.ResolveExpectedExceptionHelper(testMethodInfo, new("DummyName", "DummyFullClassName", "DummyAssemblyName", isAsync: false))); - Assert.AreEqual("The test method DummyFullClassName.DummyName has multiple attributes derived from ExpectedExceptionBaseAttribute defined on it. Only one such attribute is allowed.", ex.Message); - } - - public void ResolveExpectedExceptionShouldThrowWhenAttributeIsDefinedTwice_SameConcreteType() - { - MethodInfo testMethodInfo = typeof(DummyTestClass).GetMethod(nameof(DummyTestClass.DummyTestMethod2)); - - // Don't mock. Use the real ReflectionOperations2. - _testablePlatformServiceProvider.MockReflectionOperations = null; - - TypeInspectionException ex = Assert.ThrowsException( - () => ReflectHelper.Instance.ResolveExpectedExceptionHelper(testMethodInfo, new("DummyName", "DummyFullClassName", "DummyAssemblyName", isAsync: false))); - Assert.AreEqual("The test method DummyFullClassName.DummyName has multiple attributes derived from ExpectedExceptionBaseAttribute defined on it. Only one such attribute is allowed.", ex.Message); - } - internal class AttributeMockingHelper { public AttributeMockingHelper(Mock mockReflectionOperations) => _mockReflectionOperations = mockReflectionOperations; @@ -361,30 +336,4 @@ public object[] GetCustomAttributesNotCached(ICustomAttributeProvider attributeP public class TestableExtendedTestMethod : TestMethodAttribute; -public class DummyTestClass -{ - private class MyExpectedException1Attribute : ExpectedExceptionBaseAttribute - { - protected internal override void Verify(Exception exception) => throw new NotImplementedException(); - } - - [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] - public class MyExpectedException2Attribute : ExpectedExceptionBaseAttribute - { - protected internal override void Verify(Exception exception) => throw new NotImplementedException(); - } - - [ExpectedException(typeof(Exception))] - [MyExpectedException1] - - public void DummyTestMethod1() - { - } - - [MyExpectedException2] - [MyExpectedException2] - public void DummyTestMethod2() - { - } -} #endregion From 852087652f3029dfda44de7649d534c62907e6c2 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 6 Jan 2025 13:52:07 +0100 Subject: [PATCH 223/273] Use different message for Assert.AreEqual when string difference is casing only (#4525) --- src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs | 3 ++- .../Assertions/AssertTests.AreEqualTests.cs | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs index 274bc26248..5b94c7ed13 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs @@ -698,7 +698,8 @@ private static void ThrowAssertAreEqualFailed(T expected, T actual, T delta, [DoesNotReturn] private static void ThrowAssertAreEqualFailed(string? expected, string? actual, bool ignoreCase, CultureInfo culture, string userMessage) { - string finalMessage = !ignoreCase && CompareInternal(expected, actual, ignoreCase, culture) == 0 + // If the user requested to match case, and the difference between expected/actual is casing only, then we use a different message. + string finalMessage = !ignoreCase && CompareInternal(expected, actual, ignoreCase: true, culture) == 0 ? string.Format( CultureInfo.CurrentCulture, FrameworkMessages.AreEqualCaseFailMsg, diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs index 4760984225..746caa344f 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs @@ -126,7 +126,8 @@ public void AreEqual_WithEnglishCultureAndDoesNotIgnoreCase_Throws() var englishCulture = new CultureInfo("en-EN"); // Won't ignore case. - VerifyThrows(() => Assert.AreEqual(expected, actual, false, englishCulture)); + Exception ex = VerifyThrows(() => Assert.AreEqual(expected, actual, false, englishCulture)); + Verify(ex.Message == "Assert.AreEqual failed. Expected:. Case is different for actual value:. "); } public void AreEqual_WithTurkishCultureAndDoesNotIgnoreCase_Throws() From d7d0ee120e0ec683fbd83446f90b42101e70495e Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 6 Jan 2025 14:01:07 +0100 Subject: [PATCH 224/273] Report diagnostic when AreNotSame is passed value type (#4523) --- ...voidAssertAreSameWithValueTypesAnalyzer.cs | 5 +- .../MSTest.Analyzers/Resources.Designer.cs | 6 +-- src/Analyzers/MSTest.Analyzers/Resources.resx | 8 ++-- .../MSTest.Analyzers/xlf/Resources.cs.xlf | 12 ++--- .../MSTest.Analyzers/xlf/Resources.de.xlf | 12 ++--- .../MSTest.Analyzers/xlf/Resources.es.xlf | 12 ++--- .../MSTest.Analyzers/xlf/Resources.fr.xlf | 12 ++--- .../MSTest.Analyzers/xlf/Resources.it.xlf | 12 ++--- .../MSTest.Analyzers/xlf/Resources.ja.xlf | 12 ++--- .../MSTest.Analyzers/xlf/Resources.ko.xlf | 12 ++--- .../MSTest.Analyzers/xlf/Resources.pl.xlf | 12 ++--- .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 12 ++--- .../MSTest.Analyzers/xlf/Resources.ru.xlf | 12 ++--- .../MSTest.Analyzers/xlf/Resources.tr.xlf | 12 ++--- .../xlf/Resources.zh-Hans.xlf | 12 ++--- .../xlf/Resources.zh-Hant.xlf | 12 ++--- ...ssertAreSameWithValueTypesAnalyzerTests.cs | 48 +++++++++++++++++++ 17 files changed, 136 insertions(+), 87 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs index fc6a8b0fec..4da001105c 100644 --- a/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs @@ -56,7 +56,7 @@ private static void AnalyzeOperation(OperationAnalysisContext context, INamedTyp { var operation = (IInvocationOperation)context.Operation; IMethodSymbol targetMethod = operation.TargetMethod; - if (targetMethod.Name != "AreSame" || + if ((targetMethod.Name != "AreSame" && targetMethod.Name != "AreNotSame") || !assertSymbol.Equals(operation.TargetMethod.ContainingType, SymbolEqualityComparer.Default)) { return; @@ -72,7 +72,8 @@ private static void AnalyzeOperation(OperationAnalysisContext context, INamedTyp if (argExpected.Value.WalkDownConversion().Type?.IsValueType == true || argActual.Value.WalkDownConversion().Type?.IsValueType == true) { - context.ReportDiagnostic(operation.CreateDiagnostic(Rule)); + string suggestedReplacement = targetMethod.Name == "AreSame" ? "AreEqual" : "AreNotEqual"; + context.ReportDiagnostic(operation.CreateDiagnostic(Rule, targetMethod.Name, suggestedReplacement)); } } } diff --git a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs index 8b7c3bc0da..0b67805132 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs @@ -181,7 +181,7 @@ internal static string AssertionArgsShouldBePassedInCorrectOrderTitle { } /// - /// Looks up a localized string similar to Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens.. + /// Looks up a localized string similar to Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass.. /// internal static string AvoidAssertAreSameWithValueTypesDescription { get { @@ -190,7 +190,7 @@ internal static string AvoidAssertAreSameWithValueTypesDescription { } /// - /// Looks up a localized string similar to Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. + /// Looks up a localized string similar to Use '{0}' instead of '{1}' when comparing value types. /// internal static string AvoidAssertAreSameWithValueTypesMessageFormat { get { @@ -199,7 +199,7 @@ internal static string AvoidAssertAreSameWithValueTypesMessageFormat { } /// - /// Looks up a localized string similar to Don't use 'Assert.AreSame' with value types. + /// Looks up a localized string similar to Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types. /// internal static string AvoidAssertAreSameWithValueTypesTitle { get { diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx index 93e6d7f3da..a0c20d4122 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.resx +++ b/src/Analyzers/MSTest.Analyzers/Resources.resx @@ -544,12 +544,12 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - \ No newline at end of file + diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index 6e330b099f..fea7e43a4b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -118,18 +118,18 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index e8158f968a..d97754638a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -118,18 +118,18 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index d906f03e01..5314ae2834 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -118,18 +118,18 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 5007193e4a..8c619eb032 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -118,18 +118,18 @@ Le type doit être une classe - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index 04e4eab6eb..5f77bc4ccc 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -118,18 +118,18 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index ef8201b9f2..c6bd722af3 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -118,18 +118,18 @@ The type declaring these methods should also respect the following rules: - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 01418be2c5..aa32398e06 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -118,18 +118,18 @@ The type declaring these methods should also respect the following rules: - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 71f8dc79e2..519ae66ab8 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -118,18 +118,18 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 07cc18781f..31cea31278 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -118,18 +118,18 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index ec3a3f092e..d7be24e727 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -121,18 +121,18 @@ The type declaring these methods should also respect the following rules: - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index efebdd5ad3..67a0463e19 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -118,18 +118,18 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 2c8a1b9bc0..b6bc1e5a0d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -118,18 +118,18 @@ The type declaring these methods should also respect the following rules: - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index c8c3516c3c..508370179d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -118,18 +118,18 @@ The type declaring these methods should also respect the following rules: - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types. Passing a value type to 'Assert.AreSame' will be boxed (creating a new object). Because 'Assert.AreSame' does the comparison by reference, it will fail when boxing happens. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types - Use 'Assert.AreEqual' instead of 'Assert.AreSame' when comparing value types + Use '{0}' instead of '{1}' when comparing value types + Use '{0}' instead of '{1}' when comparing value types - Don't use 'Assert.AreSame' with value types - Don't use 'Assert.AreSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs index 42c8306e5e..11f7b53938 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs @@ -57,4 +57,52 @@ public void TestMethod() await VerifyCS.VerifyCodeFixAsync(code, code); } + + [TestMethod] + public async Task UseAssertAreNotSameWithValueTypes_Diagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void TestMethod() + { + // Both are value types + [|Assert.AreNotSame(0, 1)|]; + [|Assert.AreNotSame(0, 1, "Message")|]; + [|Assert.AreNotSame(0, 1, "Message {0}", "Arg")|]; + [|Assert.AreNotSame(message: "Message", notExpected: 0, actual: 1)|]; + + [|Assert.AreNotSame(0, 1)|]; + [|Assert.AreNotSame(0, 1, "Message")|]; + [|Assert.AreNotSame(0, 1, "Message {0}", "Arg")|]; + [|Assert.AreNotSame(message: "Message", notExpected: 0, actual: 1)|]; + + // Expected is value type. This is always-failing assert. + [|Assert.AreNotSame("0", 1)|]; + [|Assert.AreNotSame("0", 1, "Message")|]; + [|Assert.AreNotSame("0", 1, "Message {0}", "Arg")|]; + [|Assert.AreNotSame(message: "Message", notExpected: "0", actual: 1)|]; + + // Actual is value type. This is always-failing assert. + [|Assert.AreNotSame(0, "1")|]; + [|Assert.AreNotSame(0, "1", "Message")|]; + [|Assert.AreNotSame(0, "1", "Message {0}", "Arg")|]; + [|Assert.AreNotSame(message: "Message", notExpected: 0, actual: "1")|]; + + // Both are reference types. No diagnostic. + Assert.AreNotSame("0", "1"); + Assert.AreNotSame("0", "1", "Message"); + Assert.AreNotSame("0", "1", "Message {0}", "Arg"); + Assert.AreNotSame(message: "Message", notExpected: "0", actual: "1"); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); + } } From da39a9b466a160af8f054806c8ff7759a4d28566 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 6 Jan 2025 14:07:00 +0100 Subject: [PATCH 225/273] Move ResolveTestContext from TypeCache to TestClassInfo (#4498) --- .../Execution/TestClassInfo.cs | 41 +++++++++++++++++-- .../MSTest.TestAdapter/Execution/TypeCache.cs | 41 +------------------ .../Execution/ClassCleanupManagerTests.cs | 2 +- .../Execution/TestClassInfoTests.cs | 6 +-- .../Execution/TestMethodInfoTests.cs | 26 +++++------- .../Execution/TestMethodRunnerTests.cs | 3 +- .../Execution/TypeCacheTests.cs | 2 + 7 files changed, 55 insertions(+), 66 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index 417b507c24..32543a26c9 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -24,6 +24,11 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; #endif public class TestClassInfo { + /// + /// Test context property name. + /// + private const string TestContextPropertyName = "TestContext"; + private readonly Lock _testClassExecuteSyncObject = new(); /// @@ -31,21 +36,19 @@ public class TestClassInfo /// /// Underlying test class type. /// Constructor for the test class. - /// Reference to the property in test class. /// Test class attribute. /// Parent assembly info. internal TestClassInfo( Type type, ConstructorInfo constructor, bool isParameterlessConstructor, - PropertyInfo? testContextProperty, TestClassAttribute classAttribute, TestAssemblyInfo parent) { ClassType = type; Constructor = constructor; IsParameterlessConstructor = isParameterlessConstructor; - TestContextProperty = testContextProperty; + TestContextProperty = ResolveTestContext(type); Parent = parent; ClassAttribute = classAttribute; } @@ -767,4 +770,36 @@ void DoRun() Resource.ClassCleanupWasCancelled, Resource.ClassCleanupTimedOut); } + + /// + /// Resolves the test context property. + /// + /// The class Type. + /// The for TestContext property. Null if not defined. + private static PropertyInfo? ResolveTestContext(Type classType) + { + try + { + PropertyInfo? testContextProperty = PlatformServiceProvider.Instance.ReflectionOperations.GetRuntimeProperty(classType, TestContextPropertyName, includeNonPublic: false); + if (testContextProperty == null) + { + // that's okay may be the property was not defined + return null; + } + + // check if testContextProperty is of correct type + if (!string.Equals(testContextProperty.PropertyType.FullName, typeof(TestContext).FullName, StringComparison.Ordinal)) + { + string errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_TestContextTypeMismatchLoadError, classType.FullName); + throw new TypeInspectionException(errorMessage); + } + + return testContextProperty; + } + catch (AmbiguousMatchException ex) + { + string errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_TestContextLoadError, classType.FullName, ex.Message); + throw new TypeInspectionException(errorMessage); + } + } } diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index 5d96f9e6f4..63997f4b6b 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -18,11 +18,6 @@ namespace Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; /// internal sealed class TypeCache : MarshalByRefObject { - /// - /// Test context property name. - /// - private const string TestContextPropertyName = "TestContext"; - /// /// Predefined test Attribute names. /// @@ -311,13 +306,11 @@ private TestClassInfo CreateClassInfo(Type classType, TestMethod testMethod) ConstructorInfo constructor = selectedConstructor.Value.CtorInfo; bool isParameterLessConstructor = selectedConstructor.Value.IsParameterless; - PropertyInfo? testContextProperty = ResolveTestContext(classType); - TestAssemblyInfo assemblyInfo = GetAssemblyInfo(classType); TestClassAttribute? testClassAttribute = ReflectHelper.Instance.GetFirstDerivedAttributeOrDefault(classType, inherit: false); DebugEx.Assert(testClassAttribute is not null, "testClassAttribute is null"); - var classInfo = new TestClassInfo(classType, constructor, isParameterLessConstructor, testContextProperty, testClassAttribute, assemblyInfo); + var classInfo = new TestClassInfo(classType, constructor, isParameterLessConstructor, testClassAttribute, assemblyInfo); // List holding the instance of the initialize/cleanup methods // to be passed into the tuples' queue when updating the class info. @@ -361,38 +354,6 @@ private TestClassInfo CreateClassInfo(Type classType, TestMethod testMethod) return classInfo; } - /// - /// Resolves the test context property. - /// - /// The class Type. - /// The for TestContext property. Null if not defined. - private static PropertyInfo? ResolveTestContext(Type classType) - { - try - { - PropertyInfo? testContextProperty = PlatformServiceProvider.Instance.ReflectionOperations.GetRuntimeProperty(classType, TestContextPropertyName, includeNonPublic: false); - if (testContextProperty == null) - { - // that's okay may be the property was not defined - return null; - } - - // check if testContextProperty is of correct type - if (!string.Equals(testContextProperty.PropertyType.FullName, typeof(TestContext).FullName, StringComparison.Ordinal)) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_TestContextTypeMismatchLoadError, classType.FullName); - throw new TypeInspectionException(errorMessage); - } - - return testContextProperty; - } - catch (AmbiguousMatchException ex) - { - string errorMessage = string.Format(CultureInfo.CurrentCulture, Resource.UTA_TestContextLoadError, classType.FullName, ex.Message); - throw new TypeInspectionException(errorMessage); - } - } - #endregion #region AssemblyInfo creation and cache logic. diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/ClassCleanupManagerTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/ClassCleanupManagerTests.cs index 2bad83bade..64fa22ef13 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/ClassCleanupManagerTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/ClassCleanupManagerTests.cs @@ -33,7 +33,7 @@ public void AssemblyCleanupRunsAfterAllTestsFinishEvenIfWeScheduleTheSameTestMul var classCleanupManager = new ClassCleanupManager(testsToRun, ClassCleanupBehavior.EndOfClass, ClassCleanupBehavior.EndOfClass, reflectHelper); - TestClassInfo testClassInfo = new(typeof(ClassCleanupManagerTests), null, true, null, null, null) + TestClassInfo testClassInfo = new(typeof(ClassCleanupManagerTests), null, true, null, null) { // This needs to be set, to allow running class cleanup. ClassCleanupMethod = classCleanupMethodInfo, diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs index 2c2bfa50dd..99c1297130 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestClassInfoTests.cs @@ -21,8 +21,6 @@ public class TestClassInfoTests : TestContainer private readonly ConstructorInfo _testClassConstructor; - private readonly PropertyInfo _testContextProperty; - private readonly UTF.TestClassAttribute _testClassAttribute; private readonly TestAssemblyInfo _testAssemblyInfo; @@ -35,7 +33,6 @@ public TestClassInfoTests() { _testClassType = typeof(DummyTestClass); _testClassConstructor = _testClassType.GetConstructors().First(); - _testContextProperty = _testClassType.GetProperties().First(); _testClassAttribute = (UTF.TestClassAttribute)_testClassType.GetCustomAttributes().First(); _testAssemblyInfo = new TestAssemblyInfo(_testClassType.Assembly); @@ -43,7 +40,6 @@ public TestClassInfoTests() _testClassType, _testClassConstructor, true, - _testContextProperty, _testClassAttribute, _testAssemblyInfo); @@ -68,7 +64,7 @@ public TestClassInfoTests() public void TestClassInfoConstructorGetsTheConstructorInfoForTestClass() => Verify(_testClassConstructor == _testClassInfo.Constructor); - public void TestClassInfoTestContextPropertyGetsAReferenceToTheTestContextDefinedInTestClass() => Verify(_testContextProperty == _testClassInfo.TestContextProperty); + public void TestClassInfoTestContextPropertyGetsAReferenceToTheTestContextDefinedInTestClass() => Verify(_testClassInfo.TestContextProperty == _testClassType.GetProperty("TestContext")); public void TestClassInfoParentGetsAReferenceToTheParentAssemblyForTheTestClass() => Verify(_testAssemblyInfo == _testClassInfo.Parent); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs index a884c94ffe..7bd0f0cd76 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs @@ -31,8 +31,6 @@ public class TestMethodInfoTests : TestContainer private readonly UTF.TestMethodAttribute _testMethodAttribute; - private readonly PropertyInfo _testContextProperty; - private readonly TestAssemblyInfo _testAssemblyInfo; private readonly ConstructorInfo _constructorInfo; @@ -51,12 +49,11 @@ public TestMethodInfoTests() _methodInfo = typeof(DummyTestClass).GetMethods().Single(m => m.Name.Equals("DummyTestMethod", StringComparison.Ordinal)); _classAttribute = new UTF.TestClassAttribute(); _testMethodAttribute = new UTF.TestMethodAttribute(); - _testContextProperty = typeof(DummyTestClass).GetProperty("TestContext"); _testAssemblyInfo = new TestAssemblyInfo(typeof(DummyTestClass).Assembly); var testMethod = new TestMethod("dummyTestName", "dummyClassName", "dummyAssemblyName", false); _testContextImplementation = new TestContextImplementation(testMethod, new ThreadSafeStringWriter(null, "test"), new Dictionary()); - _testClassInfo = new TestClassInfo(typeof(DummyTestClass), _constructorInfo, true, _testContextProperty, _classAttribute, _testAssemblyInfo); + _testClassInfo = new TestClassInfo(typeof(DummyTestClass), _constructorInfo, true, _classAttribute, _testAssemblyInfo); _expectedException = new UTF.ExpectedExceptionAttribute(typeof(DivideByZeroException)); _testMethodOptions = new TestMethodOptions(TimeoutInfo.FromTimeout(3600 * 1000), _testContextImplementation, false, _testMethodAttribute); @@ -264,7 +261,7 @@ public void TestMethodInfoInvokeShouldSetErrorMessageIfTestClassConstructorThrow public void TestMethodInfoInvokeShouldSetErrorMessageIfTestClassConstructorThrowsWithoutInnerException() { ConstructorInfo ctorInfo = typeof(DummyTestClassWithParameterizedCtor).GetConstructors().Single(); - var testClass = new TestClassInfo(typeof(DummyTestClassWithParameterizedCtor), ctorInfo, true, _testContextProperty, _classAttribute, _testAssemblyInfo); + var testClass = new TestClassInfo(typeof(DummyTestClassWithParameterizedCtor), ctorInfo, true, _classAttribute, _testAssemblyInfo); var method = new TestMethodInfo(_methodInfo, testClass, _testMethodOptions); UTF.TestResult result = method.Invoke(null); @@ -294,7 +291,7 @@ public void TestMethodInfoInvokeShouldSetStackTraceInformationIfTestClassConstru public void TestMethodInfoInvokeShouldSetStackTraceInformationIfTestClassConstructorThrowsWithoutInnerException() { ConstructorInfo ctorInfo = typeof(DummyTestClassWithParameterizedCtor).GetConstructors().Single(); - var testClass = new TestClassInfo(typeof(DummyTestClassWithParameterizedCtor), ctorInfo, true, _testContextProperty, _classAttribute, _testAssemblyInfo); + var testClass = new TestClassInfo(typeof(DummyTestClassWithParameterizedCtor), ctorInfo, true, _classAttribute, _testAssemblyInfo); var method = new TestMethodInfo(_methodInfo, testClass, _testMethodOptions); var exception = method.Invoke(null).TestFailureException as TestFailedException; @@ -323,7 +320,7 @@ public void TestMethodInfoInvokeShouldSetResultFilesIfTestContextHasAttachments( public void TestMethodInfoInvoke_WhenCtorHasOneParameterOfTypeTestContext_SetsItToTestContext() { ConstructorInfo ctorInfo = typeof(DummyTestClass).GetConstructor([typeof(UTFExtension.TestContext)]); - var testClassInfo = new TestClassInfo(typeof(DummyTestClass), ctorInfo, false, _testContextProperty, _classAttribute, _testAssemblyInfo); + var testClassInfo = new TestClassInfo(typeof(DummyTestClass), ctorInfo, false, _classAttribute, _testAssemblyInfo); var testMethodInfo = new TestMethodInfo(_methodInfo, testClassInfo, _testMethodOptions); UTF.TestResult result = testMethodInfo.Invoke(null); @@ -337,7 +334,7 @@ public void TestMethodInfoInvoke_WhenCtorHasOneParameterOfTypeTestContext_SetsIt public void TestMethodInfoInvokeShouldNotThrowIfTestContextIsNotPresent() { - var testClass = new TestClassInfo(typeof(DummyTestClass), _constructorInfo, true, null, _classAttribute, _testAssemblyInfo); + var testClass = new TestClassInfo(typeof(DummyTestClass), _constructorInfo, true, _classAttribute, _testAssemblyInfo); var method = new TestMethodInfo(_methodInfo, testClass, _testMethodOptions); UTF.TestResult result; @@ -349,8 +346,7 @@ public void TestMethodInfoInvokeShouldNotThrowIfTestContextIsNotPresent() public void TestMethodInfoInvokeShouldNotThrowIfTestContextDoesNotHaveASetter() { - PropertyInfo testContext = typeof(DummyTestClassWithTestContextWithoutSetter).GetProperties().Single(); - var testClass = new TestClassInfo(typeof(DummyTestClass), _constructorInfo, true, testContext, _classAttribute, _testAssemblyInfo); + var testClass = new TestClassInfo(typeof(DummyTestClass), _constructorInfo, true, _classAttribute, _testAssemblyInfo); var method = new TestMethodInfo(_methodInfo, testClass, _testMethodOptions); UTF.TestResult result; @@ -410,7 +406,7 @@ public void TestMethodInfoInvokeShouldSetStackTraceInformationIfSetTestContextTh public void TestMethodInfoInvoke_WhenCtorHasOneParameterOfTypeTestContextAndTestContextProperty_InitializeBothTestContexts() { ConstructorInfo ctorInfo = typeof(DummyTestClass).GetConstructor([typeof(UTFExtension.TestContext)]); - var testClassInfo = new TestClassInfo(typeof(DummyTestClass), ctorInfo, false, _testContextProperty, _classAttribute, _testAssemblyInfo); + var testClassInfo = new TestClassInfo(typeof(DummyTestClass), ctorInfo, false, _classAttribute, _testAssemblyInfo); var testMethodInfo = new TestMethodInfo(_methodInfo, testClassInfo, _testMethodOptions); UTFExtension.TestContext testContext = null; DummyTestClass.TestContextSetterBody = context => testContext = context as UTFExtension.TestContext; @@ -882,7 +878,7 @@ public void TestMethodInfoInvokeShouldCallDisposeForDisposableTestClass() bool disposeCalled = false; DummyTestClassWithDisposable.DisposeMethodBody = () => disposeCalled = true; ConstructorInfo ctorInfo = typeof(DummyTestClassWithDisposable).GetConstructor([])!; - var testClass = new TestClassInfo(typeof(DummyTestClassWithDisposable), ctorInfo, true, null, _classAttribute, _testAssemblyInfo); + var testClass = new TestClassInfo(typeof(DummyTestClassWithDisposable), ctorInfo, true, _classAttribute, _testAssemblyInfo); var method = new TestMethodInfo(typeof(DummyTestClassWithDisposable).GetMethod("DummyTestMethod"), testClass, _testMethodOptions); method.Invoke(null); @@ -897,7 +893,7 @@ public void TestMethodInfoInvoke_WhenTestClassIsAsyncDisposable_ShouldDisposeAsy bool asyncDisposeCalled = false; DummyTestClassWithAsyncDisposable.DisposeAsyncMethodBody = () => asyncDisposeCalled = true; ConstructorInfo ctorInfo = typeof(DummyTestClassWithAsyncDisposable).GetConstructor([])!; - var testClass = new TestClassInfo(typeof(DummyTestClassWithAsyncDisposable), ctorInfo, true, null, _classAttribute, _testAssemblyInfo); + var testClass = new TestClassInfo(typeof(DummyTestClassWithAsyncDisposable), ctorInfo, true, _classAttribute, _testAssemblyInfo); var method = new TestMethodInfo(typeof(DummyTestClassWithAsyncDisposable).GetMethod("DummyTestMethod"), testClass, _testMethodOptions); // Act @@ -918,7 +914,7 @@ public void TestMethodInfoInvoke_WhenTestClassIsDisposableAndAsyncDisposable_Sho DummyTestClassWithAsyncDisposableAndDisposable.DisposeAsyncMethodBody = () => disposeAsyncCalledOrder = ++order; ConstructorInfo ctorInfo = typeof(DummyTestClassWithAsyncDisposableAndDisposable).GetConstructor([])!; - var testClass = new TestClassInfo(typeof(DummyTestClassWithAsyncDisposableAndDisposable), ctorInfo, true, null, _classAttribute, _testAssemblyInfo); + var testClass = new TestClassInfo(typeof(DummyTestClassWithAsyncDisposableAndDisposable), ctorInfo, true, _classAttribute, _testAssemblyInfo); var method = new TestMethodInfo(typeof(DummyTestClassWithAsyncDisposableAndDisposable).GetMethod("DummyTestMethod"), testClass, _testMethodOptions); // Act @@ -936,7 +932,7 @@ public void TestMethodInfoInvokeShouldCallDisposeForDisposableTestClassIfTestCle DummyTestClassWithDisposable.DisposeMethodBody = () => disposeCalled = true; DummyTestClassWithDisposable.DummyTestCleanupMethodBody = classInstance => throw new NotImplementedException(); ConstructorInfo ctorInfo = typeof(DummyTestClassWithDisposable).GetConstructor([])!; - var testClass = new TestClassInfo(typeof(DummyTestClassWithDisposable), ctorInfo, true, null, _classAttribute, _testAssemblyInfo) + var testClass = new TestClassInfo(typeof(DummyTestClassWithDisposable), ctorInfo, true, _classAttribute, _testAssemblyInfo) { TestCleanupMethod = typeof(DummyTestClassWithDisposable).GetMethod("DummyTestCleanupMethod"), }; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs index 8231ee2497..c11710a862 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodRunnerTests.cs @@ -63,10 +63,9 @@ public TestMethodRunnerTests() private static TestClassInfo GetTestClassInfo() { ConstructorInfo constructorInfo = typeof(T).GetConstructor([])!; - PropertyInfo testContextProperty = typeof(T).GetProperty("TestContext"); var classAttribute = new TestClassAttribute(); var testAssemblyInfo = new TestAssemblyInfo(typeof(T).Assembly); - return new TestClassInfo(typeof(T), constructorInfo, isParameterlessConstructor: true, testContextProperty, classAttribute, testAssemblyInfo); + return new TestClassInfo(typeof(T), constructorInfo, isParameterlessConstructor: true, classAttribute, testAssemblyInfo); } protected override void Dispose(bool disposing) diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs index 36f83f5d95..3e0bd1ccb3 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TypeCacheTests.cs @@ -1507,6 +1507,7 @@ private DummyTestClassWithNoDefaultConstructor(int a) } } + [DummyTestClass] private class DummyTestClassWithIncorrectTestContextType { // This is TP.TF type. @@ -1518,6 +1519,7 @@ private class DummyTestClassWithTestContextProperty : DummyTestClassWithIncorrec public new string TestContext { get; set; } } + [DummyTestClass] private class DummyTestClassWithMultipleTestContextProperties : DummyTestClassWithTestContextProperty; [DummyTestClass] From 91b6b0f2c0394b0726f21f3fbc98c51a342c5076 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 6 Jan 2025 14:36:46 +0100 Subject: [PATCH 226/273] Implement analyzer and codefix to switch to Assert.ThrowsExactly[Async] (#4459) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../CodeFixResources.Designer.cs | 9 + .../CodeFixResources.resx | 5 +- .../UseNewerAssertThrowsFixer.cs | 156 +++++++++ .../xlf/CodeFixResources.cs.xlf | 5 + .../xlf/CodeFixResources.de.xlf | 5 + .../xlf/CodeFixResources.es.xlf | 5 + .../xlf/CodeFixResources.fr.xlf | 5 + .../xlf/CodeFixResources.it.xlf | 5 + .../xlf/CodeFixResources.ja.xlf | 5 + .../xlf/CodeFixResources.ko.xlf | 5 + .../xlf/CodeFixResources.pl.xlf | 5 + .../xlf/CodeFixResources.pt-BR.xlf | 5 + .../xlf/CodeFixResources.ru.xlf | 5 + .../xlf/CodeFixResources.tr.xlf | 5 + .../xlf/CodeFixResources.zh-Hans.xlf | 5 + .../xlf/CodeFixResources.zh-Hant.xlf | 5 + .../AnalyzerReleases.Unshipped.md | 3 +- .../MSTest.Analyzers/Helpers/DiagnosticIds.cs | 1 + .../Helpers/WellKnownTypeNames.cs | 1 + .../MSTest.Analyzers/Resources.Designer.cs | 18 ++ src/Analyzers/MSTest.Analyzers/Resources.resx | 6 + .../UseNewerAssertThrowsAnalyzer.cs | 82 +++++ .../MSTest.Analyzers/xlf/Resources.cs.xlf | 10 + .../MSTest.Analyzers/xlf/Resources.de.xlf | 10 + .../MSTest.Analyzers/xlf/Resources.es.xlf | 10 + .../MSTest.Analyzers/xlf/Resources.fr.xlf | 10 + .../MSTest.Analyzers/xlf/Resources.it.xlf | 10 + .../MSTest.Analyzers/xlf/Resources.ja.xlf | 10 + .../MSTest.Analyzers/xlf/Resources.ko.xlf | 10 + .../MSTest.Analyzers/xlf/Resources.pl.xlf | 10 + .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 10 + .../MSTest.Analyzers/xlf/Resources.ru.xlf | 10 + .../MSTest.Analyzers/xlf/Resources.tr.xlf | 10 + .../xlf/Resources.zh-Hans.xlf | 10 + .../xlf/Resources.zh-Hant.xlf | 10 + .../UseNewerAssertThrowsAnalyzerTests.cs | 298 ++++++++++++++++++ 36 files changed, 772 insertions(+), 2 deletions(-) create mode 100644 src/Analyzers/MSTest.Analyzers.CodeFixes/UseNewerAssertThrowsFixer.cs create mode 100644 src/Analyzers/MSTest.Analyzers/UseNewerAssertThrowsAnalyzer.cs create mode 100644 test/UnitTests/MSTest.Analyzers.UnitTests/UseNewerAssertThrowsAnalyzerTests.cs diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs index 23c6c67073..f5a7523e84 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs @@ -204,6 +204,15 @@ internal static string UseAttributeOnTestMethodFix { } } + /// + /// Looks up a localized string similar to Use '{0}'. + /// + internal static string UseNewerAssertThrows { + get { + return ResourceManager.GetString("UseNewerAssertThrows", resourceCulture); + } + } + /// /// Looks up a localized string similar to Use '{0}'. /// diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx index a3f8296b3e..d59fe84364 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx @@ -168,4 +168,7 @@ Use '{0}' - \ No newline at end of file + + Use '{0}' + + diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/UseNewerAssertThrowsFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/UseNewerAssertThrowsFixer.cs new file mode 100644 index 0000000000..587c039756 --- /dev/null +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/UseNewerAssertThrowsFixer.cs @@ -0,0 +1,156 @@ +// 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 System.Composition; + +using Analyzer.Utilities; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.Simplification; + +using MSTest.Analyzers.Helpers; + +namespace MSTest.Analyzers; + +[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(UseNewerAssertThrowsFixer))] +[Shared] +public sealed class UseNewerAssertThrowsFixer : CodeFixProvider +{ + public sealed override ImmutableArray FixableDiagnosticIds { get; } + = ImmutableArray.Create(DiagnosticIds.UseNewerAssertThrowsRuleId); + + public override FixAllProvider GetFixAllProvider() + // See https://github.com/dotnet/roslyn/blob/main/docs/analyzers/FixAllProvider.md for more information on Fix All Providers + => WellKnownFixAllProviders.BatchFixer; + + public override async Task RegisterCodeFixesAsync(CodeFixContext context) + { + SyntaxNode root = await context.Document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + Diagnostic diagnostic = context.Diagnostics[0]; + + SyntaxNode diagnosticNode = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); + if (diagnosticNode is not InvocationExpressionSyntax invocation) + { + Debug.Fail($"Is this an interesting scenario where IInvocationOperation for Assert call isn't associated with InvocationExpressionSyntax? SyntaxNode type: '{diagnosticNode.GetType()}', Text: '{diagnosticNode.GetText()}'"); + return; + } + + SyntaxNode methodNameIdentifier = invocation.Expression; + if (methodNameIdentifier is MemberAccessExpressionSyntax memberAccess) + { + methodNameIdentifier = memberAccess.Name; + } + + if (methodNameIdentifier is not GenericNameSyntax genericNameSyntax) + { + Debug.Fail($"Is this an interesting scenario where we are unable to retrieve GenericNameSyntax corresponding to the assert method? SyntaxNode type: '{methodNameIdentifier}', Text: '{methodNameIdentifier.GetText()}'."); + return; + } + + string updatedMethodName = genericNameSyntax.Identifier.Text switch + { + "ThrowsException" => "ThrowsExactly", + "ThrowsExceptionAsync" => "ThrowsExactlyAsync", + // The analyzer should report a diagnostic only for ThrowsException and ThrowsExceptionAsync + _ => throw ApplicationStateGuard.Unreachable(), + }; + + context.RegisterCodeFix( + CodeAction.Create( + title: string.Format(CultureInfo.InvariantCulture, CodeFixResources.UseNewerAssertThrows, updatedMethodName), + ct => Task.FromResult(context.Document.WithSyntaxRoot(UpdateMethodName(new SyntaxEditor(root, context.Document.Project.Solution.Workspace), invocation, genericNameSyntax, updatedMethodName, diagnostic.AdditionalLocations))), + equivalenceKey: nameof(UseProperAssertMethodsFixer)), + diagnostic); + } + + private static SyntaxNode UpdateMethodName(SyntaxEditor editor, InvocationExpressionSyntax invocation, GenericNameSyntax genericNameSyntax, string updatedMethodName, IReadOnlyList additionalLocations) + { + editor.ReplaceNode(genericNameSyntax, genericNameSyntax.WithIdentifier(SyntaxFactory.Identifier(updatedMethodName).WithTriviaFrom(genericNameSyntax.Identifier))); + + // The object[] parameter to format the message is named parameters in the old ThrowsException[Async] methods, but is named messageArgs in the new ThrowsExactly[Async] methods. + if (invocation.ArgumentList.Arguments.FirstOrDefault(arg => arg.NameColon is { Name.Identifier.Text: "parameters" }) is { } arg) + { + editor.ReplaceNode(arg.NameColon!.Name, arg.NameColon!.Name.WithIdentifier(SyntaxFactory.Identifier("messageArgs").WithTriviaFrom(arg.NameColon.Name.Identifier))); + } + + if (additionalLocations.Count != 1) + { + return editor.GetChangedRoot(); + } + + // The existing ThrowsException call is using the Func overload. The new ThrowsExactly method does not have this overload, so we need to adjust. + // This is a best effort handling. + SyntaxNode actionArgument = editor.OriginalRoot.FindNode(additionalLocations[0].SourceSpan, getInnermostNodeForTie: true); + + if (actionArgument is ParenthesizedLambdaExpressionSyntax lambdaSyntax) + { + if (lambdaSyntax.ExpressionBody is not null) + { + editor.ReplaceNode( + lambdaSyntax.ExpressionBody, + AssignToDiscard(lambdaSyntax.ExpressionBody)); + } + else if (lambdaSyntax.Block is not null) + { + // This is more complex. We need to iterate through all descendants of type ReturnStatementSyntax, and split it into two statements. + // The first statement will be an assignment expression to a discard, and the second statement will be 'return;'. + // We may even need to add extra braces in case the return statement (for example) is originally inside an if statement without braces. + // For example: + // if (condition) + // return Whatever; + // should be converted to: + // if (condition) + // { + // _ = Whatever; + // return; + // } + // Keep in mind: When descending into descendant nodes, we shouldn't descend into potential other lambda expressions or local functions. + IEnumerable returnStatements = lambdaSyntax.Block.DescendantNodes(descendIntoChildren: node => node is not (LocalFunctionStatementSyntax or AnonymousFunctionExpressionSyntax)).OfType(); + foreach (ReturnStatementSyntax returnStatement in returnStatements) + { + if (returnStatement.Expression is not { } returnExpression) + { + // This should be an error in user code. + continue; + } + + ExpressionStatementSyntax returnReplacement = SyntaxFactory.ExpressionStatement(AssignToDiscard(returnStatement.Expression)); + + if (returnStatement.Parent is BlockSyntax blockSyntax) + { + editor.InsertAfter(returnStatement, SyntaxFactory.ReturnStatement()); + editor.ReplaceNode(returnStatement, returnReplacement); + } + else + { + editor.ReplaceNode( + returnStatement, + SyntaxFactory.Block( + returnReplacement, + SyntaxFactory.ReturnStatement())); + } + } + } + } + else if (actionArgument is ExpressionSyntax expressionSyntax) + { + editor.ReplaceNode( + expressionSyntax, + SyntaxFactory.ParenthesizedLambdaExpression( + SyntaxFactory.ParameterList(), + block: null, + expressionBody: AssignToDiscard(SyntaxFactory.InvocationExpression(SyntaxFactory.ParenthesizedExpression(expressionSyntax).WithAdditionalAnnotations(Simplifier.Annotation))))); + } + + return editor.GetChangedRoot(); + } + + private static AssignmentExpressionSyntax AssignToDiscard(ExpressionSyntax expression) + => SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, SyntaxFactory.IdentifierName("_"), expression); +} diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf index d58b3e72b6..70893b6e64 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf @@ -82,6 +82,11 @@ Přidat [TestMethod] + + Use '{0}' + Use '{0}' + + Use '{0}' Použít {0} diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf index 563149bafd..2eda581eb9 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf @@ -82,6 +82,11 @@ „[TestMethod]“ hinzufügen + + Use '{0}' + Use '{0}' + + Use '{0}' "{0}" verwenden diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf index 35e521fa47..7135f5bedf 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf @@ -82,6 +82,11 @@ Agregar '[TestMethod]' + + Use '{0}' + Use '{0}' + + Use '{0}' Usar "{0}" diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf index 0dde1ce7ba..89525653e5 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf @@ -82,6 +82,11 @@ Ajouter « [TestMethod] » + + Use '{0}' + Use '{0}' + + Use '{0}' Utiliser « {0} » diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf index acacf8c10d..4e81efb9b2 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf @@ -82,6 +82,11 @@ Aggiungi '[TestMethod]' + + Use '{0}' + Use '{0}' + + Use '{0}' Usa '{0}' diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf index 99c1533bcf..bf289a600c 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf @@ -82,6 +82,11 @@ '[TestMethod]' の追加 + + Use '{0}' + Use '{0}' + + Use '{0}' '{0}' を使用します diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf index a4812d36aa..7db8bcdfb5 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf @@ -82,6 +82,11 @@ '[TestMethod]' 추가 + + Use '{0}' + Use '{0}' + + Use '{0}' '{0}' 사용 diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf index dfe805fc24..e327bf1b3e 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf @@ -82,6 +82,11 @@ Dodaj „[TestMethod]” + + Use '{0}' + Use '{0}' + + Use '{0}' Użyj „{0}” diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf index afb8abcafd..e3160981fb 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf @@ -82,6 +82,11 @@ Adicionar ''[TestMethod]" + + Use '{0}' + Use '{0}' + + Use '{0}' Usar '{0}' diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf index d81aae1484..10a50cb7e8 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf @@ -82,6 +82,11 @@ Добавить "[TestMethod]" + + Use '{0}' + Use '{0}' + + Use '{0}' Использовать "{0}" diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf index e9a368cbae..e5d55eef49 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf @@ -82,6 +82,11 @@ '[TestMethod]' ekle + + Use '{0}' + Use '{0}' + + Use '{0}' '{0}' kullan diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf index fe8e6c7875..acf884ead9 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf @@ -82,6 +82,11 @@ 添加“[TestMethod]” + + Use '{0}' + Use '{0}' + + Use '{0}' 使用“{0}” diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf index c30f129ce5..3c18ebee7e 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf @@ -82,6 +82,11 @@ 新增 '[TestMethod]' + + Use '{0}' + Use '{0}' + + Use '{0}' 使用 '{0}' diff --git a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md index 2bbee99456..f8b045e159 100644 --- a/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md +++ b/src/Analyzers/MSTest.Analyzers/AnalyzerReleases.Unshipped.md @@ -4,4 +4,5 @@ Rule ID | Category | Severity | Notes --------|----------|----------|------- -MSTEST0038 | `Usage` | Warning | AvoidAssertAreSameWithValueTypesAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0038) +MSTEST0038 | Usage | Warning | AvoidAssertAreSameWithValueTypesAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0038) +MSTEST0039 | Usage | Info | UseNewerAssertThrowsAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/core/testing/mstest-analyzers/mstest0039) diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs b/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs index 7c92ad22ca..60450d9c51 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/DiagnosticIds.cs @@ -43,4 +43,5 @@ internal static class DiagnosticIds public const string DoNotUseShadowingRuleId = "MSTEST0036"; public const string UseProperAssertMethodsRuleId = "MSTEST0037"; public const string AvoidAssertAreSameWithValueTypesRuleId = "MSTEST0038"; + public const string UseNewerAssertThrowsRuleId = "MSTEST0039"; } diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs b/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs index dacfbbf53b..900066e322 100644 --- a/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs +++ b/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs @@ -42,6 +42,7 @@ internal static class WellKnownTypeNames public const string System = "System"; public const string SystemCollectionsGenericIEnumerable1 = "System.Collections.Generic.IEnumerable`1"; public const string SystemDescriptionAttribute = "System.ComponentModel.DescriptionAttribute"; + public const string SystemFunc1 = "System.Func`1"; public const string SystemIAsyncDisposable = "System.IAsyncDisposable"; public const string SystemIDisposable = "System.IDisposable"; public const string SystemReflectionMethodInfo = "System.Reflection.MethodInfo"; diff --git a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs index 0b67805132..2ac0bd98dc 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs @@ -1069,6 +1069,24 @@ internal static string UseDeploymentItemWithTestMethodOrTestClassTitle { } } + /// + /// Looks up a localized string similar to Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException'. + /// + internal static string UseNewerAssertThrowsMessageFormat { + get { + return ResourceManager.GetString("UseNewerAssertThrowsMessageFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Use newer methods to assert exceptions. + /// + internal static string UseNewerAssertThrowsTitle { + get { + return ResourceManager.GetString("UseNewerAssertThrowsTitle", resourceCulture); + } + } + /// /// Looks up a localized string similar to By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'.. /// diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx index a0c20d4122..d206443a87 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.resx +++ b/src/Analyzers/MSTest.Analyzers/Resources.resx @@ -543,6 +543,12 @@ The type declaring these methods should also respect the following rules: '[DynamicData]' member '{0}.{1}' is not a property nor a method. Only properties and methods are supported. + + Use newer methods to assert exceptions + + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types diff --git a/src/Analyzers/MSTest.Analyzers/UseNewerAssertThrowsAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/UseNewerAssertThrowsAnalyzer.cs new file mode 100644 index 0000000000..0ccf036c59 --- /dev/null +++ b/src/Analyzers/MSTest.Analyzers/UseNewerAssertThrowsAnalyzer.cs @@ -0,0 +1,82 @@ +// 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 Microsoft.CodeAnalysis.Operations; + +using MSTest.Analyzers.Helpers; + +namespace MSTest.Analyzers; + +/// +/// MSTEST0039: Use newer 'Assert.Throws' methods. +/// +[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] +internal sealed class UseNewerAssertThrowsAnalyzer : DiagnosticAnalyzer +{ + private static readonly LocalizableResourceString Title = new(nameof(Resources.UseNewerAssertThrowsTitle), Resources.ResourceManager, typeof(Resources)); + private static readonly LocalizableResourceString MessageFormat = new(nameof(Resources.UseNewerAssertThrowsMessageFormat), Resources.ResourceManager, typeof(Resources)); + + internal static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create( + DiagnosticIds.UseNewerAssertThrowsRuleId, + Title, + MessageFormat, + null, + Category.Usage, + DiagnosticSeverity.Info, + isEnabledByDefault: true); + + 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.MicrosoftVisualStudioTestToolsUnitTestingAssert, out INamedTypeSymbol? assertTypeSymbol)) + { + return; + } + + INamedTypeSymbol? funcType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemFunc1); + context.RegisterOperationAction(context => AnalyzeInvocationOperation(context, assertTypeSymbol, funcType), OperationKind.Invocation); + }); + } + + private static void AnalyzeInvocationOperation(OperationAnalysisContext context, INamedTypeSymbol assertTypeSymbol, INamedTypeSymbol? funcType) + { + var operation = (IInvocationOperation)context.Operation; + IMethodSymbol targetMethod = operation.TargetMethod; + if (!SymbolEqualityComparer.Default.Equals(targetMethod.ContainingType, assertTypeSymbol) || + targetMethod.Name is not ("ThrowsException" or "ThrowsExceptionAsync")) + { + return; + } + + ImmutableArray additionalLocations = ImmutableArray.Empty; + + // The old synchronous ThrowsException method has an overload that takes a Func as the action. + // The new synchronous ThrowsExactly method does not have this overload, and only Action overload is available. + // Hence, the codefix should be aware of that to adjust accordingly. + // For example, 'Assert.ThrowsException(() => 5)' should be fixed to Assert.ThrowsExactly(() => _ = 5). + // Also, Assert.ThrowsException usage could be a long body with some return statements, which would be invalid for ThrowsExactly as there is only Action overload. + // The codefix should adjust any "return whatever;" statements to "_ = whatever;" followed by "return;" + // The codefix will know that it needs to adjust something if there is an additional location, which will be pointing to the action argument. + if (!targetMethod.Name.EndsWith("Async", StringComparison.Ordinal) && + targetMethod.Parameters[0].Type.OriginalDefinition.Equals(funcType, SymbolEqualityComparer.Default) && + operation.Arguments.FirstOrDefault(arg => arg.Parameter?.Ordinal == 0)?.Syntax.GetLocation() is { } additionalLocation) + { + additionalLocations = ImmutableArray.Create(additionalLocation); + } + + context.ReportDiagnostic(operation.CreateDiagnostic(Rule, additionalLocations, properties: null)); + } +} diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index fea7e43a4b..f187ab7e0a 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -739,6 +739,16 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: [DeploymentItem] se dá zadat jenom pro testovací třídu nebo testovací metodu. + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. Ve výchozím nastavení spouští MSTest testy v rámci stejného sestavení sekvenčně, což může vést k závažným omezením výkonu. Doporučuje se povolit atribut sestavení [Parallelize] k paralelnímu spouštění testů nebo explicitně použít atribut [DoNotParallelize] na úrovni sestavení, pokud je známo, že sestavení není paralelizovatelné. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index d97754638a..3cdeb35835 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -740,6 +740,16 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte „[DeploymentItem]“ kann nur für die Testklasse oder Testmethode angegeben werden. + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. Standardmäßig führt MSTest Tests in derselben Assembly sequentiell aus, was zu erheblichen Leistungseinschränkungen führen kann. Es wird empfohlen, das Assembly-Attribut "[Parallelize]" zu aktivieren, um Tests parallel auszuführen, oder, wenn bekannt ist, dass die Assembly nicht parallelisierbar ist, explizit das Assembly-Attribut "[DoNotParallelize]" zu verwenden. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 5314ae2834..003421091b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -739,6 +739,16 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: '[DeploymentItem]' solo se puede especificar en la clase de prueba o el método de prueba + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. De forma predeterminada, MSTest ejecuta pruebas en el mismo ensamblado secuencialmente, lo que puede provocar limitaciones de rendimiento graves. Se recomienda habilitar el atributo de ensamblado ''[Parallelize]'' o, si se sabe que el ensamblado no se puede paralelizar, usar explícitamente el atributo de nivel de ensamblado ''[DoNotParallelize]''. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 8c619eb032..902eb5a29e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -739,6 +739,16 @@ Le type doit être une classe « [DeploymentItem] » ne peut être spécifié que sur une classe de test ou une méthode de test + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. Par défaut, MSTest exécute des tests dans la même assembly de façon séquentielle, ce qui peut entraîner de graves limitations de performances. Il est recommandé d’activer l’attribut d’assemblée « [Parallelize] » pour exécuter des tests en parallèle ou, si l’assemblée est connu pour ne pas être parallélisable, d’utiliser explicitement l’attribut de niveau assemblée « [DoNotParallelize] ». diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index 5f77bc4ccc..5c866d7ac4 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -739,6 +739,16 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: '[DeploymentItem]' può essere specificato solo per la classe di test o il metodo di test + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. Per impostazione predefinita, MSTest esegue i test in sequenza nello stesso assemby, il che può causare gravi limitazioni delle prestazioni. È consigliabile abilitare l'attributo di assembly '[Parallelize]' per eseguire i test in parallelo, o, se l'assembly non è parallelizzabile, usare in modo esplicito l'attributo a livello di assembly '[DoNotParallelize]'. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index c6bd722af3..11352366ed 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -739,6 +739,16 @@ The type declaring these methods should also respect the following rules: '[DeploymentItem]' は、テスト クラスまたはテスト メソッドでのみ指定できます + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. 既定では、MSTest は同じアセンブリ内でテストを順番に実行するため、重大なパフォーマンス制限が生じる可能性があります。アセンブリ属性 '[Parallelize]' を有効にして並列でテストを実行するか、アセンブリが並列化できないことがわかっている場合は、アセンブリ レベル属性 '[DoNotParallelize]' を明示的に使用することをお勧めします。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index aa32398e06..befa4352ab 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -739,6 +739,16 @@ The type declaring these methods should also respect the following rules: '[DeploymentItem]'은(는) 테스트 클래스 또는 테스트 메서드에만 지정할 수 있습니다. + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. 기본적으로 MSTest는 동일한 어셈블리 내에서 테스트를 순차적으로 실행하므로 심각한 성능 제한이 발생할 수 있습니다. 어셈블리 특성 '[Parallelize]'가 병렬로 테스트를 실행하도록 설정하거나 어셈블리가 병렬화할 수 없는 것으로 알려진 경우 어셈블리 수준 특성 '[DoNotParallelize]'을(를) 명시적으로 사용하는 것이 좋습니다. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 519ae66ab8..c35df35cae 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -739,6 +739,16 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu Element „[DeploymentItem]” można określić tylko dla klasy testowej lub metody testowej + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. Domyślnie platforma MSTest uruchamia testy w ramach tego samego zestawu sekwencyjnie, co może prowadzić do poważnego ograniczenia wydajności. Zaleca się włączenie atrybutu zestawu „[Parallelize]”, aby uruchamiać testy równolegle, lub jeśli zestaw na to nie pozwala — użycie jawnie atrybutu poziomu zestawu „[DoNotParallelize]”. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 31cea31278..bcb20d8f7d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -739,6 +739,16 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: '[DeploymentItem]' pode ser especificado apenas na classe de teste ou método de teste + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. Por padrão, o MSTest executa testes no mesmo assembly sequencialmente, o que pode levar a limitações graves de desempenho. É recomendável habilitar o atributo de assembly ''[Parallelize]'' para executar testes em paralelo ou se o assembly for conhecido por não ser paralelizável, para usar explicitamente o atributo de nível de assembly ''[DoNotParallelize]''. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index d7be24e727..c98778ad01 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -751,6 +751,16 @@ The type declaring these methods should also respect the following rules: Указать "[DeploymentItem]" можно только для тестового класса или метода. + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. По умолчанию MSTest выполняет тесты в одной сборке последовательно, что может привести к серьезному ограничению производительности. Рекомендуется включить атрибут сборки "[Parallelize]", чтобы выполнять тесты параллельно, или явно использовать атрибут уровня сборки "[DoNotParallelize]", если известно, что сборка не поддерживает параллелизацию. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index 67a0463e19..d3393681b2 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -741,6 +741,16 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: '[DeploymentItem]' yalnızca test sınıfında veya test yönteminde belirtilebilir + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. Varsayılan olarak, MSTest hizmeti testleri aynı derleme içinde sırayla çalıştırır ve bu durum ciddi performans sınırlamalarına yol açabilir. Testleri paralel yürütmek için '[Parallelize]' derleme özniteliğini etkinleştirmeniz önerilir veya derlemenin paralelleştirilebilir olduğu biliniyorsa, doğrudan '[DoNotParallelize]' derleme düzeyi özniteliğini kullanmanız önerilir. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index b6bc1e5a0d..a875949ec2 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -739,6 +739,16 @@ The type declaring these methods should also respect the following rules: 只能对测试类或测试方法指定 "[DeploymentItem]" + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. 默认情况下,MSTest 将按顺序在同一程序集中运行测试,这可能会导致严重的性能限制。建议启用程序集属性“[Parallelize]”以并行运行测试,或者如果已知程序集不可并行,则显式使用程序集级别属性“DoNotParallelize”。 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 508370179d..3ec95cc99c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -739,6 +739,16 @@ The type declaring these methods should also respect the following rules: '[DeploymentItem]' 只能在測試類或測試方法上指定 + + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + + + + Use newer methods to assert exceptions + Use newer methods to assert exceptions + + By default, MSTest runs tests within the same assembly sequentially, which can lead to severe performance limitations. It is recommended to enable assembly attribute '[Parallelize]' to run tests in parallel, or if the assembly is known to not be parallelizable, to use explicitly the assembly level attribute '[DoNotParallelize]'. 根據預設,MSTest 會依順序執行在相同組件內的測試,這可能會導致嚴重的效能限制。建議啟用組件屬性 '[Parallelize]' 來平行執行測試,或者如果已知組件無法平行處理,則明確使用組件層級的屬性 '[DoNotParallelize]'。 diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseNewerAssertThrowsAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseNewerAssertThrowsAnalyzerTests.cs new file mode 100644 index 0000000000..1bc0223a6b --- /dev/null +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseNewerAssertThrowsAnalyzerTests.cs @@ -0,0 +1,298 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +using VerifyCS = MSTest.Analyzers.Test.CSharpCodeFixVerifier< + MSTest.Analyzers.UseNewerAssertThrowsAnalyzer, + MSTest.Analyzers.UseNewerAssertThrowsFixer>; + +namespace MSTest.Analyzers.Test; + +[TestClass] +public sealed class UseNewerAssertThrowsAnalyzerTests +{ + [TestMethod] + public async Task WhenAssertThrowsException_Diagnostic() + { + string code = """ + using System; + using System.Threading.Tasks; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + // action only overload + [|Assert.ThrowsException(() => Console.WriteLine())|]; + [|Assert.ThrowsException(action: () => Console.WriteLine())|]; + [|Assert.ThrowsExceptionAsync(() => Task.CompletedTask)|]; + [|Assert.ThrowsExceptionAsync(action: () => Task.CompletedTask)|]; + + // action and message overload + [|Assert.ThrowsException(() => Console.WriteLine(), "Message")|]; + [|Assert.ThrowsException(action: () => Console.WriteLine(), message: "Message")|]; + [|Assert.ThrowsException(message: "Message", action: () => Console.WriteLine())|]; + [|Assert.ThrowsException(action: () => Console.WriteLine(), "Message")|]; + [|Assert.ThrowsException(() => Console.WriteLine(), message: "Message")|]; + [|Assert.ThrowsExceptionAsync(() => Task.CompletedTask, "Message")|]; + [|Assert.ThrowsExceptionAsync(action: () => Task.CompletedTask, message: "Message")|]; + [|Assert.ThrowsExceptionAsync(message: "Message", action: () => Task.CompletedTask)|]; + [|Assert.ThrowsExceptionAsync(action: () => Task.CompletedTask, "Message")|]; + [|Assert.ThrowsExceptionAsync(() => Task.CompletedTask, message: "Message")|]; + + // action, message, and parameters overload + [|Assert.ThrowsException(() => Console.WriteLine(), "Message", "A", "B", "C")|]; + [|Assert.ThrowsException(() => Console.WriteLine(), "Message", parameters: new object[] { "A", "B", "C" })|]; + [|Assert.ThrowsExceptionAsync(() => Task.CompletedTask, "Message", "A", "B", "C")|]; + [|Assert.ThrowsExceptionAsync(() => Task.CompletedTask, "Message", parameters: new object[] { "A", "B", "C" })|]; + } + } + """; + + string fixedCode = """ + using System; + using System.Threading.Tasks; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + // action only overload + Assert.ThrowsExactly(() => Console.WriteLine()); + Assert.ThrowsExactly(action: () => Console.WriteLine()); + Assert.ThrowsExactlyAsync(() => Task.CompletedTask); + Assert.ThrowsExactlyAsync(action: () => Task.CompletedTask); + + // action and message overload + Assert.ThrowsExactly(() => Console.WriteLine(), "Message"); + Assert.ThrowsExactly(action: () => Console.WriteLine(), message: "Message"); + Assert.ThrowsExactly(message: "Message", action: () => Console.WriteLine()); + Assert.ThrowsExactly(action: () => Console.WriteLine(), "Message"); + Assert.ThrowsExactly(() => Console.WriteLine(), message: "Message"); + Assert.ThrowsExactlyAsync(() => Task.CompletedTask, "Message"); + Assert.ThrowsExactlyAsync(action: () => Task.CompletedTask, message: "Message"); + Assert.ThrowsExactlyAsync(message: "Message", action: () => Task.CompletedTask); + Assert.ThrowsExactlyAsync(action: () => Task.CompletedTask, "Message"); + Assert.ThrowsExactlyAsync(() => Task.CompletedTask, message: "Message"); + + // action, message, and parameters overload + Assert.ThrowsExactly(() => Console.WriteLine(), "Message", "A", "B", "C"); + Assert.ThrowsExactly(() => Console.WriteLine(), "Message", messageArgs: new object[] { "A", "B", "C" }); + Assert.ThrowsExactlyAsync(() => Task.CompletedTask, "Message", "A", "B", "C"); + Assert.ThrowsExactlyAsync(() => Task.CompletedTask, "Message", messageArgs: new object[] { "A", "B", "C" }); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + [TestMethod] + public async Task WhenAssertThrowsExceptionFuncOverloadExpressionBody_Diagnostic() + { + string code = """ + using System; + using System.Threading.Tasks; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + [|Assert.ThrowsException(() => 5)|]; + } + } + """; + + // NOTE: The discard is needed to avoid CS0201: Only assignment, call, increment, decrement, and new object expressions can be used as a statement + // This is because ThrowsException has a Func overload that is being used in the original code. + // But ThrowsExactly only has an Action overload. + string fixedCode = """ + using System; + using System.Threading.Tasks; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + Assert.ThrowsExactly(() => _ = 5); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + [TestMethod] + public async Task WhenAssertThrowsExceptionFuncOverloadComplexBody_Diagnostic() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + [|Assert.ThrowsException(() => + { + Console.WriteLine(); + Func x = () => + { + int LocalFunction() + { + // This shouldn't be touched. + return 0; + } + + // This shouldn't be touched. + return LocalFunction(); + }; + + if (true) + { + return 1; + } + else if (true) + return 2; + + return 3; + })|]; + } + } + """; + + string fixedCode = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + Assert.ThrowsExactly(() => + { + Console.WriteLine(); + Func x = () => + { + int LocalFunction() + { + // This shouldn't be touched. + return 0; + } + + // This shouldn't be touched. + return LocalFunction(); + }; + + if (true) + { + _ = 1; + return; + } + else if (true) + { + _ = 2; + return; + } + + _ = 3; + return; + }); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + [TestMethod] + public async Task WhenAssertThrowsExceptionFuncOverloadVariable_Diagnostic() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + Func action = () => _ = 5; + [|Assert.ThrowsException(action)|]; + } + } + """; + + string fixedCode = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + Func action = () => _ = 5; + Assert.ThrowsExactly(() => _ = action()); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + [TestMethod] + public async Task WhenAssertThrowsExceptionFuncOverloadBinaryExpression_Diagnostic() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + Func action = () => _ = 5; + [|Assert.ThrowsException(action + action)|]; + } + } + """; + + string fixedCode = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void MyTestMethod() + { + Func action = () => _ = 5; + Assert.ThrowsExactly(() => _ = (action + action)()); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } +} From e88a90e1ed20efd5d0b9f83c424181e3348722f5 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 6 Jan 2025 15:25:06 +0100 Subject: [PATCH 227/273] Fix main build (#4528) --- .../Execution/TestMethodInfoTests.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs index 7bd0f0cd76..b7b13af569 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// 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.VisualStudio.TestPlatform.MSTest.TestAdapter; @@ -1254,7 +1254,6 @@ public void ResolveExpectedExceptionShouldThrowWhenAttributeIsDefinedTwice_Diffe typeof(DummyTestClassForExpectedException), typeof(DummyTestClassForExpectedException).GetConstructor(Array.Empty()), isParameterlessConstructor: true, - null, new UTF.TestClassAttribute(), new TestAssemblyInfo(typeof(DummyTestClassForExpectedException).Assembly)); @@ -1269,7 +1268,6 @@ public void ResolveExpectedExceptionShouldThrowWhenAttributeIsDefinedTwice_SameC typeof(DummyTestClassForExpectedException), typeof(DummyTestClassForExpectedException).GetConstructor(Array.Empty()), isParameterlessConstructor: true, - null, new UTF.TestClassAttribute(), new TestAssemblyInfo(typeof(DummyTestClassForExpectedException).Assembly)); @@ -1285,7 +1283,6 @@ public void ResolveExpectedExceptionHelperShouldReturnExpectedExceptionAttribute typeof(DummyTestClassForExpectedException), typeof(DummyTestClassForExpectedException).GetConstructor(Array.Empty()), isParameterlessConstructor: true, - null, new UTF.TestClassAttribute(), new TestAssemblyInfo(typeof(DummyTestClassForExpectedException).Assembly)); @@ -1303,7 +1300,6 @@ public void ResolveExpectedExceptionHelperShouldReturnNullIfExpectedExceptionAtt typeof(DummyTestClassForExpectedException), typeof(DummyTestClassForExpectedException).GetConstructor(Array.Empty()), isParameterlessConstructor: true, - null, new UTF.TestClassAttribute(), new TestAssemblyInfo(typeof(DummyTestClassForExpectedException).Assembly)); From 5248f5d563e41d0be4f3394df7f02456dc28d2fa Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 6 Jan 2025 16:05:33 +0100 Subject: [PATCH 228/273] Update ExpectedException analyzer message/description to use the new Assert.Throws methods (#4527) --- src/Analyzers/MSTest.Analyzers/Resources.Designer.cs | 4 ++-- src/Analyzers/MSTest.Analyzers/Resources.resx | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf | 8 ++++---- src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf | 8 ++++---- 15 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs index 2ac0bd98dc..96683c893f 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers/Resources.Designer.cs @@ -208,7 +208,7 @@ internal static string AvoidAssertAreSameWithValueTypesTitle { } /// - /// 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.. + /// Looks up a localized string similar to Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception.. /// internal static string AvoidExpectedExceptionAttributeDescription { get { @@ -217,7 +217,7 @@ internal static string AvoidExpectedExceptionAttributeDescription { } /// - /// Looks up a localized string similar to Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]'. + /// Looks up a localized string similar to Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]'. /// internal static string AvoidExpectedExceptionAttributeMessageFormat { get { diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx index d206443a87..470293fe98 100644 --- a/src/Analyzers/MSTest.Analyzers/Resources.resx +++ b/src/Analyzers/MSTest.Analyzers/Resources.resx @@ -181,10 +181,10 @@ The type declaring these methods should also respect the following rules: Assertion arguments should be passed in the correct order - 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.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' Avoid '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index f187ab7e0a..992792f112 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -133,13 +133,13 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: - 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. - Preferujte Assert.ThrowsException nebo Assert.ThrowsExceptionAsync před [ExpectedException], protože zajišťuje, že očekávanou výjimku vyvolá pouze očekávané volání. Rozhraní API assert také poskytují větší flexibilitu a umožňují vyhodnocovat další vlastnosti výjimky. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Preferujte Assert.ThrowsException nebo Assert.ThrowsExceptionAsync před [ExpectedException], protože zajišťuje, že očekávanou výjimku vyvolá pouze očekávané volání. Rozhraní API assert také poskytují větší flexibilitu a umožňují vyhodnocovat další vlastnosti výjimky. - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - Preferovat Assert.ThrowsException/ThrowsExceptionAsync před [ExpectedException] + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Preferovat Assert.ThrowsException/ThrowsExceptionAsync před [ExpectedException] diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 3cdeb35835..e0e38db59c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -133,13 +133,13 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte - 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. - „Assert.ThrowsException“ oder „Assert.ThrowsExceptionAsync“ gegenüber „[ExpectedException]“ bevorzugen, da dadurch sichergestellt wird, dass nur der erwartete Aufruf die erwartete Ausnahme auslöst. Die Assert-APIs bieten außerdem mehr Flexibilität und ermöglichen es Ihnen, zusätzliche Eigenschaften der Ausführung zu bestätigen. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + „Assert.ThrowsException“ oder „Assert.ThrowsExceptionAsync“ gegenüber „[ExpectedException]“ bevorzugen, da dadurch sichergestellt wird, dass nur der erwartete Aufruf die erwartete Ausnahme auslöst. Die Assert-APIs bieten außerdem mehr Flexibilität und ermöglichen es Ihnen, zusätzliche Eigenschaften der Ausführung zu bestätigen. - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - „Assert.ThrowsException/ThrowsExceptionAsync“ gegenüber „[ExpectedException]“ bevorzugen + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + „Assert.ThrowsException/ThrowsExceptionAsync“ gegenüber „[ExpectedException]“ bevorzugen diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 003421091b..569bcdf6f4 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -133,13 +133,13 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: - 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. - Preferir "Assert.ThrowsException" o "Assert.ThrowsExceptionAsync" en lugar de '[ExpectedException]' ya que garantiza que solo la llamada esperada inicia la excepción esperada. Las API de aserción también proporcionan más flexibilidad y le permiten declarar propiedades adicionales de la ejecución. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Preferir "Assert.ThrowsException" o "Assert.ThrowsExceptionAsync" en lugar de '[ExpectedException]' ya que garantiza que solo la llamada esperada inicia la excepción esperada. Las API de aserción también proporcionan más flexibilidad y le permiten declarar propiedades adicionales de la ejecución. - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - Preferir "Assert.ThrowsException/ThrowsExceptionAsync" en lugar de "[ExpectedException]" + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Preferir "Assert.ThrowsException/ThrowsExceptionAsync" en lugar de "[ExpectedException]" diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 902eb5a29e..12c6845a8c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -133,13 +133,13 @@ Le type doit être une classe - 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. - Préférez « Assert.ThrowsException » ou « Assert.ThrowsExceptionAsync » à « [ExpectedException] », car cela assure que seul l’appel attendu lève l’exception attendue. Les API d’assertion offrent également plus de flexibilité et vous permettent de déclarer des propriétés supplémentaires de l’exception. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Préférez « Assert.ThrowsException » ou « Assert.ThrowsExceptionAsync » à « [ExpectedException] », car cela assure que seul l’appel attendu lève l’exception attendue. Les API d’assertion offrent également plus de flexibilité et vous permettent de déclarer des propriétés supplémentaires de l’exception. - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - Préférer « Assert.ThrowsException/ThrowsExceptionAsync » à « [ExpectedException] » + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Préférer « Assert.ThrowsException/ThrowsExceptionAsync » à « [ExpectedException] » diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index 5c866d7ac4..1d19a42b14 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -133,13 +133,13 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: - 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. - Preferisci 'Assert.ThrowsException' o 'Assert.ThrowsExceptionAsync' a '[ExpectedException]', perché garantisce che solo la chiamata prevista lanci l'eccezione prevista. Le API di asserzione forniscono anche una maggiore flessibilità e consentono l’asserzione delle proprietà aggiuntive dell'eccezione. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Preferisci 'Assert.ThrowsException' o 'Assert.ThrowsExceptionAsync' a '[ExpectedException]', perché garantisce che solo la chiamata prevista lanci l'eccezione prevista. Le API di asserzione forniscono anche una maggiore flessibilità e consentono l’asserzione delle proprietà aggiuntive dell'eccezione. - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - Preferisci 'Assert.ThrowsException/ThrowsExceptionAsync' a '[ExpectedException]'. + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Preferisci 'Assert.ThrowsException/ThrowsExceptionAsync' a '[ExpectedException]'. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 11352366ed..f6de1f26e3 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -133,13 +133,13 @@ The type declaring these methods should also respect the following rules: - 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. - '[ExpectedException]' よりも 'Assert.ThrowsException' または 'Assert.ThrowsExceptionAsync' を優先します。これは、予期された呼び出しのみが予期された例外をスローするようにするためです。アサート API も柔軟性が高く、例外の追加プロパティをアサートできます。 + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + '[ExpectedException]' よりも 'Assert.ThrowsException' または 'Assert.ThrowsExceptionAsync' を優先します。これは、予期された呼び出しのみが予期された例外をスローするようにするためです。アサート API も柔軟性が高く、例外の追加プロパティをアサートできます。 - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - '[ExpectedException]' よりも 'Assert.ThrowsException/ThrowsExceptionAsync' を優先します + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + '[ExpectedException]' よりも 'Assert.ThrowsException/ThrowsExceptionAsync' を優先します diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index befa4352ab..1af5d8b3b5 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -133,13 +133,13 @@ The type declaring these methods should also respect the following rules: - 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. - 예상되는 호출만 예상되는 예외를 throw하도록 보장하는 '[ExpectedException]'보다 'Assert.ThrowsException' 또는 'Assert.ThrowsExceptionAsync'를 사용하는 것이 좋습니다. 또한 Assert API는 더 많은 유연성을 제공하고 예외의 추가 속성을 어설션할 수 있도록 합니다. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + 예상되는 호출만 예상되는 예외를 throw하도록 보장하는 '[ExpectedException]'보다 'Assert.ThrowsException' 또는 'Assert.ThrowsExceptionAsync'를 사용하는 것이 좋습니다. 또한 Assert API는 더 많은 유연성을 제공하고 예외의 추가 속성을 어설션할 수 있도록 합니다. - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - '[ExpectedException]'보다 'Assert.ThrowsException/ThrowsExceptionAsync' 권장 + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + '[ExpectedException]'보다 'Assert.ThrowsException/ThrowsExceptionAsync' 권장 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index c35df35cae..67a889c8b8 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -133,13 +133,13 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu - 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. - Preferuj element „Assert.ThrowsException” lub „Assert.ThrowsExceptionAsync” niż „[ExpectedException]”, ponieważ gwarantuje, że tylko oczekiwane wywołanie zgłosi oczekiwany wyjątek. Interfejsy API potwierdzenia zapewniają również większą elastyczność i pozwalają na potwierdzenie dodatkowych właściwości wyjątku. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Preferuj element „Assert.ThrowsException” lub „Assert.ThrowsExceptionAsync” niż „[ExpectedException]”, ponieważ gwarantuje, że tylko oczekiwane wywołanie zgłosi oczekiwany wyjątek. Interfejsy API potwierdzenia zapewniają również większą elastyczność i pozwalają na potwierdzenie dodatkowych właściwości wyjątku. - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - Preferuj element „Assert.ThrowsException/ThrowsExceptionAsync” od „[ExpectedException]” + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Preferuj element „Assert.ThrowsException/ThrowsExceptionAsync” od „[ExpectedException]” diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index bcb20d8f7d..6d43aa22a0 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -133,13 +133,13 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: - 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. - Prefira 'Assert.ThrowsException' ou 'Assert.ThrowsExceptionAsync' '[ExpectedException]', pois isso garante que somente a chamada esperada lance a exceção esperada. As APIs assert também fornecem mais flexibilidade e permitem declarar propriedades extras da exceção. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Prefira 'Assert.ThrowsException' ou 'Assert.ThrowsExceptionAsync' '[ExpectedException]', pois isso garante que somente a chamada esperada lance a exceção esperada. As APIs assert também fornecem mais flexibilidade e permitem declarar propriedades extras da exceção. - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - Preferir 'Assert.ThrowsException/ThrowsExceptionAsync' em vez de '[ExpectedException]' + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Preferir 'Assert.ThrowsException/ThrowsExceptionAsync' em vez de '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index c98778ad01..6492061d04 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -136,13 +136,13 @@ The type declaring these methods should also respect the following rules: - 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. - Предпочитайте "Assert.ThrowsException" или "Assert.ThrowsExceptionAsync" вместо "[ExpectedException]", так как это гарантирует, что только ожидаемый вызов приводит к ожидаемому исключению. API-интерфейсы утверждения также обеспечивают дополнительную гибкость и позволяют утверждать дополнительные свойства исключения. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Предпочитайте "Assert.ThrowsException" или "Assert.ThrowsExceptionAsync" вместо "[ExpectedException]", так как это гарантирует, что только ожидаемый вызов приводит к ожидаемому исключению. API-интерфейсы утверждения также обеспечивают дополнительную гибкость и позволяют утверждать дополнительные свойства исключения. - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - Предпочитать "Assert.ThrowsException/ThrowsExceptionAsync" вместо "[ExpectedException]" + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Предпочитать "Assert.ThrowsException/ThrowsExceptionAsync" вместо "[ExpectedException]" diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index d3393681b2..d4f8d5659d 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -133,13 +133,13 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: - 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. - Yalnızca beklenen çağrının beklenen özel durumu oluşturmasını sağladığı için '[ExpectedException]' yerine 'Assert.ThrowsException' veya 'Assert.ThrowsExceptionAsync' tercih edin. Onaylama API'leri de daha fazla esneklik sağlar ve özel durumun ek özelliklerini onaylamanıza izin verir. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Yalnızca beklenen çağrının beklenen özel durumu oluşturmasını sağladığı için '[ExpectedException]' yerine 'Assert.ThrowsException' veya 'Assert.ThrowsExceptionAsync' tercih edin. Onaylama API'leri de daha fazla esneklik sağlar ve özel durumun ek özelliklerini onaylamanıza izin verir. - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - '[ExpectedException]' yerine 'Assert.ThrowsException/ThrowsExceptionAsync' tercih edin + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + '[ExpectedException]' yerine 'Assert.ThrowsException/ThrowsExceptionAsync' tercih edin diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index a875949ec2..d810042000 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -133,13 +133,13 @@ The type declaring these methods should also respect the following rules: - 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. - 首选 "Assert.ThrowsException" 或 "Assert.ThrowsExceptionAsync" 而不是 "[ExpectedException]",因为它确保只有预期调用才会引发预期异常。断言 API 还提供更多的灵活性,并允许你断言异常的额外属性。 + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + 首选 "Assert.ThrowsException" 或 "Assert.ThrowsExceptionAsync" 而不是 "[ExpectedException]",因为它确保只有预期调用才会引发预期异常。断言 API 还提供更多的灵活性,并允许你断言异常的额外属性。 - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - 首选 "Assert.ThrowsException/ThrowsExceptionAsync" 而不是 "[ExpectedException]" + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + 首选 "Assert.ThrowsException/ThrowsExceptionAsync" 而不是 "[ExpectedException]" diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 3ec95cc99c..d7e0c237e3 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -133,13 +133,13 @@ The type declaring these methods should also respect the following rules: - 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. - 偏好 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' 而非 '[ExpectedException]',因為它可確保只有預期的呼叫會擲出預期的例外狀況。判斷提示 API 也提供更多彈性,並允許您斷言例外狀況的額外屬性。 + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + 偏好 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' 而非 '[ExpectedException]',因為它可確保只有預期的呼叫會擲出預期的例外狀況。判斷提示 API 也提供更多彈性,並允許您斷言例外狀況的額外屬性。 - Prefer 'Assert.ThrowsException/ThrowsExceptionAsync' over '[ExpectedException]' - 偏好 'Assert.ThrowsException/ThrowsExceptionAsync' 而非 '[ExpectedException]' + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + 偏好 'Assert.ThrowsException/ThrowsExceptionAsync' 而非 '[ExpectedException]' From a908cc8c98f517957a02e931c5f393ed708a8f14 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Mon, 6 Jan 2025 07:18:04 -0800 Subject: [PATCH 229/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2613803 --- src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index 992792f112..c60c29b4e4 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -134,12 +134,12 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Preferujte Assert.ThrowsException nebo Assert.ThrowsExceptionAsync před [ExpectedException], protože zajišťuje, že očekávanou výjimku vyvolá pouze očekávané volání. Rozhraní API assert také poskytují větší flexibilitu a umožňují vyhodnocovat další vlastnosti výjimky. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Preferovat Assert.ThrowsException/ThrowsExceptionAsync před [ExpectedException] + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index e0e38db59c..9cc523aba8 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -134,12 +134,12 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - „Assert.ThrowsException“ oder „Assert.ThrowsExceptionAsync“ gegenüber „[ExpectedException]“ bevorzugen, da dadurch sichergestellt wird, dass nur der erwartete Aufruf die erwartete Ausnahme auslöst. Die Assert-APIs bieten außerdem mehr Flexibilität und ermöglichen es Ihnen, zusätzliche Eigenschaften der Ausführung zu bestätigen. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - „Assert.ThrowsException/ThrowsExceptionAsync“ gegenüber „[ExpectedException]“ bevorzugen + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 569bcdf6f4..996d9692f5 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -134,12 +134,12 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Preferir "Assert.ThrowsException" o "Assert.ThrowsExceptionAsync" en lugar de '[ExpectedException]' ya que garantiza que solo la llamada esperada inicia la excepción esperada. Las API de aserción también proporcionan más flexibilidad y le permiten declarar propiedades adicionales de la ejecución. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Preferir "Assert.ThrowsException/ThrowsExceptionAsync" en lugar de "[ExpectedException]" + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 12c6845a8c..01226f80cd 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -134,12 +134,12 @@ Le type doit être une classe Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Préférez « Assert.ThrowsException » ou « Assert.ThrowsExceptionAsync » à « [ExpectedException] », car cela assure que seul l’appel attendu lève l’exception attendue. Les API d’assertion offrent également plus de flexibilité et vous permettent de déclarer des propriétés supplémentaires de l’exception. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Préférer « Assert.ThrowsException/ThrowsExceptionAsync » à « [ExpectedException] » + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index 1d19a42b14..12d9d9f98b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -134,12 +134,12 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Preferisci 'Assert.ThrowsException' o 'Assert.ThrowsExceptionAsync' a '[ExpectedException]', perché garantisce che solo la chiamata prevista lanci l'eccezione prevista. Le API di asserzione forniscono anche una maggiore flessibilità e consentono l’asserzione delle proprietà aggiuntive dell'eccezione. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Preferisci 'Assert.ThrowsException/ThrowsExceptionAsync' a '[ExpectedException]'. + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index f6de1f26e3..ffc18100c0 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -134,12 +134,12 @@ The type declaring these methods should also respect the following rules: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - '[ExpectedException]' よりも 'Assert.ThrowsException' または 'Assert.ThrowsExceptionAsync' を優先します。これは、予期された呼び出しのみが予期された例外をスローするようにするためです。アサート API も柔軟性が高く、例外の追加プロパティをアサートできます。 + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - '[ExpectedException]' よりも 'Assert.ThrowsException/ThrowsExceptionAsync' を優先します + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 1af5d8b3b5..531a88169e 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -134,12 +134,12 @@ The type declaring these methods should also respect the following rules: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - 예상되는 호출만 예상되는 예외를 throw하도록 보장하는 '[ExpectedException]'보다 'Assert.ThrowsException' 또는 'Assert.ThrowsExceptionAsync'를 사용하는 것이 좋습니다. 또한 Assert API는 더 많은 유연성을 제공하고 예외의 추가 속성을 어설션할 수 있도록 합니다. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - '[ExpectedException]'보다 'Assert.ThrowsException/ThrowsExceptionAsync' 권장 + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 67a889c8b8..6ab6c394a6 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -134,12 +134,12 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Preferuj element „Assert.ThrowsException” lub „Assert.ThrowsExceptionAsync” niż „[ExpectedException]”, ponieważ gwarantuje, że tylko oczekiwane wywołanie zgłosi oczekiwany wyjątek. Interfejsy API potwierdzenia zapewniają również większą elastyczność i pozwalają na potwierdzenie dodatkowych właściwości wyjątku. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Preferuj element „Assert.ThrowsException/ThrowsExceptionAsync” od „[ExpectedException]” + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 6d43aa22a0..b925314554 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -134,12 +134,12 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefira 'Assert.ThrowsException' ou 'Assert.ThrowsExceptionAsync' '[ExpectedException]', pois isso garante que somente a chamada esperada lance a exceção esperada. As APIs assert também fornecem mais flexibilidade e permitem declarar propriedades extras da exceção. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Preferir 'Assert.ThrowsException/ThrowsExceptionAsync' em vez de '[ExpectedException]' + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index 6492061d04..3f928ddb39 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -137,12 +137,12 @@ The type declaring these methods should also respect the following rules: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Предпочитайте "Assert.ThrowsException" или "Assert.ThrowsExceptionAsync" вместо "[ExpectedException]", так как это гарантирует, что только ожидаемый вызов приводит к ожидаемому исключению. API-интерфейсы утверждения также обеспечивают дополнительную гибкость и позволяют утверждать дополнительные свойства исключения. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Предпочитать "Assert.ThrowsException/ThrowsExceptionAsync" вместо "[ExpectedException]" + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index d4f8d5659d..7356ec4368 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -134,12 +134,12 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Yalnızca beklenen çağrının beklenen özel durumu oluşturmasını sağladığı için '[ExpectedException]' yerine 'Assert.ThrowsException' veya 'Assert.ThrowsExceptionAsync' tercih edin. Onaylama API'leri de daha fazla esneklik sağlar ve özel durumun ek özelliklerini onaylamanıza izin verir. + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - '[ExpectedException]' yerine 'Assert.ThrowsException/ThrowsExceptionAsync' tercih edin + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index d810042000..973ce34145 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -134,12 +134,12 @@ The type declaring these methods should also respect the following rules: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - 首选 "Assert.ThrowsException" 或 "Assert.ThrowsExceptionAsync" 而不是 "[ExpectedException]",因为它确保只有预期调用才会引发预期异常。断言 API 还提供更多的灵活性,并允许你断言异常的额外属性。 + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - 首选 "Assert.ThrowsException/ThrowsExceptionAsync" 而不是 "[ExpectedException]" + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index d7e0c237e3..0a544e82bb 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -134,12 +134,12 @@ The type declaring these methods should also respect the following rules: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - 偏好 'Assert.ThrowsException' or 'Assert.ThrowsExceptionAsync' 而非 '[ExpectedException]',因為它可確保只有預期的呼叫會擲出預期的例外狀況。判斷提示 API 也提供更多彈性,並允許您斷言例外狀況的額外屬性。 + Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - 偏好 'Assert.ThrowsException/ThrowsExceptionAsync' 而非 '[ExpectedException]' + Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' From 4abf7f5695c5b670890307c299f491b971c6e26a Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 19:07:38 +0100 Subject: [PATCH 230/273] [main] Update dependencies from devdiv/DevDiv/vs-code-coverage, microsoft/testanywhere (#4531) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 4115df9640..ca23d5f225 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,13 +13,13 @@ https://github.com/dotnet/arcade 45d845e04c05fbe5da9838c454bbc3af1df6be81 - + https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage - d4a113f856a31bcdcbf6e08da8928961c98bb497 + 3889f929bc86d4f819c62bfa687b01660c9e195d - + https://github.com/microsoft/testanywhere - 631611080534165fca1733e7e31e7aeee417cdcc + 5799f8f7b95d0915aef24076a473213d7d2024fe diff --git a/eng/Versions.props b/eng/Versions.props index 3dd1f2ee94..291fcfb71d 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,8 +8,8 @@ 10.0.0-beta.24604.4 - 17.14.0-preview.24630.1 + 17.14.0-preview.25056.1 - 1.0.0-alpha.25055.2 + 1.0.0-alpha.25055.3 From f7ddde6db81476dc031fb5c327abb2eef7f38969 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Mon, 6 Jan 2025 20:12:59 +0100 Subject: [PATCH 231/273] Small ClassInitialize refactoring (#4503) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../Execution/TestClassInfo.cs | 61 ++++++++++++++++--- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index 32543a26c9..1d30aa93ef 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. +// 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.VisualStudio.TestPlatform.MSTest.TestAdapter.Extensions; @@ -31,6 +31,8 @@ public class TestClassInfo private readonly Lock _testClassExecuteSyncObject = new(); + private UnitTestResult? _classInitializeResult; + /// /// Initializes a new instance of the class. /// @@ -344,22 +346,62 @@ public void RunClassInitialize(TestContext testContext) throw testFailedException; } + private UnitTestResult? TryGetClonedCachedClassInitializeResult() + { + // Historically, we were not caching class initialize result, and were always going through the logic in GetResultOrRunClassInitialize. + // When caching is introduced, we found out that using the cached instance can change the behavior in some cases. For example, + // if you have Console.WriteLine in class initialize, those will be present on the UnitTestResult. + // Before caching was introduced, these logs will be only in the first class initialize result (attached to the first test run in class) + // By re-using the cached instance, it's now part of all tests. + // To preserve the original behavior, we clone the cached instance so we keep only the information we are sure should be reused. + if (_classInitializeResult is null) + { + return null; + } + + if (_classInitializeResult.ErrorStackTrace is not null && _classInitializeResult.ErrorMessage is not null) + { + return new( + new TestFailedException( + _classInitializeResult.Outcome, + _classInitializeResult.ErrorMessage, + new StackTraceInformation(_classInitializeResult.ErrorStackTrace, _classInitializeResult.ErrorFilePath, _classInitializeResult.ErrorLineNumber, _classInitializeResult.ErrorColumnNumber))); + } + + // We are expecting this to be hit for the case of "Passed". + // It's unlikely to be hit otherwise (GetResultOrRunClassInitialize appears to only create either Passed results or a result from exception), but + // we can still create UnitTestResult from outcome and error message (which is expected to be null for Passed). + return new(_classInitializeResult.Outcome, _classInitializeResult.ErrorMessage); + } + internal UnitTestResult GetResultOrRunClassInitialize(ITestContext testContext, string initializationLogs, string initializationErrorLogs, string initializationTrace, string initializationTestContextMessages) { + UnitTestResult? clonedInitializeResult = TryGetClonedCachedClassInitializeResult(); + + // Optimization: If we already ran before and know the result, return it. + if (clonedInitializeResult is not null) + { + DebugEx.Assert(IsClassInitializeExecuted, "Class initialize result should be available if and only if class initialize was executed"); + return clonedInitializeResult; + } + + DebugEx.Assert(!IsClassInitializeExecuted, "If class initialize was executed, we should have been in the previous if were we have a result available."); + + // For optimization purposes, return right away if there is nothing to execute. + // For STA, this avoids starting a thread when we know it will do nothing. + // But we still return early even not STA. + if (ClassInitializeMethod is null && BaseClassInitMethods.Count == 0) + { + IsClassInitializeExecuted = true; + return _classInitializeResult = new(ObjectModelUnitTestOutcome.Passed, null); + } + bool isSTATestClass = AttributeComparer.IsDerived(ClassAttribute); bool isWindowsOS = RuntimeInformation.IsOSPlatform(OSPlatform.Windows); if (isSTATestClass && isWindowsOS && Thread.CurrentThread.GetApartmentState() != ApartmentState.STA) { - // For optimization purposes, we duplicate some of the logic of RunClassInitialize here so we don't need to start - // a thread for nothing. - if ((ClassInitializeMethod is null && BaseClassInitMethods.Count == 0) - || IsClassInitializeExecuted) - { - return DoRun(); - } - UnitTestResult result = new(ObjectModelUnitTestOutcome.Error, "MSTest STATestClass ClassInitialize didn't complete"); Thread entryPointThread = new(() => result = DoRun()) { @@ -429,6 +471,7 @@ UnitTestResult DoRun() result.TestContextMessages = initializationTestContextMessages; } + _classInitializeResult = result; return result; } } From 8c80b995ff7eb8180fe50a6044206975c05185fd Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 07:22:03 +0100 Subject: [PATCH 232/273] [main] Update dependencies from microsoft/testanywhere (#4533) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index ca23d5f225..547087c481 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -17,9 +17,9 @@ https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage 3889f929bc86d4f819c62bfa687b01660c9e195d - + https://github.com/microsoft/testanywhere - 5799f8f7b95d0915aef24076a473213d7d2024fe + 9321d81962123d9c9d624d35a7dff1d1cea09da1 diff --git a/eng/Versions.props b/eng/Versions.props index 291fcfb71d..84e71f60e5 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,6 +10,6 @@ 10.0.0-beta.24604.4 17.14.0-preview.25056.1 - 1.0.0-alpha.25055.3 + 1.0.0-alpha.25056.3 From c5843c5031903f158a2aff51fedd53541317ba97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 7 Jan 2025 10:05:40 +0100 Subject: [PATCH 233/273] [main] Bump MSTest from 3.8.0-preview.25055.1 to 3.8.0-preview.25056.11 (#4535) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 1e0580fb96..af2de7feb8 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -24,7 +24,7 @@ 1.1.3-beta1.24423.1 - 3.8.0-preview.25055.1 + 3.8.0-preview.25056.11 From 36eaf0579aa6d736675064654c3c70a2a9cc0e6d Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 7 Jan 2025 12:18:49 +0100 Subject: [PATCH 234/273] Add ability to ignore specific test cases (#4457) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- src/Adapter/MSTest.TestAdapter/Constants.cs | 2 + .../Discovery/AssemblyEnumerator.cs | 4 +- .../Discovery/TypeEnumerator.cs | 1 - .../Execution/TestClassInfo.cs | 6 +- .../Execution/TestMethodRunner.cs | 15 ++ .../Execution/UnitTestRunner.cs | 10 +- .../Extensions/TestCaseExtensions.cs | 1 + .../Extensions/TestResultExtensions.cs | 6 + .../Extensions/UnitTestOutcomeExtensions.cs | 2 + .../ObjectModel/TestMethod.cs | 2 + .../ObjectModel/UnitTestElement.cs | 6 +- .../Attributes/DataSource/DataRowAttribute.cs | 7 +- .../DataSource/DynamicDataAttribute.cs | 7 +- .../TestMethod/TestClassAttribute.cs | 5 + .../TestMethod/TestMethodAttribute.cs | 5 + .../Attributes/TestMethod/TestResult.cs | 2 + .../ITestDataSourceIgnoreCapability.cs | 15 ++ .../PublicAPI/PublicAPI.Unshipped.txt | 12 + .../TestFramework/UnitTestOutcome.cs | 5 + .../IgnoreTests.cs | 212 +++++++++++++++++- .../Discovery/TypeEnumeratorTests.cs | 12 - .../Execution/TestExecutionManagerTests.cs | 9 +- 22 files changed, 313 insertions(+), 33 deletions(-) create mode 100644 src/TestFramework/TestFramework/Interfaces/ITestDataSourceIgnoreCapability.cs diff --git a/src/Adapter/MSTest.TestAdapter/Constants.cs b/src/Adapter/MSTest.TestAdapter/Constants.cs index f110859dc8..569d49159b 100644 --- a/src/Adapter/MSTest.TestAdapter/Constants.cs +++ b/src/Adapter/MSTest.TestAdapter/Constants.cs @@ -123,6 +123,8 @@ internal static class Constants internal static readonly TestProperty TestDynamicDataProperty = TestProperty.Register("MSTest.DynamicData", "DynamicData", typeof(string[]), TestPropertyAttributes.Hidden, typeof(TestCase)); internal static readonly TestProperty TestIdGenerationStrategyProperty = TestProperty.Register("MSTest.TestIdGenerationStrategy", "TestIdGenerationStrategy", typeof(int), TestPropertyAttributes.Hidden, typeof(TestCase)); + + internal static readonly TestProperty TestDataSourceIgnoreMessageProperty = TestProperty.Register("MSTest.TestDataSourceIgnoreMessageProperty", "TestDataSourceIgnoreMessageProperty", typeof(string), TestPropertyAttributes.Hidden, typeof(TestCase)); #endregion #region Private Constants diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs index 884fe813fb..74654b6bca 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/AssemblyEnumerator.cs @@ -342,7 +342,6 @@ static UnitTestElement GetFixtureTest(string classFullName, string assemblyLocat return new UnitTestElement(method) { DisplayName = $"[{fixtureType}] {methodName}", - Ignored = true, Traits = [new Trait(Constants.FixturesTestTrait, fixtureType)], }; } @@ -424,6 +423,7 @@ private static bool TryUnfoldITestDataSource(ITestDataSource dataSource, TestDat // This code is to discover tests. To run the tests code is in TestMethodRunner.ExecuteDataSourceBasedTests. // Any change made here should be reflected in TestMethodRunner.ExecuteDataSourceBasedTests as well. data = dataSource.GetData(methodInfo); + string? testDataSourceIgnoreMessage = (dataSource as ITestDataSourceIgnoreCapability)?.IgnoreMessage; if (!data.Any()) { @@ -435,6 +435,7 @@ private static bool TryUnfoldITestDataSource(ITestDataSource dataSource, TestDat UnitTestElement discoveredTest = test.Clone(); // Make the test not data driven, because it had no data. discoveredTest.TestMethod.DataType = DynamicDataType.None; + discoveredTest.TestMethod.TestDataSourceIgnoreMessage = testDataSourceIgnoreMessage; discoveredTest.DisplayName = dataSource.GetDisplayName(methodInfo, null) ?? discoveredTest.DisplayName; tests.Add(discoveredTest); @@ -468,6 +469,7 @@ private static bool TryUnfoldITestDataSource(ITestDataSource dataSource, TestDat try { discoveredTest.TestMethod.SerializedData = DataSerializationHelper.Serialize(d); + discoveredTest.TestMethod.TestDataSourceIgnoreMessage = testDataSourceIgnoreMessage; discoveredTest.TestMethod.DataType = DynamicDataType.ITestDataSource; } catch (SerializationException ex) diff --git a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs index 07d9327abd..cbb50767f7 100644 --- a/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs +++ b/src/Adapter/MSTest.TestAdapter/Discovery/TypeEnumerator.cs @@ -155,7 +155,6 @@ internal UnitTestElement GetTestFromMethod(MethodInfo method, bool isDeclaredInT TestCategory = _reflectHelper.GetTestCategories(method, _type), DoNotParallelize = _reflectHelper.IsDoNotParallelizeSet(method, _type), Priority = _reflectHelper.GetPriority(method), - Ignored = _reflectHelper.IsNonDerivedAttributeDefined(method, inherit: false), DeploymentItems = PlatformServiceProvider.Instance.TestDeployment.GetDeploymentItems(method, _type, warnings), }; diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs index 1d30aa93ef..b3c6510e62 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestClassInfo.cs @@ -614,7 +614,8 @@ internal void ExecuteClassCleanup(TestContext testContext) { if (classCleanupMethod is not null) { - if (!ReflectHelper.Instance.IsNonDerivedAttributeDefined(classCleanupMethod.DeclaringType!, false)) + if (ClassAttribute.IgnoreMessage is null && + !ReflectHelper.Instance.IsNonDerivedAttributeDefined(classCleanupMethod.DeclaringType!, false)) { ClassCleanupException = InvokeCleanupMethod(classCleanupMethod, remainingCleanupCount: BaseClassCleanupMethods.Count, testContext); } @@ -625,7 +626,8 @@ internal void ExecuteClassCleanup(TestContext testContext) for (int i = 0; i < BaseClassCleanupMethods.Count; i++) { classCleanupMethod = BaseClassCleanupMethods[i]; - if (!ReflectHelper.Instance.IsNonDerivedAttributeDefined(classCleanupMethod.DeclaringType!, false)) + if (ClassAttribute.IgnoreMessage is null && + !ReflectHelper.Instance.IsNonDerivedAttributeDefined(classCleanupMethod.DeclaringType!, false)) { ClassCleanupException = InvokeCleanupMethod(classCleanupMethod, remainingCleanupCount: BaseClassCleanupMethods.Count - 1 - i, testContext); if (ClassCleanupException is not null) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs index 7ce5f213d1..6a401c345a 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestMethodRunner.cs @@ -170,6 +170,11 @@ internal UnitTestResult[] RunTestMethod() var parentStopwatch = Stopwatch.StartNew(); if (_test.DataType == DynamicDataType.ITestDataSource) { + if (_test.TestDataSourceIgnoreMessage is not null) + { + return [new(UnitTestOutcome.Ignored, _test.TestDataSourceIgnoreMessage)]; + } + object?[]? data = DataSerializationHelper.Deserialize(_test.SerializedData); TestResult[] testResults = ExecuteTestWithDataSource(null, data); results.AddRange(testResults); @@ -263,6 +268,16 @@ private bool TryExecuteFoldedDataDrivenTests(List results) foreach (UTF.ITestDataSource testDataSource in testDataSources) { + if (testDataSource is ITestDataSourceIgnoreCapability { IgnoreMessage: { } ignoreMessage }) + { + results.Add(new() + { + Outcome = UTF.UnitTestOutcome.Ignored, + IgnoreReason = ignoreMessage, + }); + continue; + } + IEnumerable? dataSource; // This code is to execute tests. To discover the tests code is in AssemblyEnumerator.ProcessTestDataSourceTests. diff --git a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs index acfd86fdb3..611e238ec5 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/UnitTestRunner.cs @@ -347,9 +347,17 @@ private bool IsTestMethodRunnable( } } + // TODO: Executor should never be null. Is it incorrectly annotated? + string? ignoreMessage = testMethodInfo.Parent.ClassAttribute.IgnoreMessage ?? testMethodInfo.TestMethodOptions.Executor?.IgnoreMessage; + if (ignoreMessage is not null) + { + notRunnableResult = [new UnitTestResult(UnitTestOutcome.Ignored, ignoreMessage)]; + return false; + } + IgnoreAttribute? ignoreAttributeOnClass = _reflectHelper.GetFirstNonDerivedAttributeOrDefault(testMethodInfo.Parent.ClassType, inherit: false); - string? ignoreMessage = ignoreAttributeOnClass?.IgnoreMessage; + ignoreMessage = ignoreAttributeOnClass?.IgnoreMessage; IgnoreAttribute? ignoreAttributeOnMethod = _reflectHelper.GetFirstNonDerivedAttributeOrDefault(testMethodInfo.TestMethod, inherit: false); diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/TestCaseExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/TestCaseExtensions.cs index c0ed82d9cb..fafe4e6346 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/TestCaseExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/TestCaseExtensions.cs @@ -86,6 +86,7 @@ internal static UnitTestElement ToUnitTestElement(this TestCase testCase, string testMethod.DataType = dataType; testMethod.SerializedData = data; + testMethod.TestDataSourceIgnoreMessage = testCase.GetPropertyValue(Constants.TestDataSourceIgnoreMessageProperty) as string; } if (testCase.GetPropertyValue(Constants.DeclaringClassNameProperty) is string declaringClassName && declaringClassName != testClassName) diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs index ecdd6901b5..d7f47e8b4c 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/TestResultExtensions.cs @@ -40,6 +40,12 @@ testFailureException is TestFailedException testException ? testException.StackTraceInformation : testFailureException.TryGetStackTraceInformation())) : new UnitTestResult { Outcome = outcome }; + + if (testResult.IgnoreReason is not null) + { + unitTestResult.ErrorMessage = testResult.IgnoreReason; + } + unitTestResult.StandardOut = testResult.LogOutput; unitTestResult.StandardError = testResult.LogError; unitTestResult.DebugTrace = testResult.DebugTrace; diff --git a/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs b/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs index 691cb5d03f..d53bf0e787 100644 --- a/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/Extensions/UnitTestOutcomeExtensions.cs @@ -31,6 +31,7 @@ public static UnitTestOutcome ToUnitTestOutcome(this UTF.UnitTestOutcome framewo UTF.UnitTestOutcome.Timeout => UnitTestOutcome.Timeout, UTF.UnitTestOutcome.NotRunnable => UnitTestOutcome.NotRunnable, UTF.UnitTestOutcome.NotFound => UnitTestOutcome.NotFound, + UTF.UnitTestOutcome.Ignored => UnitTestOutcome.Ignored, _ => UnitTestOutcome.Error, }; @@ -44,6 +45,7 @@ internal static UTF.UnitTestOutcome ToAdapterOutcome(this UnitTestOutcome outcom UnitTestOutcome.Timeout => UTF.UnitTestOutcome.Timeout, UnitTestOutcome.NotRunnable => UTF.UnitTestOutcome.NotRunnable, UnitTestOutcome.NotFound => UTF.UnitTestOutcome.NotFound, + UnitTestOutcome.Ignored => UTF.UnitTestOutcome.Ignored, _ => UTF.UnitTestOutcome.Error, }; diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs index 61d75236bf..5b94d2bfa5 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/TestMethod.cs @@ -143,6 +143,8 @@ public string? DeclaringClassFullName /// internal string?[]? SerializedData { get; set; } + internal string? TestDataSourceIgnoreMessage { get; set; } + /// /// Gets or sets the test group set during discovery. /// diff --git a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs index a585c6afde..1701b39c82 100644 --- a/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs +++ b/src/Adapter/MSTest.TestAdapter/ObjectModel/UnitTestElement.cs @@ -33,11 +33,6 @@ public UnitTestElement(TestMethod testMethod) /// public TestMethod TestMethod { get; private set; } - /// - /// Gets or sets a value indicating whether the unit test should be ignored at run-time. - /// - public bool Ignored { get; set; } - /// /// Gets or sets a value indicating whether it is a async test. /// @@ -211,6 +206,7 @@ internal TestCase ToTestCase() testCase.SetPropertyValue(Constants.TestDynamicDataTypeProperty, (int)TestMethod.DataType); testCase.SetPropertyValue(Constants.TestDynamicDataProperty, data); + testCase.SetPropertyValue(Constants.TestDataSourceIgnoreMessageProperty, TestMethod.TestDataSourceIgnoreMessage); } SetTestCaseId(testCase, testFullName); diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs index 4fdb946813..040c794cf4 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DataRowAttribute.cs @@ -9,7 +9,7 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; /// Attribute to define in-line data for a test method. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] -public class DataRowAttribute : Attribute, ITestDataSource, ITestDataSourceUnfoldingCapability +public class DataRowAttribute : Attribute, ITestDataSource, ITestDataSourceUnfoldingCapability, ITestDataSourceIgnoreCapability { /// /// Initializes a new instance of the class. @@ -53,6 +53,11 @@ public DataRowAttribute(string?[]? stringArrayData) /// public string? DisplayName { get; set; } + /// + /// Gets or sets a reason to ignore the specific test case. Setting the property to non-null value will ignore the test case. + /// + public string? IgnoreMessage { get; set; } + /// public TestDataSourceUnfoldingStrategy UnfoldingStrategy { get; set; } = TestDataSourceUnfoldingStrategy.Auto; diff --git a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs index 48825c992c..370ab10af2 100644 --- a/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/DataSource/DynamicDataAttribute.cs @@ -32,7 +32,7 @@ public enum DynamicDataSourceType /// Attribute to define dynamic data for a test method. /// [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] -public sealed class DynamicDataAttribute : Attribute, ITestDataSource, ITestDataSourceEmptyDataSourceExceptionInfo, ITestDataSourceUnfoldingCapability +public sealed class DynamicDataAttribute : Attribute, ITestDataSource, ITestDataSourceEmptyDataSourceExceptionInfo, ITestDataSourceUnfoldingCapability, ITestDataSourceIgnoreCapability { private readonly string _dynamicDataSourceName; private readonly DynamicDataSourceType _dynamicDataSourceType; @@ -114,6 +114,11 @@ public DynamicDataAttribute(string dynamicDataSourceName, Type dynamicDataDeclar /// public TestDataSourceUnfoldingStrategy UnfoldingStrategy { get; set; } = TestDataSourceUnfoldingStrategy.Auto; + /// + /// Gets or sets a reason to ignore this dynamic data source. Setting the property to non-null value will ignore the dynamic data source. + /// + public string? IgnoreMessage { get; set; } + /// public IEnumerable GetData(MethodInfo methodInfo) => DynamicDataProvider.Instance.GetData(_dynamicDataDeclaringType, _dynamicDataSourceType, _dynamicDataSourceName, methodInfo); diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs index da57c79550..0da97a08d2 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TestClassAttribute.cs @@ -26,4 +26,9 @@ public class TestClassAttribute : Attribute public virtual TestMethodAttribute? GetTestMethodAttribute(TestMethodAttribute? testMethodAttribute) => // If TestMethod is not extended by derived class then return back the original TestMethodAttribute testMethodAttribute; + + /// + /// Gets or sets a reason to ignore the test class. Setting the property to non-null value will ignore the test class. + /// + public string? IgnoreMessage { get; set; } } diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs index 319fcec986..1d42b34d43 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs @@ -50,6 +50,11 @@ public TestMethodAttribute() /// public string? DisplayName { get; } + /// + /// Gets or sets a reason to ignore the test method. Setting the property to non-null value will ignore the test method. + /// + public string? IgnoreMessage { get; set; } + /// /// Executes a test method. /// diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TestResult.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TestResult.cs index 1b0b35fe7b..0ccf2e316c 100644 --- a/src/TestFramework/TestFramework/Attributes/TestMethod/TestResult.cs +++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TestResult.cs @@ -24,6 +24,8 @@ public class TestResult /// public UnitTestOutcome Outcome { get; set; } + internal string? IgnoreReason { get; set; } + /// /// Gets or sets the exception thrown when test is failed. /// diff --git a/src/TestFramework/TestFramework/Interfaces/ITestDataSourceIgnoreCapability.cs b/src/TestFramework/TestFramework/Interfaces/ITestDataSourceIgnoreCapability.cs new file mode 100644 index 0000000000..0a22b7dc5f --- /dev/null +++ b/src/TestFramework/TestFramework/Interfaces/ITestDataSourceIgnoreCapability.cs @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +namespace Microsoft.VisualStudio.TestTools.UnitTesting; + +/// +/// Specifies the capability of a test data source to be ignored and define the ignore reason. +/// +public interface ITestDataSourceIgnoreCapability +{ + /// + /// Gets or sets a reason to ignore the test data source. Setting the property to non-null value will ignore the test data source. + /// + string? IgnoreMessage { get; set; } +} diff --git a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt index 9572aa2c29..ff0c658919 100644 --- a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt @@ -188,13 +188,25 @@ Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpola Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AppendLiteral(string! value) -> void Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AssertThrowsExactlyInterpolatedStringHandler() -> void Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler.AssertThrowsExactlyInterpolatedStringHandler(int literalLength, int formattedCount, System.Action! action, out bool shouldAppend) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.IgnoreMessage.get -> string? +Microsoft.VisualStudio.TestTools.UnitTesting.DataRowAttribute.IgnoreMessage.set -> void Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType dynamicDataSourceType) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, System.Type! dynamicDataDeclaringType) -> void Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, System.Type! dynamicDataDeclaringType, Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType dynamicDataSourceType) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.IgnoreMessage.get -> string? +Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.IgnoreMessage.set -> void Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.AutoDetect = 2 -> Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType *REMOVED*Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType dynamicDataSourceType = Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Property) -> void *REMOVED*Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute.DynamicDataAttribute(string! dynamicDataSourceName, System.Type! dynamicDataDeclaringType, Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType dynamicDataSourceType = Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Property) -> void +Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSourceIgnoreCapability +Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSourceIgnoreCapability.IgnoreMessage.get -> string? +Microsoft.VisualStudio.TestTools.UnitTesting.ITestDataSourceIgnoreCapability.IgnoreMessage.set -> void +Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute.IgnoreMessage.get -> string? +Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute.IgnoreMessage.set -> void +Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.IgnoreMessage.get -> string? +Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute.IgnoreMessage.set -> void +Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome.Ignored = 10 -> Microsoft.VisualStudio.TestTools.UnitTesting.UnitTestOutcome static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(decimal expected, decimal actual, decimal delta, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(double expected, double actual, double delta, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AreEqual(float expected, float actual, float delta, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonGenericAreEqualInterpolatedStringHandler message) -> void diff --git a/src/TestFramework/TestFramework/UnitTestOutcome.cs b/src/TestFramework/TestFramework/UnitTestOutcome.cs index 0f6658de56..e5895913e5 100644 --- a/src/TestFramework/TestFramework/UnitTestOutcome.cs +++ b/src/TestFramework/TestFramework/UnitTestOutcome.cs @@ -59,4 +59,9 @@ public enum UnitTestOutcome : int /// The specific test cannot be found. /// NotFound, + + /// + /// Test is marked as ignored. + /// + Ignored, } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs index 74d6740d73..519f74159c 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs @@ -3,6 +3,7 @@ using Microsoft.Testing.Platform.Acceptance.IntegrationTests; using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; +using Microsoft.Testing.Platform.Helpers; namespace MSTest.Acceptance.IntegrationTests; @@ -16,8 +17,8 @@ public async Task ClassCleanup_Inheritance_WhenClassIsSkipped() TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings --filter ClassName!~TestClassWithAssemblyInitialize"); // Assert - testHostResult.AssertExitCodeIs(0); - testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 1); + testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertOutputContainsSummary(failed: 0, passed: 12, skipped: 9); testHostResult.AssertOutputContains("SubClass.Method"); } @@ -29,12 +30,122 @@ public async Task WhenAllTestsAreIgnored_AssemblyInitializeAndCleanupAreSkipped( TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings --filter TestClassWithAssemblyInitialize"); // Assert - testHostResult.AssertExitCodeIs(8); + testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); testHostResult.AssertOutputContainsSummary(failed: 0, passed: 0, skipped: 1); testHostResult.AssertOutputDoesNotContain("AssemblyInitialize"); testHostResult.AssertOutputDoesNotContain("AssemblyCleanup"); } + [TestMethod] + public async Task WhenTestClassIsIgnoredViaIgnoreMessageProperty() + { + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); + TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings --filter TestClassWithIgnoreMessage"); + + // Assert + testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); + testHostResult.AssertOutputContainsSummary(failed: 0, passed: 0, skipped: 1); + } + + [TestMethod] + public async Task WhenTestMethodIsIgnoredViaIgnoreMessageProperty() + { + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); + TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings --filter TestClassWithMethodUsingIgnoreMessage"); + + // Assert + testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertOutputContainsSummary(failed: 0, passed: 1, skipped: 1); + } + + [TestMethod] + public async Task WhenSpecificDataSourceIsIgnoredViaIgnoreMessageProperty() + { + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, TargetFrameworks.NetCurrent); + TestHostResult testHostResult = await testHost.ExecuteAsync("--settings my.runsettings --filter TestClassWithDataSourcesUsingIgnoreMessage"); + + // Assert + testHostResult.AssertExitCodeIs(ExitCodes.Success); + testHostResult.AssertOutputContains(""" + TestInitialize: TestMethod1 (0) + TestCleanup: TestMethod1 (0) + """); + + testHostResult.AssertOutputContains(""" + TestInitialize: TestMethod1 (2) + TestCleanup: TestMethod1 (2) + """); + + testHostResult.AssertOutputContains(""" + TestInitialize: TestMethod2 (0) + TestCleanup: TestMethod2 (0) + """); + + testHostResult.AssertOutputContains(""" + TestInitialize: TestMethod2 (1) + TestCleanup: TestMethod2 (1) + """); + + testHostResult.AssertOutputContains(""" + TestInitialize: TestMethod2 (2) + TestCleanup: TestMethod2 (2) + """); + + testHostResult.AssertOutputContains(""" + TestInitialize: TestMethod3 (0) + TestCleanup: TestMethod3 (0) + """); + + testHostResult.AssertOutputContains(""" + TestInitialize: TestMethod3 (2) + TestCleanup: TestMethod3 (2) + """); + + testHostResult.AssertOutputContains(""" + TestInitialize: TestMethod4 (0) + TestCleanup: TestMethod4 (0) + """); + + testHostResult.AssertOutputContains(""" + TestInitialize: TestMethod4 (1) + TestCleanup: TestMethod4 (1) + """); + + testHostResult.AssertOutputContains(""" + TestInitialize: TestMethod4 (2) + TestCleanup: TestMethod4 (2) + """); + + testHostResult.AssertOutputContains("skipped TestMethod1"); + testHostResult.AssertOutputContains("skipped TestMethod2"); + testHostResult.AssertOutputContains("skipped TestMethod3 (1)"); + testHostResult.AssertOutputContains("skipped TestMethod4 (3)"); + testHostResult.AssertOutputContains("skipped TestMethod4 (4)"); + testHostResult.AssertOutputContains("skipped TestMethod4 (5)"); + + testHostResult.AssertOutputDoesNotContain("TestInitialize: TestMethod1 (1)"); + testHostResult.AssertOutputDoesNotContain("TestCleanup: TestMethod1 (1)"); + + testHostResult.AssertOutputDoesNotContain("TestInitialize: TestMethod2 (3)"); + testHostResult.AssertOutputDoesNotContain("TestCleanup: TestMethod2 (3)"); + testHostResult.AssertOutputDoesNotContain("TestInitialize: TestMethod2 (4)"); + testHostResult.AssertOutputDoesNotContain("TestCleanup: TestMethod2 (4)"); + testHostResult.AssertOutputDoesNotContain("TestInitialize: TestMethod2 (5)"); + testHostResult.AssertOutputDoesNotContain("TestCleanup: TestMethod2 (5)"); + + testHostResult.AssertOutputDoesNotContain("TestInitialize: TestMethod3 (1)"); + testHostResult.AssertOutputDoesNotContain("TestCleanup: TestMethod3 (1)"); + + testHostResult.AssertOutputDoesNotContain("TestInitialize: TestMethod4 (3)"); + testHostResult.AssertOutputDoesNotContain("TestCleanup: TestMethod4 (3)"); + testHostResult.AssertOutputDoesNotContain("TestInitialize: TestMethod4 (4)"); + testHostResult.AssertOutputDoesNotContain("TestCleanup: TestMethod4 (4)"); + testHostResult.AssertOutputDoesNotContain("TestInitialize: TestMethod4 (5)"); + testHostResult.AssertOutputDoesNotContain("TestCleanup: TestMethod4 (5)"); + + testHostResult.AssertOutputContainsSummary(failed: 0, passed: 10, skipped: 6); + } + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) { public const string ProjectName = "TestIgnore"; @@ -81,6 +192,7 @@ public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture. #file UnitTest1.cs using System; +using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -146,6 +258,100 @@ public void TestMethod1() { } } + +[TestClass(IgnoreMessage = "This test class is ignored")] +public class TestClassWithIgnoreMessage +{ + [TestMethod] + public void TestMethod1() + { + } +} + +[TestClass] +public class TestClassWithMethodUsingIgnoreMessage +{ + [TestMethod(IgnoreMessage = "This test method is ignored")] + public void TestMethod1() + { + } + + [TestMethod] + public void TestMethod2() + { + } +} + +[TestClass] +public class TestClassWithDataSourcesUsingIgnoreMessage +{ + private readonly TestContext _testContext; + + public TestClassWithDataSourcesUsingIgnoreMessage(TestContext testContext) + => _testContext = testContext; + + [TestMethod] // 1 skipped, 2 pass + [DataRow(0, UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)] + [DataRow(1, UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold, IgnoreMessage = "This data row is ignored")] + [DataRow(2, UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)] + public void TestMethod1(int i) + { + } + + [TestMethod] // 1 skipped (folded), 3 pass + [DynamicData("Data1", UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold)] + [DynamicData("Data2", UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Fold, IgnoreMessage = "This source is ignored")] + public void TestMethod2(int i) + { + } + + [TestMethod] // 1 skipped, 2 pass + [DataRow(0, UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Unfold)] + [DataRow(1, UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Unfold, IgnoreMessage = "This data row is ignored")] + [DataRow(2, UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Unfold)] + public void TestMethod3(int i) + { + } + + [TestMethod] // 3 skipped (unfolded), 3 pass + [DynamicData("Data1", UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Unfold)] + [DynamicData("Data2", UnfoldingStrategy = TestDataSourceUnfoldingStrategy.Unfold, IgnoreMessage = "This source is ignored")] + public void TestMethod4(int i) + { + } + + [TestInitialize] + public void TestInit() + { + Console.WriteLine($"TestInitialize: {_testContext.TestDisplayName}"); + } + + [TestCleanup] + public void TestClean() + { + Console.WriteLine($"TestCleanup: {_testContext.TestDisplayName}"); + } + + public static IEnumerable Data1 + { + get + { + yield return new object[] { 0 }; + yield return new object[] { 1 }; + yield return new object[] { 2 }; + } + } + + public static IEnumerable Data2 + { + get + { + yield return new object[] { 3 }; + yield return new object[] { 4 }; + yield return new object[] { 5 }; + } + } +} """; } } diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs index 60f85dff0e..5921ef972e 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/TypeEnumeratorTests.cs @@ -291,18 +291,6 @@ public void GetTestFromMethodShouldInitializeAsyncTypeNameCorrectly() Verify(expectedAsyncTaskName == testElement.AsyncTypeName); } - public void GetTestFromMethodShouldSetIgnoredPropertyToFalseIfNotSetOnTestClassAndTestMethod() - { - SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); - TypeEnumerator typeEnumerator = GetTypeEnumeratorInstance(typeof(DummyTestClass), "DummyAssemblyName"); - MethodInfo methodInfo = typeof(DummyTestClass).GetMethod("MethodWithVoidReturnType"); - - MSTest.TestAdapter.ObjectModel.UnitTestElement testElement = typeEnumerator.GetTestFromMethod(methodInfo, true, _warnings); - - Verify(testElement is not null); - Verify(!testElement.Ignored); - } - public void GetTestFromMethodShouldSetTestCategory() { SetupTestClassAndTestMethods(isValidTestClass: true, isValidTestMethod: true, isMethodFromSameAssembly: true); diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestExecutionManagerTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestExecutionManagerTests.cs index bd6cf90af7..f00010e440 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestExecutionManagerTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestExecutionManagerTests.cs @@ -123,7 +123,7 @@ public void RunTestsForTestWithFilterShouldSendResultsForFilteredTests() public void RunTestsForIgnoredTestShouldSendResultsMarkingIgnoredTestsAsSkipped() { - TestCase testCase = GetTestCase(typeof(DummyTestClass), "IgnoredTest", ignore: true); + TestCase testCase = GetTestCase(typeof(DummyTestClass), "IgnoredTest"); TestCase[] tests = [testCase]; _testExecutionManager.RunTests(tests, _runContext, _frameworkHandle, _cancellationToken); @@ -814,14 +814,11 @@ private void RunTestsForTestShouldRunTestsInTheParentDomainsApartmentState() #region private methods - private static TestCase GetTestCase(Type typeOfClass, string testName, bool ignore = false) + private static TestCase GetTestCase(Type typeOfClass, string testName) { MethodInfo methodInfo = typeOfClass.GetMethod(testName); var testMethod = new TestMethod(methodInfo.Name, typeOfClass.FullName, Assembly.GetExecutingAssembly().Location, isAsync: false); - UnitTestElement element = new(testMethod) - { - Ignored = ignore, - }; + UnitTestElement element = new(testMethod); return element.ToTestCase(); } From 1db1afd470b3745f989e6c7e2531c54b6a1c9774 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 7 Jan 2025 14:02:01 +0100 Subject: [PATCH 235/273] Don't report diagnostic for DeploymentItem on abstract class (#4538) --- ...oymentItemWithTestMethodOrTestClassAnalyzer.cs | 9 +++++++++ ...tItemWithTestMethodOrTestClassAnalyzerTests.cs | 15 +++++++++++++++ 2 files changed, 24 insertions(+) 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 ecfd32451e..e0fa42c540 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseDeploymentItemWithTestMethodOrTestClassAnalyzerTests.cs @@ -88,6 +88,21 @@ public void MyTestMethod() await VerifyCS.VerifyAnalyzerAsync(code); } + [TestMethod] + public async Task WhenAnAbstractClassHasDeploymentItem_NoDiagnostic() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [DeploymentItem("")] + public abstract class MyTestClass + { + } + """; + + await VerifyCS.VerifyAnalyzerAsync(code); + } + [TestMethod] public async Task WhenAClassHasDeploymentItem_Diagnostic() { From 3f21675e4c2af4b469e666f7f8cbac6a2c2504dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Tue, 7 Jan 2025 17:07:20 +0100 Subject: [PATCH 236/273] =?UTF-8?q?Fix=20"Could=20not=20load=20file=20or?= =?UTF-8?q?=20assembly=20'Microsoft.Testing.Platform'"=20ex=E2=80=A6=20(#4?= =?UTF-8?q?540)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- eng/verify-nupkgs.ps1 | 2 +- .../MSTest.TestAdapter/BannedSymbols.txt | 1 + .../Execution/TestExecutionManager.cs | 8 ++----- .../Helpers/MSTestDiscovererHelpers.cs | 2 +- .../IPlatformServiceProvider.cs | 2 ++ .../MSTest.TestAdapter.nuspec | 10 +++++++++ .../MSTest.TestAdapter/MSTestSettings.cs | 2 +- .../PlatformServiceProvider.cs | 2 ++ .../RunConfigurationSettings.cs | 2 +- .../BridgedConfiguration.cs | 21 +++++++++++++++++++ .../MSTestBannerCapability.cs | 2 ++ .../MSTestBridgedTestFramework.cs | 6 +++--- .../TestingPlatformAdapter/MSTestExtension.cs | 1 + ...TestGracefulStopTestExecutionCapability.cs | 7 ++++--- .../TestApplicationBuilderExtensions.cs | 1 + .../TestingPlatformBuilderHook.cs | 4 +++- .../VSTestAdapter/MSTestDiscoverer.cs | 2 +- .../VSTestAdapter/MSTestExecutor.cs | 8 ++++--- .../Interfaces/IConfiguration.cs | 13 +++++++++--- .../MSTestAdapter.PlatformServices.csproj | 4 +--- .../Services/MSTestAdapterSettings.cs | 2 +- .../Services/SettingsProvider.cs | 1 - .../Services/MSTestAdapterSettingsTests.cs | 2 +- .../MSTestSettingsTests.cs | 2 +- .../RunConfigurationSettingsTests.cs | 2 +- .../TestablePlatformServiceProvider.cs | 2 ++ 26 files changed, 79 insertions(+), 32 deletions(-) create mode 100644 src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/BridgedConfiguration.cs diff --git a/eng/verify-nupkgs.ps1 b/eng/verify-nupkgs.ps1 index d39c6437ba..c4e8ca3be5 100644 --- a/eng/verify-nupkgs.ps1 +++ b/eng/verify-nupkgs.ps1 @@ -22,7 +22,7 @@ function Confirm-NugetPackages { "MSTest.Sdk" = 15; "MSTest.Internal.TestFx.Documentation" = 10; "MSTest.TestFramework" = 148; - "MSTest.TestAdapter" = 74; + "MSTest.TestAdapter" = 75; "MSTest" = 6; "MSTest.Analyzers" = 50; } diff --git a/src/Adapter/MSTest.TestAdapter/BannedSymbols.txt b/src/Adapter/MSTest.TestAdapter/BannedSymbols.txt index 91178cbc64..31a6272126 100644 --- a/src/Adapter/MSTest.TestAdapter/BannedSymbols.txt +++ b/src/Adapter/MSTest.TestAdapter/BannedSymbols.txt @@ -1 +1,2 @@ M:Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Helpers.ReflectHelper.#ctor; This is allowed only for tests. +N:Microsoft.Testing.Platform diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs index 11e6383173..fbcf98fd67 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs @@ -407,12 +407,10 @@ private void ExecuteTestsInSource(IEnumerable tests, IRunContext? runC ExecuteTestsWithTestRunner(testsToRun, frameworkHandle, source, sourceLevelParameters, testRunner); } -#if !WINDOWS_UWP - if (MSTestGracefulStopTestExecutionCapability.Instance.IsStopRequested) + if (PlatformServiceProvider.Instance.IsGracefulStopRequested) { testRunner.ForceCleanup(sourceLevelParameters!, new RemotingMessageLogger(frameworkHandle)); } -#endif PlatformServiceProvider.Instance.AdapterTraceLogger.LogInfo("Executed tests belonging to source {0}", source); } @@ -436,12 +434,10 @@ private void ExecuteTestsWithTestRunner( foreach (TestCase currentTest in orderedTests) { _testRunCancellationToken?.ThrowIfCancellationRequested(); -#if !WINDOWS_UWP - if (MSTestGracefulStopTestExecutionCapability.Instance.IsStopRequested) + if (PlatformServiceProvider.Instance.IsGracefulStopRequested) { break; } -#endif // If it is a fixture test, add it to the list of fixture tests and do not execute it. // It is executed by test itself. diff --git a/src/Adapter/MSTest.TestAdapter/Helpers/MSTestDiscovererHelpers.cs b/src/Adapter/MSTest.TestAdapter/Helpers/MSTestDiscovererHelpers.cs index 7d4d8ee7b8..3b76323e58 100644 --- a/src/Adapter/MSTest.TestAdapter/Helpers/MSTestDiscovererHelpers.cs +++ b/src/Adapter/MSTest.TestAdapter/Helpers/MSTestDiscovererHelpers.cs @@ -1,8 +1,8 @@ // 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.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; diff --git a/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs b/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs index c7d48ea95d..8923a5c1c8 100644 --- a/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/IPlatformServiceProvider.cs @@ -59,6 +59,8 @@ internal interface IPlatformServiceProvider /// TestRunCancellationToken? TestRunCancellationToken { get; set; } + bool IsGracefulStopRequested { get; set; } + /// /// Creates an instance to the platform service for a test source host. /// diff --git a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec index 845b2f2dee..48850bcbb4 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec +++ b/src/Adapter/MSTest.TestAdapter/MSTest.TestAdapter.nuspec @@ -99,6 +99,16 @@ + + diff --git a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs index dd2320c4d7..c371cd755c 100644 --- a/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs +++ b/src/Adapter/MSTest.TestAdapter/MSTestSettings.cs @@ -1,8 +1,8 @@ // 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.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; #if !WINDOWS_UWP using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; #endif diff --git a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs index 90c8134b8c..1ad6cc37b1 100644 --- a/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs +++ b/src/Adapter/MSTest.TestAdapter/PlatformServiceProvider.cs @@ -141,6 +141,8 @@ public IReflectionOperations2 ReflectionOperations /// public TestRunCancellationToken? TestRunCancellationToken { get; set; } + public bool IsGracefulStopRequested { get; set; } + /// /// Gets or sets the instance for the platform service. /// diff --git a/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs b/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs index d2386624c9..2f9a8da62f 100644 --- a/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs +++ b/src/Adapter/MSTest.TestAdapter/RunConfigurationSettings.cs @@ -2,7 +2,7 @@ // Licensed under the MIT license. See LICENSE file in the project root for full license information. #if !WINDOWS_UWP -using Microsoft.Testing.Platform.Configurations; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; #endif using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/BridgedConfiguration.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/BridgedConfiguration.cs new file mode 100644 index 0000000000..2deb1e6aa3 --- /dev/null +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/BridgedConfiguration.cs @@ -0,0 +1,21 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. + +#if !WINDOWS_UWP +using Microsoft.Testing.Platform.Configurations; + +using PlatformServicesConfiguration = Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface.IConfiguration; + +namespace Microsoft.VisualStudio.TestTools.UnitTesting; + +[SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs", Justification = "We can use MTP from this folder")] +internal sealed class BridgedConfiguration : PlatformServicesConfiguration +{ + private readonly IConfiguration _configuration; + + public BridgedConfiguration(IConfiguration configuration) + => _configuration = configuration; + + public string? this[string key] => _configuration[key]; +} +#endif diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs index 46693dd8c3..3ebc32ee6d 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBannerCapability.cs @@ -8,6 +8,8 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + +[SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs", Justification = "We can use MTP from this folder")] internal sealed class MSTestBannerCapability : IBannerMessageOwnerCapability { private readonly IPlatformInformation _platformInformation; diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs index a5af5cb408..b8c584587b 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestBridgedTestFramework.cs @@ -5,21 +5,21 @@ using Microsoft.Testing.Extensions.VSTestBridge; using Microsoft.Testing.Extensions.VSTestBridge.Requests; using Microsoft.Testing.Platform.Capabilities.TestFramework; -using Microsoft.Testing.Platform.Configurations; using Microsoft.Testing.Platform.Messages; using Microsoft.Testing.Platform.Services; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; namespace Microsoft.VisualStudio.TestTools.UnitTesting; +[SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs", Justification = "We can use MTP from this folder")] internal sealed class MSTestBridgedTestFramework : SynchronizedSingleSessionVSTestBridgedTestFramework { - private readonly IConfiguration? _configuration; + private readonly BridgedConfiguration? _configuration; public MSTestBridgedTestFramework(MSTestExtension mstestExtension, Func> getTestAssemblies, IServiceProvider serviceProvider, ITestFrameworkCapabilities capabilities) : base(mstestExtension, getTestAssemblies, serviceProvider, capabilities) - => _configuration = serviceProvider.GetConfiguration(); + => _configuration = new(serviceProvider.GetConfiguration()); /// protected override Task SynchronizedDiscoverTestsAsync(VSTestDiscoverTestExecutionRequest request, IMessageBus messageBus, diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestExtension.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestExtension.cs index 8fbd29bc26..b331865f1a 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestExtension.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestExtension.cs @@ -6,6 +6,7 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; +[SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs", Justification = "We can use MTP from this folder")] internal sealed class MSTestExtension : IExtension { public string Uid { get; } = GetExtensionUid(); diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestGracefulStopTestExecutionCapability.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestGracefulStopTestExecutionCapability.cs index 986e45c004..ea80488cb6 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestGracefulStopTestExecutionCapability.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/MSTestGracefulStopTestExecutionCapability.cs @@ -3,10 +3,13 @@ #if !WINDOWS_UWP using Microsoft.Testing.Platform.Capabilities.TestFramework; +using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; namespace Microsoft.VisualStudio.TestTools.UnitTesting; #pragma warning disable TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. + +[SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs", Justification = "We can use MTP from this folder")] internal sealed class MSTestGracefulStopTestExecutionCapability : IGracefulStopTestExecutionCapability #pragma warning restore TPEXP // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. { @@ -16,11 +19,9 @@ private MSTestGracefulStopTestExecutionCapability() public static MSTestGracefulStopTestExecutionCapability Instance { get; } = new(); - public bool IsStopRequested { get; private set; } - public Task StopTestExecutionAsync(CancellationToken cancellationToken) { - IsStopRequested = true; + PlatformServiceProvider.Instance.IsGracefulStopRequested = true; return Task.CompletedTask; } } diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs index 045fc76a77..f16999eb17 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestApplicationBuilderExtensions.cs @@ -11,6 +11,7 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; +[SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs", Justification = "We can use MTP from this folder")] public static class TestApplicationBuilderExtensions { public static void AddMSTest(this ITestApplicationBuilder testApplicationBuilder, Func> getTestAssemblies) diff --git a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestingPlatformBuilderHook.cs b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestingPlatformBuilderHook.cs index a38ab697c8..380adc63c3 100644 --- a/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestingPlatformBuilderHook.cs +++ b/src/Adapter/MSTest.TestAdapter/TestingPlatformAdapter/TestingPlatformBuilderHook.cs @@ -6,9 +6,11 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting; +[SuppressMessage("ApiDesign", "RS0030:Do not use banned APIs", Justification = "We can use MTP from this folder")] public static class TestingPlatformBuilderHook { #pragma warning disable IDE0060 // Remove unused parameter - public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, string[] arguments) => testApplicationBuilder.AddMSTest(() => [Assembly.GetEntryAssembly()!]); + public static void AddExtensions(ITestApplicationBuilder testApplicationBuilder, string[] arguments) + => testApplicationBuilder.AddMSTest(() => [Assembly.GetEntryAssembly()!]); } #endif diff --git a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs index 1ba0d68d3f..04eefda012 100644 --- a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs +++ b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestDiscoverer.cs @@ -1,7 +1,7 @@ // 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.Testing.Platform.Configurations; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; diff --git a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs index 9f1de06897..236659f902 100644 --- a/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs +++ b/src/Adapter/MSTest.TestAdapter/VSTestAdapter/MSTestExecutor.cs @@ -1,8 +1,8 @@ // 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.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.Execution; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; @@ -49,9 +49,11 @@ internal MSTestExecutor(CancellationToken cancellationToken) /// public TestExecutionManager TestExecutionManager { get; protected set; } - public void RunTests(IEnumerable? tests, IRunContext? runContext, IFrameworkHandle? frameworkHandle) => RunTests(tests, runContext, frameworkHandle, null); + public void RunTests(IEnumerable? tests, IRunContext? runContext, IFrameworkHandle? frameworkHandle) + => RunTests(tests, runContext, frameworkHandle, null); - public void RunTests(IEnumerable? sources, IRunContext? runContext, IFrameworkHandle? frameworkHandle) => RunTests(sources, runContext, frameworkHandle, null); + public void RunTests(IEnumerable? sources, IRunContext? runContext, IFrameworkHandle? frameworkHandle) + => RunTests(sources, runContext, frameworkHandle, null); internal void RunTests(IEnumerable? tests, IRunContext? runContext, IFrameworkHandle? frameworkHandle, IConfiguration? configuration) { diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IConfiguration.cs b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IConfiguration.cs index 4a177a55d9..0630e03f79 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IConfiguration.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Interfaces/IConfiguration.cs @@ -1,10 +1,17 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -#if WINDOWS_UWP -namespace Microsoft.Testing.Platform.Configurations; +namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; +/// +/// Represents a configuration interface. +/// internal interface IConfiguration { + /// + /// Gets or sets the value associated with the specified key. + /// + /// The key of the value to get or set. + /// The value associated with the specified key. + string? this[string key] { get; } } -#endif diff --git a/src/Adapter/MSTestAdapter.PlatformServices/MSTestAdapter.PlatformServices.csproj b/src/Adapter/MSTestAdapter.PlatformServices/MSTestAdapter.PlatformServices.csproj index afa1b916ed..07f30f5b18 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/MSTestAdapter.PlatformServices.csproj +++ b/src/Adapter/MSTestAdapter.PlatformServices/MSTestAdapter.PlatformServices.csproj @@ -31,8 +31,6 @@ - Analyzer false @@ -40,7 +38,7 @@ - + diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs index a71a4322ba..f2e745a748 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs @@ -3,7 +3,7 @@ #if !WINDOWS_UWP -using Microsoft.Testing.Platform.Configurations; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs index 6775530711..709ca664ec 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/SettingsProvider.cs @@ -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 Microsoft.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; namespace Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; diff --git a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs index b39f3966d3..b9d863ba6d 100644 --- a/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs +++ b/test/UnitTests/MSTestAdapter.PlatformServices.UnitTests/Services/MSTestAdapterSettingsTests.cs @@ -1,8 +1,8 @@ // 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.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.ObjectModel; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Utilities; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs index fa447f29a2..09b54289d7 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/MSTestSettingsTests.cs @@ -1,9 +1,9 @@ // 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.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter.ObjectModel; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.TestableImplementations; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/RunConfigurationSettingsTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/RunConfigurationSettingsTests.cs index ada116e3a0..25ef9f3978 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/RunConfigurationSettingsTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/RunConfigurationSettingsTests.cs @@ -1,8 +1,8 @@ // 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.Testing.Platform.Configurations; using Microsoft.VisualStudio.TestPlatform.MSTest.TestAdapter; +using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.PlatformServices.Interface; using Microsoft.VisualStudio.TestPlatform.MSTestAdapter.UnitTests.TestableImplementations; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Adapter; using Microsoft.VisualStudio.TestPlatform.ObjectModel.Logging; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs b/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs index f00c1b7411..5f9bec282d 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/TestableImplementations/TestablePlatformServiceProvider.cs @@ -126,6 +126,8 @@ public IReflectionOperations2 ReflectionOperations public TestRunCancellationToken TestRunCancellationToken { get; set; } + public bool IsGracefulStopRequested { get; set; } + public ITestContext GetTestContext(ITestMethod testMethod, StringWriter writer, IDictionary properties, IMessageLogger messageLogger, UTF.UnitTestOutcome outcome) { var testContextImpl = new TestContextImplementation(testMethod, writer, properties, messageLogger); From 1d43f8b42f7f1d3aadf7bd42370d5656569270e1 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 7 Jan 2025 20:39:26 +0100 Subject: [PATCH 237/273] Fix NaN behavior for Assert.AreEqual/AreNotEqual (#4536) --- .../Assertions/Assert.AreEqual.cs | 80 ++- .../Assertions/AssertTests.AreEqualTests.cs | 664 ++++++++++++++++++ 2 files changed, 738 insertions(+), 6 deletions(-) diff --git a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs index 5b94c7ed13..3207dae62c 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.AreEqual.cs @@ -647,12 +647,44 @@ private static bool AreEqualFailing(string? expected, string? actual, bool ignor => CompareInternal(expected, actual, ignoreCase, culture) != 0; private static bool AreEqualFailing(float expected, float actual, float delta) - => float.IsNaN(expected) || float.IsNaN(actual) || float.IsNaN(delta) || - Math.Abs(expected - actual) > delta; + { + if (float.IsNaN(delta) || delta < 0) + { + // NaN and negative values don't make sense as a delta value. + throw new ArgumentOutOfRangeException(nameof(delta)); + } + + if (expected.Equals(actual)) + { + return false; + } + + // If both floats are NaN, then they were considered equal in the previous check. + // If only one of them is NaN, then they are not equal regardless of the value of delta. + // Then, the subtraction comparison to delta isn't involving NaNs. + return float.IsNaN(expected) || float.IsNaN(actual) || + Math.Abs(expected - actual) > delta; + } private static bool AreEqualFailing(double expected, double actual, double delta) - => double.IsNaN(expected) || double.IsNaN(actual) || double.IsNaN(delta) || - Math.Abs(expected - actual) > delta; + { + if (double.IsNaN(delta) || delta < 0) + { + // NaN and negative values don't make sense as a delta value. + throw new ArgumentOutOfRangeException(nameof(delta)); + } + + if (expected.Equals(actual)) + { + return false; + } + + // If both doubles are NaN, then they were considered equal in the previous check. + // If only one of them is NaN, then they are not equal regardless of the value of delta. + // Then, the subtraction comparison to delta isn't involving NaNs. + return double.IsNaN(expected) || double.IsNaN(actual) || + Math.Abs(expected - actual) > delta; + } private static bool AreEqualFailing(decimal expected, decimal actual, decimal delta) => Math.Abs(expected - actual) > delta; @@ -1086,7 +1118,25 @@ public static void AreNotEqual(float notExpected, float actual, float delta, [St } private static bool AreNotEqualFailing(float notExpected, float actual, float delta) - => Math.Abs(notExpected - actual) <= delta; + { + if (float.IsNaN(delta) || delta < 0) + { + // NaN and negative values don't make sense as a delta value. + throw new ArgumentOutOfRangeException(nameof(delta)); + } + + if (float.IsNaN(notExpected) && float.IsNaN(actual)) + { + // If both notExpected and actual are NaN, then AreNotEqual should fail. + return true; + } + + // Note: if both notExpected and actual are NaN, that was handled separately above. + // Now, if both are numerics, then the logic is good. + // And, if only one of them is NaN, we know they are not equal, meaning AreNotEqual shouldn't fail. + // And in this case we will correctly be returning false, because NaN <= anything is always false. + return Math.Abs(notExpected - actual) <= delta; + } /// /// Tests whether the specified decimals are equal and throws an exception @@ -1645,7 +1695,25 @@ public static void AreNotEqual(double notExpected, double actual, double delta, } private static bool AreNotEqualFailing(double notExpected, double actual, double delta) - => Math.Abs(notExpected - actual) <= delta; + { + if (double.IsNaN(delta) || delta < 0) + { + // NaN and negative values don't make sense as a delta value. + throw new ArgumentOutOfRangeException(nameof(delta)); + } + + if (double.IsNaN(notExpected) && double.IsNaN(actual)) + { + // If both notExpected and actual are NaN, then AreNotEqual should fail. + return true; + } + + // Note: if both notExpected and actual are NaN, that was handled separately above. + // Now, if both are numerics, then the logic is good. + // And, if only one of them is NaN, we know they are not equal, meaning AreNotEqual shouldn't fail. + // And in this case we will correctly be returning false, because NaN <= anything is always false. + return Math.Abs(notExpected - actual) <= delta; + } [DoesNotReturn] private static void ThrowAssertAreNotEqualFailed(T notExpected, T actual, T delta, string userMessage) diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs index 746caa344f..793c189caa 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.AreEqualTests.cs @@ -451,6 +451,670 @@ public async Task DoubleAreNotEqual_InterpolatedString_SameValues_ShouldFail() Verify(o.WasToStringCalled); } + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0f, 2.0f, float.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0f, 1.0f, float.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(float.NaN, 1.0f, float.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(float.NaN, float.NaN, float.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0f, float.NaN, float.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0f, 2.0f, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0f, 1.0f, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(float.NaN, 1.0f, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(float.NaN, float.NaN, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0f, float.NaN, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0f, 2.0f, float.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0f, 1.0f, float.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(float.NaN, 1.0f, float.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(float.NaN, float.NaN, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0f, float.NaN, float.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceGreaterThanDeltaPositive_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(5.0f, 2.0f, 2.0f)); // difference is 3. Delta is 2 + Verify(ex.Message == "Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <5> and actual value <2>. "); + } + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceGreaterThanDeltaNegative_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(2.0f, 5.0f, 2.0f)); // difference is -3. Delta is 2 + Verify(ex.Message == "Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <2> and actual value <5>. "); + } + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaPositive_DeltaIsNumeric_ShouldPass() + => Assert.AreEqual(5.0f, 4.0f, 2.0f); // difference is 1. Delta is 2 + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaNegative_DeltaIsNumeric_ShouldFail() + => Assert.AreEqual(4.0f, 5.0f, 2.0f); // difference is -1. Delta is 2 + + public void FloatAreEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(5.0f, float.NaN, 2.0f)); + Verify(ex.Message == "Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <5> and actual value . "); + } + + public void FloatAreEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(float.NaN, 5.0f, 2.0f)); + Verify(ex.Message == "Assert.AreEqual failed. Expected a difference no greater than <2> between expected value and actual value <5>. "); + } + + public void FloatAreEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNumeric_ShouldPass() + => Assert.AreEqual(float.NaN, float.NaN, 2.0f); + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0f, 2.0f, float.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0f, 1.0f, float.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(float.NaN, 1.0f, float.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(float.NaN, float.NaN, float.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0f, float.NaN, float.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0f, 2.0f, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0f, 1.0f, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(float.NaN, 1.0f, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(float.NaN, float.NaN, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0f, float.NaN, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0f, 2.0f, -1.0f)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0f, 1.0f, float.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(float.NaN, 1.0f, float.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(float.NaN, float.NaN, float.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0f, float.NaN, float.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceGreaterThanDeltaPositive_DeltaIsNumeric_ShouldPass() + => Assert.AreNotEqual(5.0f, 2.0f, 2.0f); // difference is 3. Delta is 2 + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceGreaterThanDeltaNegative_DeltaIsNumeric_ShouldPass() + => Assert.AreNotEqual(2.0f, 5.0f, 2.0f); // difference is -3. Delta is 2 + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaPositive_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(5.0f, 4.0f, 2.0f)); // difference is 1. Delta is 2 + Verify(ex.Message == "Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value <5> and actual value <4>. "); + } + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaNegative_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(4.0f, 5.0f, 2.0f)); // difference is -1. Delta is 2 + Verify(ex.Message == "Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value <4> and actual value <5>. "); + } + + public void FloatAreNotEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNumeric_ShouldPass() => Assert.AreNotEqual(5.0f, float.NaN, 2.0f); + + public void FloatAreNotEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNumeric_ShouldPass() + => Assert.AreNotEqual(float.NaN, 5.0f, 2.0f); + + public void FloatAreNotEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(float.NaN, float.NaN, 2.0f)); + Verify(ex.Message == "Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value and actual value . "); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0d, 2.0d, double.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0d, 1.0d, double.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(double.NaN, 1.0d, double.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(double.NaN, double.NaN, double.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0d, double.NaN, double.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0d, 2.0d, -1.0d)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0d, 1.0d, -1.0d)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(double.NaN, 1.0d, -1.0d)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(double.NaN, double.NaN, -1.0d)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0d, double.NaN, -1.0d)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0d, 2.0d, double.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0d, 1.0d, double.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(double.NaN, 1.0d, double.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(double.NaN, double.NaN, double.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(1.0d, double.NaN, double.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceGreaterThanDeltaPositive_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(5.0d, 2.0d, 2.0d)); // difference is 3. Delta is 2 + Verify(ex.Message == "Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <5> and actual value <2>. "); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceGreaterThanDeltaNegative_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(2.0d, 5.0d, 2.0d)); // difference is -3. Delta is 2 + Verify(ex.Message == "Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <2> and actual value <5>. "); + } + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaPositive_DeltaIsNumeric_ShouldPass() + => Assert.AreEqual(5.0d, 4.0d, 2.0d); // difference is 1. Delta is 2 + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaNegative_DeltaIsNumeric_ShouldFail() + => Assert.AreEqual(4.0d, 5.0d, 2.0d); // difference is -1. Delta is 2 + + public void DoubleAreEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(5.0d, double.NaN, 2.0d)); + Verify(ex.Message == "Assert.AreEqual failed. Expected a difference no greater than <2> between expected value <5> and actual value . "); + } + + public void DoubleAreEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreEqual(double.NaN, 5.0d, 2.0d)); + Verify(ex.Message == "Assert.AreEqual failed. Expected a difference no greater than <2> between expected value and actual value <5>. "); + } + + public void DoubleAreEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNumeric_ShouldPass() + => Assert.AreEqual(double.NaN, double.NaN, 2.0d); + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0d, 2.0d, double.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0d, 1.0d, double.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(double.NaN, 1.0d, double.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(double.NaN, double.NaN, double.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNaN_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0d, double.NaN, double.NaN)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0d, 2.0d, -1.0d)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0d, 1.0d, -1.0d)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(double.NaN, 1.0d, -1.0d)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(double.NaN, double.NaN, -1.0d)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNegative_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0d, double.NaN, -1.0d)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualNotEquals_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0d, 2.0d, double.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualEquals_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0d, 1.0d, double.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(double.NaN, 1.0d, double.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(double.NaN, double.NaN, double.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNegativeInf_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(1.0d, double.NaN, double.NegativeInfinity)); + Verify(ex.Message is """ + Specified argument was out of the range of valid values. + Parameter name: delta + """ or "Specified argument was out of the range of valid values. (Parameter 'delta')"); + } + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceGreaterThanDeltaPositive_DeltaIsNumeric_ShouldPass() + => Assert.AreNotEqual(5.0d, 2.0d, 2.0d); // difference is 3. Delta is 2 + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceGreaterThanDeltaNegative_DeltaIsNumeric_ShouldPass() + => Assert.AreNotEqual(2.0d, 5.0d, 2.0d); // difference is -3. Delta is 2 + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaPositive_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(5.0d, 4.0d, 2.0d)); // difference is 1. Delta is 2 + Verify(ex.Message == "Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value <5> and actual value <4>. "); + } + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNumeric_ExpectedAndActualDifferenceLessThanDeltaNegative_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(4.0d, 5.0d, 2.0d)); // difference is -1. Delta is 2 + Verify(ex.Message == "Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value <4> and actual value <5>. "); + } + + public void DoubleAreNotEqual_ExpectedIsNumeric_ActualIsNaN_DeltaIsNumeric_ShouldPass() => Assert.AreNotEqual(5.0d, double.NaN, 2.0d); + + public void DoubleAreNotEqual_ExpectedIsNaN_ActualIsNumeric_DeltaIsNumeric_ShouldPass() + => Assert.AreNotEqual(double.NaN, 5.0d, 2.0d); + + public void DoubleAreNotEqual_ExpectedIsNaN_ActualIsNaN_DeltaIsNumeric_ShouldFail() + { + Exception ex = VerifyThrows(() => Assert.AreNotEqual(double.NaN, double.NaN, 2.0d)); + Verify(ex.Message == "Assert.AreNotEqual failed. Expected a difference greater than <2> between expected value and actual value . "); + } + private CultureInfo? GetCultureInfo() => CultureInfo.CurrentCulture; private class TypeOverridesEquals From 6dcb80f951d627bc61b15712c9b89a1440ceeb2b Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 7 Jan 2025 20:40:51 +0100 Subject: [PATCH 238/273] Implement codefix for MSTEST0026: Avoid conditional access in assertions (and small analyzer false positive) (#4502) --- ...onArgsShouldAvoidConditionalAccessFixer.cs | 239 ++++++++++ .../CodeFixResources.Designer.cs | 9 + .../CodeFixResources.resx | 3 + .../xlf/CodeFixResources.cs.xlf | 5 + .../xlf/CodeFixResources.de.xlf | 5 + .../xlf/CodeFixResources.es.xlf | 5 + .../xlf/CodeFixResources.fr.xlf | 5 + .../xlf/CodeFixResources.it.xlf | 5 + .../xlf/CodeFixResources.ja.xlf | 5 + .../xlf/CodeFixResources.ko.xlf | 5 + .../xlf/CodeFixResources.pl.xlf | 5 + .../xlf/CodeFixResources.pt-BR.xlf | 5 + .../xlf/CodeFixResources.ru.xlf | 5 + .../xlf/CodeFixResources.tr.xlf | 5 + .../xlf/CodeFixResources.zh-Hans.xlf | 5 + .../xlf/CodeFixResources.zh-Hant.xlf | 5 + ...rgsShouldAvoidConditionalAccessAnalyzer.cs | 95 ++-- ...ouldAvoidConditionalAccessAnalyzerTests.cs | 434 +++++++++++++++++- 18 files changed, 798 insertions(+), 47 deletions(-) create mode 100644 src/Analyzers/MSTest.Analyzers.CodeFixes/AssertionArgsShouldAvoidConditionalAccessFixer.cs diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/AssertionArgsShouldAvoidConditionalAccessFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/AssertionArgsShouldAvoidConditionalAccessFixer.cs new file mode 100644 index 0000000000..60e8614c80 --- /dev/null +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/AssertionArgsShouldAvoidConditionalAccessFixer.cs @@ -0,0 +1,239 @@ +// 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 System.Composition; + +using Analyzer.Utilities; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Editing; + +using MSTest.Analyzers.Helpers; + +namespace MSTest.Analyzers; + +[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(AssertionArgsShouldAvoidConditionalAccessFixer))] +[Shared] +public sealed class AssertionArgsShouldAvoidConditionalAccessFixer : CodeFixProvider +{ + /// + /// The scenario that is complicating this code fix is if we have multiple diagnostics that are doing conditional access + /// on the same expression. In that case, we need to ensure that we don't add multiple Assert.IsNotNull calls. + /// The first idea was to iterate through the existing statements, and if we found Assert.IsNotNull with + /// the relevant expression, we don't add it again. However, this approach works for iterative codefix application + /// only, and doesn't work with the BatchFixAllProvider. The BatchFixAllProvider works by applying individual fixes + /// completely in isolation, then merging the text changes. + /// This means, every invocation of the code action will not see that Assert.IsNotNull was added by another. + /// So, we provide our own FixAllProvider. + /// This FixAllProvider will reuse the same DocumentEditor across all the code actions. + /// + private sealed class CustomFixAll : DocumentBasedFixAllProvider + { + protected override async Task FixAllAsync(FixAllContext fixAllContext, Document document, ImmutableArray diagnostics) + { + SyntaxNode root = await document.GetRequiredSyntaxRootAsync(fixAllContext.CancellationToken).ConfigureAwait(false); + DocumentEditor editor = await DocumentEditor.CreateAsync(document, fixAllContext.CancellationToken); + Document currentDocument = document; + foreach (Diagnostic diagnostic in diagnostics) + { + SyntaxNode assertInvocation = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); + // We need to track the assert invocation so that the individual 'SingleFixCodeAction's can get the up-to-date node + // from the most recent tree. + // Having the most recent node is important for IsNullAssertAlreadyPresent to work properly. + // We get the most recent node via editor.GetChangedRoot().GetCurrentNode(...) + editor.TrackNode(assertInvocation); + } + + foreach (Diagnostic diagnostic in diagnostics) + { + SyntaxNode conditionalAccess = root.FindNode(diagnostic.AdditionalLocations[0].SourceSpan, getInnermostNodeForTie: true); + SyntaxNode assertInvocation = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); + if (conditionalAccess is not ConditionalAccessExpressionSyntax conditionalAccessExpressionSyntax || + assertInvocation is not InvocationExpressionSyntax invocationExpressionSyntax) + { + continue; + } + + var codeAction = new SingleFixCodeAction(currentDocument, conditionalAccessExpressionSyntax, invocationExpressionSyntax); + currentDocument = codeAction.ApplyFix(editor); + } + + return editor.GetChangedDocument(); + } + } + + public sealed override ImmutableArray FixableDiagnosticIds { get; } + = ImmutableArray.Create(DiagnosticIds.AssertionArgsShouldAvoidConditionalAccessRuleId); + + public override FixAllProvider GetFixAllProvider() + // See https://github.com/dotnet/roslyn/blob/main/docs/analyzers/FixAllProvider.md for more information on Fix All Providers + => new CustomFixAll(); + + public override async Task RegisterCodeFixesAsync(CodeFixContext context) + { + SyntaxNode root = await context.Document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + Diagnostic diagnostic = context.Diagnostics[0]; + + SyntaxNode conditionalAccess = root.FindNode(diagnostic.AdditionalLocations[0].SourceSpan, getInnermostNodeForTie: true); + SyntaxNode assertInvocation = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); + if (conditionalAccess is not ConditionalAccessExpressionSyntax conditionalAccessExpressionSyntax || + assertInvocation is not InvocationExpressionSyntax invocationExpressionSyntax) + { + return; + } + + context.RegisterCodeFix( + new SingleFixCodeAction(context.Document, conditionalAccessExpressionSyntax, invocationExpressionSyntax), + diagnostic); + } + + private sealed class SingleFixCodeAction : CodeAction + { + private readonly Document _document; + private readonly ConditionalAccessExpressionSyntax _conditionalAccessExpressionSyntax; + private readonly InvocationExpressionSyntax _invocationExpressionSyntax; + + public SingleFixCodeAction(Document document, ConditionalAccessExpressionSyntax conditionalAccessExpressionSyntax, InvocationExpressionSyntax invocationExpressionSyntax) + { + _document = document; + _conditionalAccessExpressionSyntax = conditionalAccessExpressionSyntax; + _invocationExpressionSyntax = invocationExpressionSyntax; + } + + public override string Title { get; } = CodeFixResources.AssertionArgsShouldAvoidConditionalAccessFix; + + public override string? EquivalenceKey => nameof(AssertionArgsShouldAvoidConditionalAccessFixer); + + protected override async Task GetChangedDocumentAsync(CancellationToken cancellationToken) + { + DocumentEditor editor = await DocumentEditor.CreateAsync(_document, cancellationToken).ConfigureAwait(false); + return ApplyFix(editor); + } + + internal Document ApplyFix(DocumentEditor editor) + { + ExpressionSyntax expressionCheckedForNull = _conditionalAccessExpressionSyntax.Expression; + bool isNullAssertAlreadyPresent = IsNullAssertAlreadyPresent(expressionCheckedForNull, editor.GetChangedRoot().GetCurrentNode(_invocationExpressionSyntax) ?? _invocationExpressionSyntax); + + // Easier than correctly reconstructing the syntax node manually, but not ideal. + ExpressionSyntax parsedExpression = SyntaxFactory.ParseExpression($"{expressionCheckedForNull.ToFullString()}{_conditionalAccessExpressionSyntax.WhenNotNull}"); + parsedExpression = parsedExpression.WithTriviaFrom(_conditionalAccessExpressionSyntax); + + editor.ReplaceNode(_conditionalAccessExpressionSyntax, parsedExpression); + + if (!isNullAssertAlreadyPresent) + { + ExpressionStatementSyntax assertIsNotNull = SyntaxFactory.ExpressionStatement( + SyntaxFactory.InvocationExpression( + SyntaxFactory.MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.IdentifierName("Assert"), + SyntaxFactory.IdentifierName("IsNotNull"))) + .WithArgumentList( + SyntaxFactory.ArgumentList( + SyntaxFactory.SingletonSeparatedList( + SyntaxFactory.Argument(expressionCheckedForNull))))); + if (_invocationExpressionSyntax.Parent is ExpressionStatementSyntax expressionStatement) + { + editor.InsertBefore(expressionStatement, assertIsNotNull); + } + else if (_invocationExpressionSyntax.Parent is ArrowExpressionClauseSyntax arrowExpressionClauseSyntax) + { + // The following types are where ArrowExpressionClause can appear. + // BaseMethodDeclarationSyntax: ConstructorDeclarationSyntax, ConversionOperatorDeclarationSyntax, DestructorDeclarationSyntax, MethodDeclarationSyntax, OperatorDeclarationSyntax + // AccessorDeclarationSyntax, IndexerDeclarationSyntax, PropertyDeclarationSyntax, LocalFunctionStatementSyntax + // + // PropertyDeclarationSyntax and IndexerDeclarationSyntax don't make sense so we won't handle it. + if (arrowExpressionClauseSyntax.Parent is BaseMethodDeclarationSyntax parentBaseMethod) + { + editor.ReplaceNode( + parentBaseMethod, + (node, _) => + { + var parentBaseMethod = (BaseMethodDeclarationSyntax)node; + return parentBaseMethod + .WithExpressionBody(null) + .WithSemicolonToken(default) + .WithBody(SyntaxFactory.Block( + assertIsNotNull, + SyntaxFactory.ExpressionStatement(parentBaseMethod.ExpressionBody!.Expression))); + }); + } + else if (arrowExpressionClauseSyntax.Parent is AccessorDeclarationSyntax parentAccessor) + { + editor.ReplaceNode( + parentAccessor, + (node, _) => + { + var parentAccessor = (AccessorDeclarationSyntax)node; + return parentAccessor + .WithExpressionBody(null) + .WithSemicolonToken(default) + .WithBody(SyntaxFactory.Block( + assertIsNotNull, + SyntaxFactory.ExpressionStatement(parentAccessor.ExpressionBody!.Expression))); + }); + } + else if (arrowExpressionClauseSyntax.Parent is LocalFunctionStatementSyntax parentLocalFunction) + { + editor.ReplaceNode( + parentLocalFunction, + (node, _) => + { + var parentLocalFunction = (LocalFunctionStatementSyntax)node; + return parentLocalFunction + .WithExpressionBody(null) + .WithSemicolonToken(default) + .WithBody(SyntaxFactory.Block( + assertIsNotNull, + SyntaxFactory.ExpressionStatement(parentLocalFunction.ExpressionBody!.Expression))); + }); + } + } + } + + return editor.GetChangedDocument(); + } + } + + private static bool IsNullAssertAlreadyPresent(SyntaxNode expressionCheckedForNull, InvocationExpressionSyntax invocationExpressionSyntax) + { + if (invocationExpressionSyntax.Parent?.Parent is not BlockSyntax blockSyntax) + { + return false; + } + + foreach (StatementSyntax statement in blockSyntax.Statements) + { + if (statement is not ExpressionStatementSyntax expressionStatement) + { + continue; + } + + // We expect Assert.IsNull to be present before the invocation expression in question. + if (expressionStatement.Expression == invocationExpressionSyntax) + { + return false; + } + + if (expressionStatement.Expression is InvocationExpressionSyntax invocation) + { + SimpleNameSyntax? methodName = + invocation.Expression as IdentifierNameSyntax ?? (invocation.Expression as MemberAccessExpressionSyntax)?.Name; + if ((methodName?.Identifier.Value as string) == "IsNotNull" && + invocation.ArgumentList.Arguments.Count > 0 && + invocation.ArgumentList.Arguments[0].Expression.IsEquivalentTo(expressionCheckedForNull)) + { + return true; + } + } + } + + return false; + } +} diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs index f5a7523e84..8eb5b990f5 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs @@ -78,6 +78,15 @@ internal static string AssemblyInitializeShouldBeValidCodeFix { } } + /// + /// Looks up a localized string similar to Move conditional access in assertion to separate 'Assert.IsNotNull' check. + /// + internal static string AssertionArgsShouldAvoidConditionalAccessFix { + get { + return ResourceManager.GetString("AssertionArgsShouldAvoidConditionalAccessFix", resourceCulture); + } + } + /// /// Looks up a localized string similar to Change method accessibility to 'private'. /// diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx index d59fe84364..a72a7039ef 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx @@ -171,4 +171,7 @@ Use '{0}' + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf index 70893b6e64..e7df9fde23 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf @@ -7,6 +7,11 @@ Přidat [TestMethod] + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' Změnit přístupnost metody na private diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf index 2eda581eb9..55854fb46c 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf @@ -7,6 +7,11 @@ „[TestMethod]“ hinzufügen + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' Methodenzugriff auf „privat“ ändern diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf index 7135f5bedf..737bcf868b 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf @@ -7,6 +7,11 @@ Agregar '[TestMethod]' + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' Cambiar la accesibilidad del método a "private" diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf index 89525653e5..1b77f40977 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf @@ -7,6 +7,11 @@ Ajouter « [TestMethod] » + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' Remplacer l’accessibilité de la méthode par « privé » diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf index 4e81efb9b2..2523dff190 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf @@ -7,6 +7,11 @@ Aggiungi '[TestMethod]' + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' Modifica l'accessibilità del metodo in 'privato' diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf index bf289a600c..4582255692 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf @@ -7,6 +7,11 @@ '[TestMethod]' の追加 + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' メソッドのアクセシビリティを 'private' に変更する diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf index 7db8bcdfb5..3ef3c4b74b 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf @@ -7,6 +7,11 @@ '[TestMethod]' 추가 + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' 메서드 접근성 '비공개'로 변경하기 diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf index e327bf1b3e..f3e5a06292 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf @@ -7,6 +7,11 @@ Dodaj „[TestMethod]” + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' Zmień dostępność metody na „private” (prywatna) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf index e3160981fb..78e947879a 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf @@ -7,6 +7,11 @@ Adicionar ''[TestMethod]" + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' Alterar a acessibilidade do método para 'privado' diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf index 10a50cb7e8..06b914441c 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf @@ -7,6 +7,11 @@ Добавить "[TestMethod]" + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' Изменить доступность метода на "private" diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf index e5d55eef49..1cb3982db4 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf @@ -7,6 +7,11 @@ '[TestMethod]' ekle + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' Yöntem erişilebilirliğini ‘özel’ olarak değiştir diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf index acf884ead9..4ad657b676 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf @@ -7,6 +7,11 @@ 添加“[TestMethod]” + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' 将方法可访问性更改为“private” diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf index 3c18ebee7e..520e49868b 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf @@ -7,6 +7,11 @@ 新增 '[TestMethod]' + + Move conditional access in assertion to separate 'Assert.IsNotNull' check + Move conditional access in assertion to separate 'Assert.IsNotNull' check + + Change method accessibility to 'private' 將方法協助工具變更為 'private' diff --git a/src/Analyzers/MSTest.Analyzers/AssertionArgsShouldAvoidConditionalAccessAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AssertionArgsShouldAvoidConditionalAccessAnalyzer.cs index 6cfe536e07..784f174305 100644 --- a/src/Analyzers/MSTest.Analyzers/AssertionArgsShouldAvoidConditionalAccessAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/AssertionArgsShouldAvoidConditionalAccessAnalyzer.cs @@ -10,6 +10,7 @@ using Microsoft.CodeAnalysis.Operations; using MSTest.Analyzers.Helpers; +using MSTest.Analyzers.RoslynAnalyzerHelpers; namespace MSTest.Analyzers; @@ -19,37 +20,38 @@ namespace MSTest.Analyzers; [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] public sealed class AssertionArgsShouldAvoidConditionalAccessAnalyzer : DiagnosticAnalyzer { - private static readonly ImmutableArray AssertSupportedMethodNames = ImmutableArray.Create([ - "IsTrue", - "IsFalse", - "AreEqual", - "AreNotEqual", - "AreSame", - "AreNotSame" + private static readonly ImmutableArray<(string MethodName, int ArgumentCountToCheck)> AssertSupportedMethodNames = ImmutableArray.Create([ + ("IsTrue", 1), + ("IsFalse", 1), + ("AreEqual", 2), + ("AreNotEqual", 2), + ("AreSame", 2), + ("AreNotSame", 2) ]); - private static readonly ImmutableArray CollectionAssertSupportedMethodNames = ImmutableArray.Create([ - "IsTrue", - "IsFalse", - "AreEqual", - "AreNotEqual", - "AreEquivalent", - "AreNotEquivalent", - "Contains", - "DoesNotContain", - "AllItemsAreNotNull", - "AllItemsAreUnique", - "IsSubsetOf", - "IsNotSubsetOf", - "AllItemsAreInstancesOfType" + private static readonly ImmutableArray<(string MethodName, int ArgumentCountToCheck)> CollectionAssertSupportedMethodNames = ImmutableArray.Create([ + ("AreEqual", 2), + ("AreNotEqual", 2), + ("AreEquivalent", 2), + ("AreNotEquivalent", 2), + // TODO: Is it really bad to have Assert.Contains(myCollection, expression_with_conditional_access)? A codefix seems like may not always yield the correct result for this case. + // TODO: Maybe we should check one argument only (the collection itself) + // Same applies to DoesNotContain + ("Contains", 2), + ("DoesNotContain", 2), + ("AllItemsAreNotNull", 1), + ("AllItemsAreUnique", 1), + ("IsSubsetOf", 2), + ("IsNotSubsetOf", 2), + ("AllItemsAreInstancesOfType", 2) ]); - private static readonly ImmutableArray StringAssertSupportedMethodNames = ImmutableArray.Create([ - "Contains", - "StartsWith", - "EndsWith", - "Matches", - "DoesNotMatch" + private static readonly ImmutableArray<(string MethodName, int ArgumentCountToCheck)> StringAssertSupportedMethodNames = ImmutableArray.Create([ + ("Contains", 2), + ("StartsWith", 2), + ("EndsWith", 2), + ("Matches", 2), + ("DoesNotMatch", 2) ]); private static readonly LocalizableResourceString Title = new(nameof(Resources.AssertionArgsShouldAvoidConditionalAccessTitle), Resources.ResourceManager, typeof(Resources)); @@ -91,50 +93,61 @@ public override void Initialize(AnalysisContext context) }); } - private static void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol assertSymbol, ImmutableArray supportedMethodNames) + private static void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol assertSymbol, ImmutableArray<(string MethodName, int ArgumentCountToCheck)> supportedMethodNames) { var invocationOperation = (IInvocationOperation)context.Operation; // This is not an invocation of the expected assertion methods. - if (!supportedMethodNames.Contains(invocationOperation.TargetMethod.Name) + (_, int argumentCountToCheck) = supportedMethodNames.FirstOrDefault(x => x.MethodName == invocationOperation.TargetMethod.Name); + if (argumentCountToCheck == 0 || !SymbolEqualityComparer.Default.Equals(assertSymbol, invocationOperation.TargetMethod.ContainingType) - || !HasAnyConditionalAccessOperationChild(invocationOperation)) + || !HasAnyConditionalAccessOperationChild(invocationOperation, argumentCountToCheck, out Location? additionalLocation)) { return; } - context.ReportDiagnostic(invocationOperation.CreateDiagnostic(Rule)); + context.ReportDiagnostic(invocationOperation.CreateDiagnostic(Rule, additionalLocations: ImmutableArray.Create(additionalLocation), properties: null)); } - private static bool HasAnyConditionalAccessOperationChild(IInvocationOperation invocationOperation) + private static bool HasAnyConditionalAccessOperationChild(IInvocationOperation invocationOperation, int argumentCountToCheck, [NotNullWhen(true)] out Location? additionalLocation) { foreach (IArgumentOperation argument in invocationOperation.Arguments) { + if (argument.Parameter is null || argument.Parameter.Ordinal >= argumentCountToCheck) + { + continue; + } + + // Check for conversion operations with conditional access => (s?.Length). + IOperation value = argument.Value.WalkDownConversion(); + // Check for conditional access // a?.b // a?.b?.c // a.b?.c - if (argument.Value is IConditionalAccessOperation { Kind: OperationKind.ConditionalAccess }) + if (value.Kind == OperationKind.ConditionalAccess) { + additionalLocation = value.Syntax.GetLocation(); return true; } // Check for binary operations with conditional access => s?.Length > 1. - if (argument.Value is IBinaryOperation binaryOperation) + if (value is IBinaryOperation binaryOperation) { - if (binaryOperation.LeftOperand.Kind == OperationKind.ConditionalAccess || binaryOperation.RightOperand.Kind == OperationKind.ConditionalAccess) + if (binaryOperation.LeftOperand.Kind == OperationKind.ConditionalAccess) { + additionalLocation = binaryOperation.LeftOperand.Syntax.GetLocation(); + return true; + } + else if (binaryOperation.RightOperand.Kind == OperationKind.ConditionalAccess) + { + additionalLocation = binaryOperation.RightOperand.Syntax.GetLocation(); return true; } - } - - // Check for conversion operations with conditional access => (s?.Length). - if (argument.Value is IConversionOperation { Operand.Kind: OperationKind.ConditionalAccess }) - { - return true; } } + additionalLocation = null; return false; } } diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldAvoidConditionalAccessAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldAvoidConditionalAccessAnalyzerTests.cs index 2a7f2b5ecc..67f245a0d1 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldAvoidConditionalAccessAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AssertionArgsShouldAvoidConditionalAccessAnalyzerTests.cs @@ -3,7 +3,7 @@ using VerifyCS = MSTest.Analyzers.Test.CSharpCodeFixVerifier< MSTest.Analyzers.AssertionArgsShouldAvoidConditionalAccessAnalyzer, - Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + MSTest.Analyzers.AssertionArgsShouldAvoidConditionalAccessFixer>; namespace MSTest.Analyzers.UnitTests; @@ -97,7 +97,106 @@ public void Compliant() } """; - await VerifyCS.VerifyAnalyzerAsync(code); + string fixedCode = """ + #nullable enable + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + public class A + { + public string? S { get; set; } + public List? T { get; set; } + } + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void NonCompliant() + { + A? a = new A(); + A b = new A(); + string? s = ""; + Assert.IsNotNull(s); + Assert.AreEqual(s.Length, 32); + Assert.AreEqual(((s.Length)), 32); + Assert.AreEqual(s.Length, s.Length); + Assert.IsNotNull(a); + Assert.IsNotNull(a.S); + Assert.AreEqual(a.S.Length, 32); + Assert.IsNotNull(b.S); + Assert.AreEqual(b.S.Length, 32); + Assert.IsNotNull(a.T); + Assert.IsNotNull(a.T[3]); + Assert.AreEqual(a.T[3].Length, 32); + Assert.IsNotNull(b.T); + Assert.IsNotNull(b.T[3]); + Assert.AreEqual(b.T[3].Length, 32); + + Assert.AreNotEqual(s.Length, 32); + Assert.AreNotEqual(((s.Length)), 32); + Assert.AreNotEqual(s.Length, s.Length); + Assert.AreNotEqual(a.S.Length, 32); + Assert.AreNotEqual(b.S.Length, 32); + Assert.AreNotEqual(a.T[3].Length, 32); + Assert.AreNotEqual(b.T[3].Length, 32); + + Assert.AreSame(s.Length, 32); + Assert.AreSame(((s.Length)), 32); + Assert.AreSame(s.Length, s.Length); + Assert.AreSame(a.S.Length, 32); + Assert.AreSame(b.S.Length, 32); + Assert.AreSame(a.T[3].Length, 32); + Assert.AreSame(b.T[3].Length, 32); + + Assert.AreNotSame(s.Length, 32); + Assert.AreNotSame(((s.Length)), 32); + Assert.AreNotSame(s.Length, s.Length); + Assert.AreNotSame(a.S.Length, 32); + Assert.AreNotSame(b.S.Length, 32); + Assert.AreNotSame(a.T[3].Length, 32); + Assert.AreNotSame(b.T[3].Length, 32); + } + + [TestMethod] + public void Compliant() + { + string? s = ""; + A? a = new A(); + A b = new A(); + + Assert.IsNotNull(s); + Assert.IsNotNull(a); + Assert.IsNotNull(a.S); + Assert.IsNotNull(a.T); + Assert.IsNotNull(b); + Assert.IsNotNull(b.S); + Assert.IsNotNull(b.T); + Assert.AreEqual(s.Length, 32); + Assert.AreEqual(((s.Length)), 32); + Assert.AreEqual(s.Length, s.Length); + Assert.AreEqual(a.S.Length, 32); + Assert.AreEqual(b.S.Length, 32); + Assert.AreEqual(a.T[3].Length, 32); + Assert.AreEqual(b.T[3].Length, 32); + Assert.AreNotEqual(s.Length, 32); + Assert.AreNotEqual(((s.Length)), 32); + Assert.AreNotEqual(s.Length, s.Length); + Assert.AreNotEqual(a.S.Length, 32); + Assert.AreNotEqual(b.S.Length, 32); + } + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + NumberOfFixAllIterations = 3, + NumberOfFixAllInDocumentIterations = 3, + NumberOfFixAllInProjectIterations = 3, + NumberOfIncrementalIterations = 48, + }.RunAsync(); } [TestMethod] @@ -157,7 +256,72 @@ public void Compliant() } """; - await VerifyCS.VerifyAnalyzerAsync(code); + string fixedCode = """ + #nullable enable + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + public class A + { + public string? S { get; set; } + } + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void NonCompliant() + { + A? a = new A(); + A b = new A(); + string? s = ""; + Assert.IsNotNull(s); + Assert.IsTrue(s.Length > 32); + Assert.IsTrue((s.Length> 32)); + Assert.IsNotNull(a); + Assert.IsNotNull(a.S); + Assert.IsTrue(a.S.Length > 32); + Assert.IsNotNull(b.S); + Assert.IsTrue(b.S.Length > 32); + Assert.IsFalse(s.Length > 32); + Assert.IsFalse((s.Length > 32)); + Assert.IsFalse(a.S.Length > 32); + Assert.IsFalse(b.S.Length > 32); + } + + [TestMethod] + public void Compliant() + { + string? s = ""; + A? a = new A(); + A b = new A(); + + Assert.IsNotNull(s); + Assert.IsNotNull(a); + Assert.IsNotNull(a.S); + Assert.IsNotNull(b); + Assert.IsNotNull(b.S); + Assert.IsTrue(s.Length > 32); + Assert.IsTrue((s.Length > 32)); + Assert.IsTrue(a.S.Length > 32); + Assert.IsTrue(b.S.Length > 32); + Assert.IsFalse(s.Length > 32); + Assert.IsFalse((s.Length > 32)); + Assert.IsFalse(a.S.Length > 32); + Assert.IsFalse(b.S.Length > 32); + } + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + NumberOfFixAllIterations = 2, + NumberOfFixAllInDocumentIterations = 2, + NumberOfFixAllInProjectIterations = 2, + NumberOfIncrementalIterations = 10, + }.RunAsync(); } [TestMethod] @@ -187,7 +351,7 @@ public void Compliant() } """; - await VerifyCS.VerifyAnalyzerAsync(code); + await VerifyCS.VerifyCodeFixAsync(code, code); } [TestMethod] @@ -259,7 +423,81 @@ public void Compliant() } """; - await VerifyCS.VerifyAnalyzerAsync(code); + string fixedCode = """ + #nullable enable + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + public class A + { + public List? S { get; set; } + public Type? T { get; set; } + } + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void NonCompliant() + { + A? a = new A(); + A b = new A(); + Assert.IsNotNull(a); + CollectionAssert.AreEqual(a.S, b.S); + CollectionAssert.AreEqual(a.S, a.S); + CollectionAssert.AreEqual(b.S, a.S); + CollectionAssert.AreNotEqual(a.S, b.S); + CollectionAssert.AreNotEqual(a.S, a.S); + CollectionAssert.AreNotEqual(b.S, a.S); + CollectionAssert.Contains(a.S, a); + CollectionAssert.Contains(b.S, a.S); + CollectionAssert.Contains(a.S, a.S); + CollectionAssert.DoesNotContain(a.S, a); + CollectionAssert.DoesNotContain(b.S, a.S); + CollectionAssert.DoesNotContain(a.S, a.S); + CollectionAssert.AllItemsAreNotNull(a.S); + CollectionAssert.AllItemsAreUnique(a.S); + CollectionAssert.IsSubsetOf(a.S, b.S); + CollectionAssert.IsSubsetOf(a.S, a.S); + CollectionAssert.IsSubsetOf(b.S, a.S); + CollectionAssert.IsNotSubsetOf(a.S, b.S); + CollectionAssert.IsNotSubsetOf(a.S, a.S); + CollectionAssert.IsNotSubsetOf(b.S, a.S); + CollectionAssert.AllItemsAreInstancesOfType(a.S, b.T); + CollectionAssert.AllItemsAreInstancesOfType(a.S, a.T); + CollectionAssert.AllItemsAreInstancesOfType(b.S, a.T); + } + + [TestMethod] + public void Compliant() + { + A? a = new A(); + A b = new A(); + + Assert.IsNotNull(a); + CollectionAssert.AreEqual(a.S, b.S); + CollectionAssert.AreNotEqual(a.S, b.S); + CollectionAssert.Contains(a.S, a); + CollectionAssert.DoesNotContain(a.S, a); + CollectionAssert.AllItemsAreNotNull(a.S); + CollectionAssert.AllItemsAreUnique(a.S); + CollectionAssert.IsSubsetOf(a.S, b.S); + CollectionAssert.IsNotSubsetOf(a.S, b.S); + CollectionAssert.AllItemsAreInstancesOfType(a.S, a.T); + } + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + NumberOfFixAllIterations = 2, + NumberOfFixAllInDocumentIterations = 2, + NumberOfFixAllInProjectIterations = 2, + NumberOfIncrementalIterations = 30, + }.RunAsync(); } [TestMethod] @@ -333,6 +571,190 @@ public void Compliant() } """; - await VerifyCS.VerifyAnalyzerAsync(code); + string fixedCode = """ + #nullable enable + using System.Text.RegularExpressions; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + public class A + { + public string? S { get; set; } + public Regex? R { get; set; } + } + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void NonCompliant() + { + string s = ""; + Regex r = new Regex(""); + A? a = new A(); + A b = new A(); + Assert.IsNotNull(a); + StringAssert.Contains(a.S, s); + StringAssert.Contains(a.S, a.S); + StringAssert.Contains(b.S, a.S); + StringAssert.StartsWith(a.S, s); + StringAssert.StartsWith(a.S, a.S); + StringAssert.StartsWith(s, a.S); + StringAssert.EndsWith(a.S, s); + StringAssert.EndsWith(a.S, a.S); + StringAssert.EndsWith(s, a.S); + StringAssert.Matches(a.S, r); + StringAssert.Matches(a.S, a.R); + StringAssert.Matches(s, a.R); + StringAssert.DoesNotMatch(a.S, r); + StringAssert.DoesNotMatch(a.S, a.R); + StringAssert.DoesNotMatch(s, a.R); + } + + [TestMethod] + public void Compliant() + { + string s = ""; + Regex r = new Regex(""); + A? a = new A(); + A b = new A(); + + Assert.IsNotNull(a); + StringAssert.Contains(a.S, s); + StringAssert.Contains(a.S, a.S); + StringAssert.Contains(b.S, a.S); + StringAssert.StartsWith(a.S, s); + StringAssert.StartsWith(a.S, a.S); + StringAssert.StartsWith(s, a.S); + StringAssert.EndsWith(a.S, s); + StringAssert.EndsWith(a.S, a.S); + StringAssert.EndsWith(s, a.S); + StringAssert.Matches(a.S, r); + StringAssert.Matches(a.S, a.R); + StringAssert.Matches(s, a.R); + StringAssert.DoesNotMatch(a.S, r); + StringAssert.DoesNotMatch(a.S, a.R); + StringAssert.DoesNotMatch(s, a.R); + } + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + NumberOfFixAllIterations = 2, + NumberOfFixAllInDocumentIterations = 2, + NumberOfFixAllInProjectIterations = 2, + NumberOfIncrementalIterations = 20, + }.RunAsync(); + } + + [TestMethod] + public async Task WhenExpressionBody() + { + string code = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + public class MyClass + { + public MyClass A { get; set; } + public MyClass B { get; set; } + public MyClass C { get; set; } + public MyClass D { get; set; } + public MyClass E { get; set; } + public MyClass F { get; set; } + + public bool MyBool { get; set; } + } + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void Case1() // NOTE: No easy way for us to fix this properly + => [|Assert.IsTrue(new MyClass().A?.B.C?.D.E.MyBool)|]; + + [TestMethod] + public void Case2() // NOTE: No easy way for us to fix this properly + => [|Assert.IsTrue(new MyClass().A?.B.C.D.E.MyBool)|]; + } + """; + + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + public class MyClass + { + public MyClass A { get; set; } + public MyClass B { get; set; } + public MyClass C { get; set; } + public MyClass D { get; set; } + public MyClass E { get; set; } + public MyClass F { get; set; } + + public bool MyBool { get; set; } + } + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void Case1() // NOTE: No easy way for us to fix this properly + { + Assert.IsNotNull(new MyClass().A); + Assert.IsNotNull(new MyClass().A.B.C); + Assert.IsTrue(new MyClass().A.B.C.D.E.MyBool); + } + + [TestMethod] + public void Case2() // NOTE: No easy way for us to fix this properly + { + Assert.IsNotNull(new MyClass().A); + Assert.IsTrue(new MyClass().A.B.C.D.E.MyBool); + } + } + """; + + await new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + NumberOfFixAllIterations = 2, + NumberOfFixAllInDocumentIterations = 2, + NumberOfFixAllInProjectIterations = 2, + NumberOfIncrementalIterations = 3, + }.RunAsync(); + } + + [TestMethod] + public async Task WhenUsingConditionalsAccess_In_Message_NoDiagnostic() + { + string code = """ + #nullable enable + using System.Text.RegularExpressions; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + public class A + { + public string? S { get; set; } + public Regex? R { get; set; } + } + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void Compliant() + { + Assert.AreEqual(new object(), new object(), new A().S?.Length.ToString()); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, code); } } From e8edc352e84880a7bc9d3b23fe1eb2d14fa8f229 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Tue, 7 Jan 2025 20:43:49 +0100 Subject: [PATCH 239/273] Add messageBuilder overloads for Assert.Throws[Exactly][Async] (#4541) --- .../Assertions/Assert.ThrowsException.cs | 237 ++++++++++++++---- .../PublicAPI/PublicAPI.Unshipped.txt | 4 + .../AssertTests.ThrowsExceptionTests.cs | 176 +++++++++++++ 3 files changed, 368 insertions(+), 49 deletions(-) diff --git a/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs b/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs index 66efac037d..e6f380b084 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.ThrowsException.cs @@ -38,7 +38,7 @@ internal TException ComputeAssertion() } else { - return (TException)_state.ExceptionWhenNotFailing!; + return (TException)_state.ExceptionThrown!; } // This will not hit, but need it for compiler. @@ -105,7 +105,7 @@ internal TException ComputeAssertion() } else { - return (TException)_state.ExceptionWhenNotFailing!; + return (TException)_state.ExceptionThrown!; } // This will not hit, but need it for compiler. @@ -173,6 +173,30 @@ public static TException Throws(Action action, string message = "", where TException : Exception => ThrowsException(action, isStrictType: false, message, parameters: messageArgs); + /// + /// Asserts that the delegate throws an exception of type + /// (or derived type) and throws AssertFailedException if code does not throws exception or throws + /// exception of type other than . + /// + /// + /// Delegate to code to be tested and which is expected to throw exception. + /// + /// + /// A func that takes the thrown Exception (or null if the action didn't throw any exception) to construct the message to include in the exception when does not throws exception of type . + /// + /// + /// The type of exception expected to be thrown. + /// + /// + /// Thrown if does not throws exception of type . + /// + /// + /// The exception that was thrown. + /// + public static TException Throws(Action action, Func messageBuilder) + where TException : Exception + => ThrowsException(action, isStrictType: false, messageBuilder); + /// #pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 public static TException Throws(Action action, [InterpolatedStringHandlerArgument(nameof(action))] ref AssertNonStrictThrowsInterpolatedStringHandler message) @@ -207,6 +231,30 @@ public static TException ThrowsExactly(Action action, string message where TException : Exception => ThrowsException(action, isStrictType: true, message, parameters: messageArgs); + /// + /// Asserts that the delegate throws an exception of type + /// (and not of derived type) and throws AssertFailedException if code does not throws exception or throws + /// exception of type other than . + /// + /// + /// Delegate to code to be tested and which is expected to throw exception. + /// + /// + /// A func that takes the thrown Exception (or null if the action didn't throw any exception) to construct the message to include in the exception when does not throws exception of type . + /// + /// + /// The type of exception expected to be thrown. + /// + /// + /// Thrown if does not throws exception of type . + /// + /// + /// The exception that was thrown. + /// + public static TException ThrowsExactly(Action action, Func messageBuilder) + where TException : Exception + => ThrowsException(action, isStrictType: true, messageBuilder); + /// #pragma warning disable IDE0060 // Remove unused parameter - https://github.com/dotnet/roslyn/issues/76578 public static TException ThrowsExactly(Action action, [InterpolatedStringHandlerArgument(nameof(action))] ref AssertThrowsExactlyInterpolatedStringHandler message) @@ -384,7 +432,27 @@ private static TException ThrowsException(Action action, bool isStri } else { - return (TException)state.ExceptionWhenNotFailing!; + return (TException)state.ExceptionThrown!; + } + + // This will not hit, but need it for compiler. + return null!; + } + + private static TException ThrowsException(Action action, bool isStrictType, Func messageBuilder, [CallerMemberName] string assertMethodName = "") + where TException : Exception + { + Guard.NotNull(action); + Guard.NotNull(messageBuilder); + + ThrowsExceptionState state = IsThrowsFailing(action, isStrictType, assertMethodName); + if (state.FailAction is not null) + { + state.FailAction(messageBuilder(state.ExceptionThrown)); + } + else + { + return (TException)state.ExceptionThrown!; } // This will not hit, but need it for compiler. @@ -445,6 +513,54 @@ public static Task ThrowsExactlyAsync(Func action, where TException : Exception => ThrowsExceptionAsync(action, isStrictType: true, message, parameters: messageArgs); + /// + /// Asserts that the delegate throws an exception of type + /// (or derived type) and throws AssertFailedException if code does not throws exception or throws + /// exception of type other than . + /// + /// + /// Delegate to code to be tested and which is expected to throw exception. + /// + /// + /// A func that takes the thrown Exception (or null if the action didn't throw any exception) to construct the message to include in the exception when does not throws exception of type . + /// + /// + /// The type of exception expected to be thrown. + /// + /// + /// Thrown if does not throws exception of type . + /// + /// + /// The exception that was thrown. + /// + public static Task ThrowsAsync(Func action, Func messageBuilder) + where TException : Exception + => ThrowsExceptionAsync(action, isStrictType: false, messageBuilder); + + /// + /// Asserts that the delegate throws an exception of type + /// (and not of derived type) and throws AssertFailedException if code does not throws exception or throws + /// exception of type other than . + /// + /// + /// Delegate to code to be tested and which is expected to throw exception. + /// + /// + /// A func that takes the thrown Exception (or null if the action didn't throw any exception) to construct the message to include in the exception when does not throws exception of type . + /// + /// + /// The type of exception expected to be thrown. + /// + /// + /// Thrown if does not throws exception of type . + /// + /// + /// The exception that was thrown. + /// + public static Task ThrowsExactlyAsync(Func action, Func messageBuilder) + where TException : Exception + => ThrowsExceptionAsync(action, isStrictType: true, messageBuilder); + /// /// Tests whether the code specified by delegate throws exact given exception /// of type (and not of derived type) and throws AssertFailedException @@ -530,7 +646,27 @@ private static async Task ThrowsExceptionAsync(Func ThrowsExceptionAsync(Func action, bool isStrictType, Func messageBuilder, [CallerMemberName] string assertMethodName = "") + where TException : Exception + { + Guard.NotNull(action); + Guard.NotNull(messageBuilder); + + ThrowsExceptionState state = await IsThrowsAsyncFailingAsync(action, isStrictType, assertMethodName).ConfigureAwait(false); + if (state.FailAction is not null) + { + state.FailAction(messageBuilder(state.ExceptionThrown)); + } + else + { + return (TException)state.ExceptionThrown!; } // This will not hit, but need it for compiler. @@ -552,27 +688,29 @@ private static async Task IsThrowsAsyncFailingAsync - { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.WrongExceptionThrown, - userMessage, - typeof(TException), - ex.GetType()); - ThrowAssertFailed("Assert." + assertMethodName, finalMessage); - }); + : ThrowsExceptionState.CreateFailingState( + userMessage => + { + string finalMessage = string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.WrongExceptionThrown, + userMessage, + typeof(TException), + ex.GetType()); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + }, ex); } - return ThrowsExceptionState.CreateFailingState(failAction: userMessage => - { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.NoExceptionThrown, - userMessage, - typeof(TException)); - ThrowAssertFailed("Assert." + assertMethodName, finalMessage); - }); + return ThrowsExceptionState.CreateFailingState( + failAction: userMessage => + { + string finalMessage = string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.NoExceptionThrown, + userMessage, + typeof(TException)); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + }, null); } private static ThrowsExceptionState IsThrowsFailing(Action action, bool isStrictType, string assertMethodName) @@ -590,46 +728,47 @@ private static ThrowsExceptionState IsThrowsFailing(Action action, b return isExceptionOfType ? ThrowsExceptionState.CreateNotFailingState(ex) - : ThrowsExceptionState.CreateFailingState(userMessage => - { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.WrongExceptionThrown, - userMessage, - typeof(TException), - ex.GetType()); - ThrowAssertFailed("Assert." + assertMethodName, finalMessage); - }); + : ThrowsExceptionState.CreateFailingState( + userMessage => + { + string finalMessage = string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.WrongExceptionThrown, + userMessage, + typeof(TException), + ex.GetType()); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + }, ex); } - return ThrowsExceptionState.CreateFailingState(failAction: userMessage => - { - string finalMessage = string.Format( - CultureInfo.CurrentCulture, - FrameworkMessages.NoExceptionThrown, - userMessage, - typeof(TException)); - ThrowAssertFailed("Assert." + assertMethodName, finalMessage); - }); + return ThrowsExceptionState.CreateFailingState( + failAction: userMessage => + { + string finalMessage = string.Format( + CultureInfo.CurrentCulture, + FrameworkMessages.NoExceptionThrown, + userMessage, + typeof(TException)); + ThrowAssertFailed("Assert." + assertMethodName, finalMessage); + }, null); } private readonly struct ThrowsExceptionState { - public Exception? ExceptionWhenNotFailing { get; } + public Exception? ExceptionThrown { get; } public Action? FailAction { get; } - private ThrowsExceptionState(Exception? exceptionWhenNotFailing, Action? failAction) + private ThrowsExceptionState(Exception? exceptionThrown, Action? failAction) { - // If the assert is failing, failAction should be non-null, and exceptionWhenNotFailing should be null. + // If the assert is failing, failAction should be non-null, and exceptionWhenNotFailing may or may not be null. // If the assert is not failing, exceptionWhenNotFailing should be non-null, and failAction should be null. - Debug.Assert(exceptionWhenNotFailing is null ^ failAction is null, "Exactly one of exceptionWhenNotFailing and failAction should be null."); - ExceptionWhenNotFailing = exceptionWhenNotFailing; + ExceptionThrown = exceptionThrown; FailAction = failAction; } - public static ThrowsExceptionState CreateFailingState(Action failAction) - => new(exceptionWhenNotFailing: null, failAction); + public static ThrowsExceptionState CreateFailingState(Action failAction, Exception? exceptionThrown) + => new(exceptionThrown, failAction); public static ThrowsExceptionState CreateNotFailingState(Exception exception) => new(exception, failAction: null); diff --git a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt index ff0c658919..01ad108d22 100644 --- a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt +++ b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt @@ -239,7 +239,11 @@ static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool condition static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.IsTrue(bool? condition, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertIsTrueInterpolatedStringHandler message) -> void static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Throws(System.Action! action, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertNonStrictThrowsInterpolatedStringHandler message) -> TException! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Throws(System.Action! action, string! message = "", params object![]! messageArgs) -> TException! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Throws(System.Action! action, System.Func! messageBuilder) -> TException! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsAsync(System.Func! action, string! message = "", params object![]! messageArgs) -> System.Threading.Tasks.Task! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsAsync(System.Func! action, System.Func! messageBuilder) -> System.Threading.Tasks.Task! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactly(System.Action! action, ref Microsoft.VisualStudio.TestTools.UnitTesting.Assert.AssertThrowsExactlyInterpolatedStringHandler message) -> TException! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactly(System.Action! action, string! message = "", params object![]! messageArgs) -> TException! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactly(System.Action! action, System.Func! messageBuilder) -> TException! static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactlyAsync(System.Func! action, string! message = "", params object![]! messageArgs) -> System.Threading.Tasks.Task! +static Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactlyAsync(System.Func! action, System.Func! messageBuilder) -> System.Threading.Tasks.Task! diff --git a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs index 74aa52e347..66202bd2da 100644 --- a/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs +++ b/test/UnitTests/TestFramework.UnitTests/Assertions/AssertTests.ThrowsExceptionTests.cs @@ -235,4 +235,180 @@ public void ThrowsExactlyAsync_WhenExceptionIsDerivedFromExpectedType_ShouldThro public async Task ThrowsExactlyAsync_WhenExceptionExpectedType_ShouldNotThrow() => await Assert.ThrowsExactlyAsync(() => throw new ArgumentNullException()); + + public void Throws_WithMessageBuilder_Passes() + { + bool wasBuilderCalled = false; + Assert.Throws(() => throw new ArgumentNullException(), messageBuilder: _ => + { + wasBuilderCalled = true; + return "message constructed via builder."; + }); + + Verify(!wasBuilderCalled); + } + + public void Throws_WithMessageBuilder_FailsBecauseNoException() + { + bool wasBuilderCalled = false; + Exception exceptionPassedToBuilder = null; + AssertFailedException assertFailedEx = VerifyThrows(() => Assert.Throws(() => { }, messageBuilder: ex => + { + wasBuilderCalled = true; + exceptionPassedToBuilder = ex; + return "message constructed via builder."; + })); + + Verify(wasBuilderCalled); + Verify(exceptionPassedToBuilder is null); + Verify(assertFailedEx.Message == "Assert.Throws failed. Expected exception type: but no exception was thrown. message constructed via builder."); + } + + public void Throws_WithMessageBuilder_FailsBecauseTypeMismatch() + { + bool wasBuilderCalled = false; + Exception exceptionPassedToBuilder = null; + AssertFailedException assertFailedEx = VerifyThrows(() => Assert.Throws(() => throw new ArgumentOutOfRangeException("MyParamNameHere"), messageBuilder: ex => + { + wasBuilderCalled = true; + exceptionPassedToBuilder = ex; + return "message constructed via builder."; + })); + + Verify(wasBuilderCalled); + Verify(exceptionPassedToBuilder is ArgumentOutOfRangeException { ParamName: "MyParamNameHere" }); + Verify(assertFailedEx.Message == "Assert.Throws failed. Expected exception type:. Actual exception type:. message constructed via builder."); + } + + public void ThrowsExactly_WithMessageBuilder_Passes() + { + bool wasBuilderCalled = false; + Assert.ThrowsExactly(() => throw new ArgumentNullException(), messageBuilder: _ => + { + wasBuilderCalled = true; + return "message constructed via builder."; + }); + + Verify(!wasBuilderCalled); + } + + public void ThrowsExactly_WithMessageBuilder_FailsBecauseNoException() + { + bool wasBuilderCalled = false; + Exception exceptionPassedToBuilder = null; + AssertFailedException assertFailedEx = VerifyThrows(() => Assert.ThrowsExactly(() => { }, messageBuilder: ex => + { + wasBuilderCalled = true; + exceptionPassedToBuilder = ex; + return "message constructed via builder."; + })); + + Verify(wasBuilderCalled); + Verify(exceptionPassedToBuilder is null); + Verify(assertFailedEx.Message == "Assert.ThrowsExactly failed. Expected exception type: but no exception was thrown. message constructed via builder."); + } + + public void ThrowsExactly_WithMessageBuilder_FailsBecauseTypeMismatch() + { + bool wasBuilderCalled = false; + Exception exceptionPassedToBuilder = null; + AssertFailedException assertFailedEx = VerifyThrows(() => Assert.ThrowsExactly(() => throw new ArgumentOutOfRangeException("MyParamNameHere"), messageBuilder: ex => + { + wasBuilderCalled = true; + exceptionPassedToBuilder = ex; + return "message constructed via builder."; + })); + + Verify(wasBuilderCalled); + Verify(exceptionPassedToBuilder is ArgumentOutOfRangeException { ParamName: "MyParamNameHere" }); + Verify(assertFailedEx.Message == "Assert.ThrowsExactly failed. Expected exception type:. Actual exception type:. message constructed via builder."); + } + + public async Task ThrowsAsync_WithMessageBuilder_Passes() + { + bool wasBuilderCalled = false; + await Assert.ThrowsAsync(() => Task.FromException(new ArgumentNullException()), messageBuilder: _ => + { + wasBuilderCalled = true; + return "message constructed via builder."; + }); + + Verify(!wasBuilderCalled); + } + + public async Task ThrowsAsync_WithMessageBuilder_FailsBecauseNoException() + { + bool wasBuilderCalled = false; + Exception exceptionPassedToBuilder = null; + AssertFailedException assertFailedEx = await VerifyThrowsAsync(async () => await Assert.ThrowsAsync(() => Task.CompletedTask, messageBuilder: ex => + { + wasBuilderCalled = true; + exceptionPassedToBuilder = ex; + return "message constructed via builder."; + })); + + Verify(wasBuilderCalled); + Verify(exceptionPassedToBuilder is null); + Verify(assertFailedEx.Message == "Assert.ThrowsAsync failed. Expected exception type: but no exception was thrown. message constructed via builder."); + } + + public async Task ThrowsAsync_WithMessageBuilder_FailsBecauseTypeMismatch() + { + bool wasBuilderCalled = false; + Exception exceptionPassedToBuilder = null; + AssertFailedException assertFailedEx = await VerifyThrowsAsync(async () => await Assert.ThrowsAsync(() => Task.FromException(new ArgumentOutOfRangeException("MyParamNameHere")), messageBuilder: ex => + { + wasBuilderCalled = true; + exceptionPassedToBuilder = ex; + return "message constructed via builder."; + })); + + Verify(wasBuilderCalled); + Verify(exceptionPassedToBuilder is ArgumentOutOfRangeException { ParamName: "MyParamNameHere" }); + Verify(assertFailedEx.Message == "Assert.ThrowsAsync failed. Expected exception type:. Actual exception type:. message constructed via builder."); + } + + public async Task ThrowsExactlyAsync_WithMessageBuilder_Passes() + { + bool wasBuilderCalled = false; + await Assert.ThrowsExactlyAsync(() => Task.FromException(new ArgumentNullException()), messageBuilder: _ => + { + wasBuilderCalled = true; + return "message constructed via builder."; + }); + + Verify(!wasBuilderCalled); + } + + public async Task ThrowsExactlyAsync_WithMessageBuilder_FailsBecauseNoException() + { + bool wasBuilderCalled = false; + Exception exceptionPassedToBuilder = null; + AssertFailedException assertFailedEx = await VerifyThrowsAsync(async () => await Assert.ThrowsExactlyAsync(() => Task.CompletedTask, messageBuilder: ex => + { + wasBuilderCalled = true; + exceptionPassedToBuilder = ex; + return "message constructed via builder."; + })); + + Verify(wasBuilderCalled); + Verify(exceptionPassedToBuilder is null); + Verify(assertFailedEx.Message == "Assert.ThrowsExactlyAsync failed. Expected exception type: but no exception was thrown. message constructed via builder."); + } + + public async Task ThrowsExactlyAsync_WithMessageBuilder_FailsBecauseTypeMismatch() + { + bool wasBuilderCalled = false; + Exception exceptionPassedToBuilder = null; + AssertFailedException assertFailedEx = await VerifyThrowsAsync(async () => await Assert.ThrowsExactlyAsync(() => Task.FromException(new ArgumentOutOfRangeException("MyParamNameHere")), messageBuilder: ex => + { + wasBuilderCalled = true; + exceptionPassedToBuilder = ex; + return "message constructed via builder."; + })); + + Verify(wasBuilderCalled); + Verify(exceptionPassedToBuilder is ArgumentOutOfRangeException { ParamName: "MyParamNameHere" }); + Verify(assertFailedEx.Message == "Assert.ThrowsExactlyAsync failed. Expected exception type:. Actual exception type:. message constructed via builder."); + } } From 8a7a75c6677de0b6a25ed071c2c345d01b704972 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:09:47 +0100 Subject: [PATCH 240/273] [main] Update dependencies from microsoft/testanywhere (#4554) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 4 ++-- eng/Versions.props | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 547087c481..22787098d4 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -17,9 +17,9 @@ https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage 3889f929bc86d4f819c62bfa687b01660c9e195d - + https://github.com/microsoft/testanywhere - 9321d81962123d9c9d624d35a7dff1d1cea09da1 + 712ed1a92cec839ca106e0ffdfd134b05925f1ad diff --git a/eng/Versions.props b/eng/Versions.props index 84e71f60e5..6becc094b3 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -10,6 +10,6 @@ 10.0.0-beta.24604.4 17.14.0-preview.25056.1 - 1.0.0-alpha.25056.3 + 1.0.0-alpha.25056.4 From 6d3b7ce17efba5d17f561cc21ee061fb2bd4c8b0 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 8 Jan 2025 02:50:33 -0800 Subject: [PATCH 241/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2615514 (#4557) --- .../xlf/CodeFixResources.es.xlf | 2 +- .../xlf/CodeFixResources.fr.xlf | 2 +- .../xlf/CodeFixResources.it.xlf | 2 +- .../xlf/CodeFixResources.ja.xlf | 2 +- .../xlf/CodeFixResources.pl.xlf | 2 +- .../xlf/CodeFixResources.pt-BR.xlf | 2 +- .../xlf/CodeFixResources.tr.xlf | 2 +- .../xlf/CodeFixResources.zh-Hant.xlf | 2 +- .../MSTest.Analyzers/xlf/Resources.cs.xlf | 10 +++++----- .../MSTest.Analyzers/xlf/Resources.de.xlf | 14 +++++++------- .../MSTest.Analyzers/xlf/Resources.es.xlf | 14 +++++++------- .../MSTest.Analyzers/xlf/Resources.fr.xlf | 14 +++++++------- .../MSTest.Analyzers/xlf/Resources.it.xlf | 14 +++++++------- .../MSTest.Analyzers/xlf/Resources.ja.xlf | 10 +++++----- .../MSTest.Analyzers/xlf/Resources.ko.xlf | 10 +++++----- .../MSTest.Analyzers/xlf/Resources.pl.xlf | 14 +++++++------- .../MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 10 +++++----- .../MSTest.Analyzers/xlf/Resources.ru.xlf | 14 +++++++------- .../MSTest.Analyzers/xlf/Resources.tr.xlf | 14 +++++++------- .../MSTest.Analyzers/xlf/Resources.zh-Hans.xlf | 10 +++++----- .../MSTest.Analyzers/xlf/Resources.zh-Hant.xlf | 14 +++++++------- 21 files changed, 89 insertions(+), 89 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf index 737bcf868b..d713d9bc90 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + Usar "{0}" diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf index 1b77f40977..52703c000f 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + Utiliser « {0} » diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf index 2523dff190..01427c605a 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + Usare ‘{0}’ diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf index 4582255692..84c5786c5c 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + '{0}' を使用する diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf index f3e5a06292..da8b0630df 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + Użyj „{0}” diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf index 78e947879a..0da76f1ca5 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + Usar "{0}" diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf index 1cb3982db4..725162bebe 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + '{0}' kullan diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf index 520e49868b..92274ff135 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + 使用 '{0}' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index c60c29b4e4..67e36132ae 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -119,17 +119,17 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Při porovnávání typů hodnot použijte Assert.AreEqual/Assert.AreNotEqual místo Assert.AreSame/Assert.AreNotSame. Předání typu hodnoty do assert.AreSame/Assert.AreNotSame bude zabaleno (vytváření nového objektu). Protože Assert.AreSame/Assert.AreNotSame provádí porovnání podle odkazu, Assert.AreSame selže, když dojde k zabalení, a Assert.AreNotSame vždy proběhne. Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + Při porovnávání typů hodnot použít '{0}' místo '{1}' Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Nepoužívejte Assert.AreSame ani Assert.AreNotSame s typy hodnot. @@ -741,12 +741,12 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Místo Assert.ThrowsException použijte Assert.ThrowsExactly. Use newer methods to assert exceptions - Use newer methods to assert exceptions + Pro vyhodnocení výjimek použijte novější metody. diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf index 9cc523aba8..9f9b3db605 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf @@ -119,27 +119,27 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Verwenden Sie beim Vergleichen von Werttypen "Assert.AreEqual"/"Assert.AreNotEqual" anstelle von "Assert.AreSame"/"Assert.AreNotSame". Das Übergeben eines Werttyps an "Assert.AreSame"/"Assert.AreNotSame" wird geschachtelt (ein neues Objekt wird erstellt). Da "Assert.AreSame"/"Assert.AreNotSame" den Vergleich als Verweis führt, tritt bei "Assert.AreSame" beim Boxing ein Fehler auf, und "Assert.AreNotSame" wird immer übergeben. Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + Beim Vergleichen von Werttypen '{0}' anstelle von '{1}' verwenden Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Verwenden Sie "Assert.AreSame" oder "Assert.AreNotSame" nicht mit Werttypen. Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + „Assert.ThrowsExactly“ oder „Assert.ThrowsExactlyAsync“ gegenüber „[ExpectedException]“ bevorzugen, da dadurch sichergestellt wird, dass nur der erwartete Aufruf die erwartete Ausnahme auslöst. Die Assert-APIs bieten außerdem mehr Flexibilität und ermöglichen es Ihnen, zusätzliche Eigenschaften der Ausführung zu bestätigen. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + „Assert.ThrowsExactly/ThrowsExactlyAsync“ gegenüber „[ExpectedException]“ bevorzugen @@ -742,12 +742,12 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Verwenden Sie "Assert.ThrowsExactly" anstelle von "Assert.ThrowsException". Use newer methods to assert exceptions - Use newer methods to assert exceptions + Neuere Methoden zum Bestätigen von Ausnahmen verwenden diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf index 996d9692f5..1f9b00a97f 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf @@ -119,27 +119,27 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' en lugar de 'Assert.AreSame'/'Assert.AreNotSame' al comparar tipos de valor. Al pasar un tipo de valor a 'Assert.AreSame'/'Assert.AreNotSame', se aplicará la conversión boxing (creando un nuevo objeto). Dado que 'Assert.AreSame'/'Assert.AreNotSame' realiza la comparación por referencia, 'Assert.AreSame' producirá un error cuando se produzca una conversión boxing y 'Assert.AreNotSame' pasará siempre. Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + Usar '{0}' en lugar de '{1}' al comparar tipos de valor Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + No use "Assert.AreSame" o "Assert.AreNotSame" con tipos de valor Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Preferir "Assert.ThrowsExactly" o "Assert.ThrowsExactlyAsync" en lugar de "[ExpectedException]", ya que garantiza que solo la llamada esperada inicie la excepción esperada. Las API de aserción también proporcionan más flexibilidad y permiten declarar propiedades adicionales de la ejecución. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Preferir "Assert.ThrowsExactly/ThrowsExactlyAsync" en lugar de "[ExpectedException]" @@ -741,12 +741,12 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes: Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Usar "Assert.ThrowsExactly" en lugar de "Assert.ThrowsException" Use newer methods to assert exceptions - Use newer methods to assert exceptions + Usar métodos más recientes para declarar excepciones diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf index 01226f80cd..e89cfa1e60 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf @@ -119,27 +119,27 @@ Le type doit être une classe Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Utilisez 'Assert.AreEqual'/'Assert.AreNotEqual' à la place de 'Assert.AreSame'/'Assert.AreNotSame' lors de la comparaison des types valeur. Le passage d’un type valeur à 'Assert.AreSame'/'Assert.AreNotSame' est encadré (création d’un objet). Dans la mesure où 'Assert.AreSame'/'Assert.AreNotSame' effectue la comparaison par référence, 'Assert.AreSame' échoue quand le boxing se produit et 'Assert.AreNotSame' passe toujours. Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + Utiliser '{0}' au lieu de '{1}' lors de la comparaison de types valeur Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + N’utilisez pas 'Assert.AreSame' ou 'Assert.AreNotSame' avec des types valeur Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Préférez « Assert.ThrowsExactly » ou « Assert.ThrowsExactlyAsync » à « [ExpectedException] », car il garantit que seul l’appel attendu lève l’exception attendue. Les API d’assertion offrent également plus de flexibilité et vous permettent de déclarer des propriétés supplémentaires de l’exception. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Préférez « Assert.ThrowsExactly/ThrowsExactlyAsync » à « [ExpectedException] » @@ -741,12 +741,12 @@ Le type doit être une classe Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Utiliser 'Assert.ThrowsExactly' à la place de 'Assert.ThrowsException' Use newer methods to assert exceptions - Use newer methods to assert exceptions + Utiliser des méthodes plus nouvelles pour déclarer des exceptions diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf index 12d9d9f98b..717fc30523 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf @@ -119,27 +119,27 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Usare 'Assert.AreEqual'/'Assert.AreNotEqual' invece di 'Assert.AreSame'/'Assert.AreNotSame' durante il confronto dei tipi valore. Se si passa un tipo valore a 'Assert.AreSame'/'Assert.AreNotSame', verrà eseguito il boxing (creazione di un nuovo oggetto). Poiché 'Assert.AreSame'/'Assert.AreNotSame' esegue il confronto per riferimento, 'Assert.AreSame' non riuscirà quando si esegue la boxing e 'Assert.AreNotSame' passerà sempre. Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + Usa '{0}' invece di '{1}' durante il confronto dei tipi di valore Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Non usare 'Assert.AreSame' o 'Assert.AreNotSame' con i tipi di valore Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Preferire 'Assert.ThrowsExactly' o 'Assert.ThrowsExactlyAsync' a '[ExpectedException]' perché assicura che solo la chiamata prevista generi l'eccezione prevista. Le API di asserzione offrono anche maggiore flessibilità e consentono di dichiarare proprietà aggiuntive dell'eccezione. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Preferire 'Assert.ThrowsExactly/ThrowsExactlyAsync' a '[ExpectedException]' @@ -741,12 +741,12 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti: Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Usare 'Assert.ThrowsExactly' invece di 'Assert.ThrowsException' Use newer methods to assert exceptions - Use newer methods to assert exceptions + Usa metodi più recenti per dichiarare le eccezioni diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index ffc18100c0..2c47350396 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -119,17 +119,17 @@ The type declaring these methods should also respect the following rules: Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + 値の型を比較するときは、'Assert.AreSame'/'Assert.AreNotSame' の代わりに 'Assert.AreEqual'/'Assert.AreNotEqual' を使用してください。値の型を 'Assert.AreSame'/'Assert.AreNotSame' に渡すとボックス化されます (新しいオブジェクトが作成されます)。'Assert.AreSame'/'Assert.AreNotSame' は参照による比較を行うため、ボックス化が発生すると 'Assert.AreSame' は失敗し、'Assert.AreNotSame' は常に渡されます。 Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + 値の型を比較するときに '{1}' の代わりに '{0}' を使用する Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + 値型に 'Assert.AreSame' または 'Assert.AreNotSame' を使用しないでください @@ -741,12 +741,12 @@ The type declaring these methods should also respect the following rules: Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + 'Assert.ThrowsException' の代わりに 'Assert.ThrowsExactly' を使用する Use newer methods to assert exceptions - Use newer methods to assert exceptions + 新しいメソッドを使用して例外をアサートする diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 531a88169e..60db122201 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -119,17 +119,17 @@ The type declaring these methods should also respect the following rules: Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + 값 형식을 비교할 때 'Assert.AreSame'/'Assert.AreNotSame' 대신 'Assert.AreEqual'/'Assert.AreNotEqual'을 사용합니다. 값 형식을 'Assert.AreSame'/'Assert.AreNotSame'에 전달하면 boxed(새 개체 만들기)됩니다. 'Assert.AreSame'/'Assert.AreNotSame'은 참조로 비교하므로 boxing이 발생할 때 'Assert.AreSame'이 실패하고 'Assert.AreNotSame'이 항상 전달됩니다. Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + 값 형식을 비교할 때 '{1}' 대신 '{0}' 사용 Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + 값 형식에 'Assert.AreSame' 또는 'Assert.AreNotSame'을 사용하지 마세요. @@ -741,12 +741,12 @@ The type declaring these methods should also respect the following rules: Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + 'Assert.ThrowsException' 대신 'Assert.ThrowsExactly' 사용 Use newer methods to assert exceptions - Use newer methods to assert exceptions + 최신 메서드를 사용하여 예외 어설션 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf index 6ab6c394a6..842e9f1974 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf @@ -119,27 +119,27 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Użyj metody Assert.AreEqual'/'Assert.AreNotEqual' zamiast assert.AreSame'/'Assert.AreNotSame' podczas porównywania typów wartości. Przekazanie typu wartości do elementu "Assert.AreSame"/"Assert.AreNotSame" zostanie opakowane (tworzenie nowego obiektu). Ponieważ funkcja "Assert.AreSame"/"Assert.AreNotSame" wykonuje porównanie przez referencję, operacja "Assert.AreSame" zakończy się niepowodzeniem, gdy nastąpi konwersja boxing, a element "Assert.AreNotSame" zawsze przejdzie. Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + Użyj '{0}' zamiast '{1}' podczas porównywania typów wartości Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Nie używaj elementu "Assert.AreSame" ani "Assert.AreNotSame" z typami wartości Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Preferuj opcję „Assert.ThrowsExactly” lub „Assert.ThrowsExactlyAsync” zamiast „[ExpectedException]”, ponieważ gwarantuje ona, że tylko oczekiwane wywołanie rzuci oczekiwany wyjątek. Interfejsy API potwierdzenia zapewniają również większą elastyczność i pozwalają na potwierdzenie dodatkowych właściwości wyjątku. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Preferuj opcję „Assert.ThrowsExactly/ThrowsExactlyAsync” zamiast „[ExpectedException]” @@ -741,12 +741,12 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Użyj metody "Assert.ThrowsExactly" zamiast elementu "Assert.ThrowsException" Use newer methods to assert exceptions - Use newer methods to assert exceptions + Użyj nowszych metod, aby potwierdzić wyjątki diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index b925314554..6f569d1da9 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -119,17 +119,17 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Use 'Assert.AreEqual'/'Assert.AreNotEqual' em vez de 'Assert.AreSame'/'Assert.AreNotSame' ao comparar tipos de valor. Passar um tipo de valor para 'Assert.AreSame'/'Assert.AreNotSame' será em caixa (criando um novo objeto). Como 'Assert.AreSame'/'Assert.AreNotSame' faz a comparação por referência, 'Assert.AreSame' falhará quando ocorrer boxing e 'Assert.AreNotSame' sempre será aprovado. Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + Usar '{0}' em vez de '{1}' ao comparar tipos de valor Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Não use 'Assert.AreSame' ou 'Assert.AreNotSame' com tipos de valor @@ -741,12 +741,12 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Usar 'Assert.ThrowsExactly' em vez de 'Assert.ThrowsException' Use newer methods to assert exceptions - Use newer methods to assert exceptions + Usar métodos mais recentes para declarar exceções diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf index 3f928ddb39..05d8602608 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf @@ -122,27 +122,27 @@ The type declaring these methods should also respect the following rules: Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + При сравнении типов значений используйте "Assert.AreEqual"/"Assert.AreNotEqual" вместо "Assert.AreSame"/"Assert.AreNotSame". Передача типа значения в "Assert.AreSame"/"Assert.AreNotSame" будет добавлена в рамку (создание нового объекта). Поскольку "Assert.AreSame"/"Assert.AreNotSame" выполняет сравнение по ссылке, при боксе "Assert.AreSame" будет выполняться с ошибкой, а "Assert.AreNotSame" всегда будет проходить. Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + Использовать '{0}' вместо '{1}' при сравнении типов значений Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Не используйте Assert.AreSame или Assert.AreNotSame с типами значений Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Предпочтите "Assert.ThrowsExactly' или 'Assert.ThrowsExactlyAsync" вместо "[ExpectedException]", так как это гарантирует, что только ожидаемый вызов вызовет ожидаемое исключение. API-интерфейсы утверждения также обеспечивают дополнительную гибкость и позволяют утверждать дополнительные свойства исключения. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Предпочтите "Assert.ThrowsExactly/ThrowsExactlyAsync" вместо "[ExpectedException]" @@ -753,12 +753,12 @@ The type declaring these methods should also respect the following rules: Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + Используйте Assert.ThrowsExactly вместо Assert.ThrowsException Use newer methods to assert exceptions - Use newer methods to assert exceptions + Использовать более новые методы для утверждения исключений diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf index 7356ec4368..4c2b557734 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf @@ -119,27 +119,27 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + Değer türlerini karşılaştırılırken 'Assert.AreSame'/'Assert.AreNotSame' yerine 'Assert.AreEqual'/'Assert.AreNotSame' kullanın. 'Assert.AreSame'/'Assert.AreNotSame' değerine bir değer türü geçirilemedi (yeni bir nesne oluşturuluyor). 'Assert.AreSame'/'Assert.AreNotSame' başvuruya göre karşılaştırmayı yapar, kutulama gerçekleşirken 'Assert.AreSame' başarısız olur ve 'Assert.AreNotSame' her zaman başarılı olur. Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + Değer '{0}' karşılaştırılırken '{1}' yerine farklı bir ad kullanın Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + Değer türleriyle 'Assert.AreSame' veya 'Assert.AreNotSame' kullanma Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Yalnızca beklenen çağrının beklenen özel durumu oluşturmasını sağladığı için '[ExpectedException]' yerine 'Assert.ThrowsExactly' veya 'Assert.ThrowsExceptionAsync' tercih edin. Onaylama API'leri de daha fazla esneklik sağlar ve özel durumun ek özelliklerini onaylamanıza izin verir. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + '[ExpectedException]' yerine 'Assert.ThrowsExactly/ThrowsExactlyAsync' tercih edin @@ -743,12 +743,12 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir: Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + 'Assert.ThrowsException' yerine 'Assert.ThrowsExactly' kullanın Use newer methods to assert exceptions - Use newer methods to assert exceptions + Özel durumları onaylamak için daha yeni yöntemler kullanın diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index 973ce34145..fad2c8e4e5 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -119,17 +119,17 @@ The type declaring these methods should also respect the following rules: Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + 比较值类型时,请使用 “Assert.AreEqual”/“Assert.AreNotEqual” 而不是 “Assert.AreSame”/“Assert.AreNotSame”。将值类型传递给 “Assert.AreSame”/“Assert.AreNotSame”将装箱 (创建新的对象)。由于 'Assert.AreSame'/'Assert.AreNotSame' 按引用进行比较,所以当装箱发生时,“Assert.AreSame” 将失败,并且 “Assert.AreNotSame” 将始终通过。 Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + 比较值类型时使用 '{0}' 而不是 '{1}' Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + 不要将 “Assert.AreSame” 或 “Assert.AreNotSame” 与值类型一起使用 @@ -741,12 +741,12 @@ The type declaring these methods should also respect the following rules: Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + 使用 “Assert.ThrowsExactly” 而不是 “Assert.ThrowsException” Use newer methods to assert exceptions - Use newer methods to assert exceptions + 使用较新的方法断言异常 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf index 0a544e82bb..125e6a1d2b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf @@ -119,27 +119,27 @@ The type declaring these methods should also respect the following rules: Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. - Use 'Assert.AreEqual'/'Assert.AreNotEqual' instead of 'Assert.AreSame'/'Assert.AreNotSame' when comparing value types. Passing a value type to 'Assert.AreSame'/'Assert.AreNotSame' will be boxed (creating a new object). Because 'Assert.AreSame'/'Assert.AreNotSame' does the comparison by reference, 'Assert.AreSame' will fail when boxing happens, and 'Assert.AreNotSame' will always pass. + 比較值類型時,請使用 'Assert.AreEqual'/'Assert.AreNotEqual' 取代 'Assert.AreSame'/'Assert.AreNotSame'。將值類型傳遞至 『Assert.AreSame』/'Assert.AreNotSame' 將會在建立新物件) (方塊化。因為 'Assert.AreSame'/'Assert.AreNotSame' 依參照進行比較,當進行拳擊時,'Assert.AreSame' 將會失敗,而且 'Assert.AreNotSame' 一律會通過。 Use '{0}' instead of '{1}' when comparing value types - Use '{0}' instead of '{1}' when comparing value types + 比較值類型時,使用 '{0}' 而非 '{1}' Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types - Don't use 'Assert.AreSame' or 'Assert.AreNotSame' with value types + 不要在值類型中使用 'Assert.AreSame' 或 'Assert.AreNotSame' Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + 偏好 'Assert.ThrowsExactly' 或 'Assert.ThrowsExactlyAsync' 而不是 '[ExpectedException]',因為它可確保只有預期的呼叫會擲出預期的例外狀況。判斷提示 API 也提供更多彈性,並允許您判斷提示例外狀況的額外屬性。 Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + 偏好 'Assert.ThrowsExactly/ThrowsExactlyAsync' 而不是 '[ExpectedException]' @@ -741,12 +741,12 @@ The type declaring these methods should also respect the following rules: Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' - Use 'Assert.ThrowsExactly' instead of 'Assert.ThrowsException' + 使用 'Assert.ThrowsExactly' 而非 'Assert.ThrowsException' Use newer methods to assert exceptions - Use newer methods to assert exceptions + 使用較新的方法判斷例外狀況 From d455de03ae7cef03c691319c49e2c42600853551 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 8 Jan 2025 11:52:50 +0100 Subject: [PATCH 242/273] [main] Bump MSTest from 3.8.0-preview.25056.11 to 3.8.0-preview.25057.8 (#4556) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index af2de7feb8..0aae14f8fc 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -24,7 +24,7 @@ 1.1.3-beta1.24423.1 - 3.8.0-preview.25056.11 + 3.8.0-preview.25057.8 From 860c0ffd309bdef8e68a874c059092883598979b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 8 Jan 2025 21:53:51 +1100 Subject: [PATCH 243/273] remove destructor pattern from TempDirectory (#4545) --- .../TempDirectory.cs | 43 +++++++------------ 1 file changed, 16 insertions(+), 27 deletions(-) diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TempDirectory.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TempDirectory.cs index 437e2fc070..a41a32e696 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TempDirectory.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/TempDirectory.cs @@ -23,29 +23,34 @@ public TempDirectory(string? subDirectory = null, bool arcadeConvention = true, _cleanup = cleanup; } - ~TempDirectory() => Clean(); - public string Path { get; } public void Dispose() - { - Dispose(true); - GC.SuppressFinalize(this); - } - - protected virtual void Dispose(bool disposing) { if (_isDisposed) { return; } - if (disposing && _cleanup) + _isDisposed = true; + + if (!_cleanup) { - Clean(); + return; } - _isDisposed = true; + if (!Directory.Exists(_baseDirectory)) + { + return; + } + + try + { + Directory.Delete(_baseDirectory, recursive: true); + } + catch + { + } } public DirectoryInfo CreateDirectory(string dir) => Directory.CreateDirectory(System.IO.Path.Combine(Path, dir)); @@ -226,22 +231,6 @@ internal static (string BaseDirectory, string FinalDirectory) CreateUniqueDirect private static string GetTempPath() => Environment.GetEnvironmentVariable("AGENT_TEMPDIRECTORY") ?? System.IO.Path.GetTempPath(); - public void Clean() - { - if (!Directory.Exists(_baseDirectory)) - { - return; - } - - try - { - Directory.Delete(_baseDirectory, recursive: true); - } - catch - { - } - } - public void Add(string fileContents) { List files = InlineFileParser.ParseFiles(fileContents); From 1087e19071c17a50826411d702f0ef89a963b6cb Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 8 Jan 2025 21:56:04 +1100 Subject: [PATCH 244/273] remove un-used list in ExceptionFlattener.cs (#4548) --- .../OutputDevice/Terminal/ExceptionFlattener.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs index e0a57cbe9d..5e0a406ab8 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/ExceptionFlattener.cs @@ -12,8 +12,6 @@ internal static FlatException[] Flatten(string? errorMessage, Exception? excepti return Array.Empty(); } - List exceptions = new(); - string? message = !RoslynString.IsNullOrWhiteSpace(errorMessage) ? errorMessage : exception?.Message; string? type = exception?.GetType().FullName; string? stackTrace = exception?.StackTrace; From a2f50bc5bff05beb6fcef29d038ccabf05cca168 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 8 Jan 2025 21:56:25 +1100 Subject: [PATCH 245/273] remove redundant string.ToString() (#4550) --- .../CommandLine/ResponseFileHelper.cs | 2 +- .../OutputDevice/Terminal/TerminalTestReporterTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/CommandLine/ResponseFileHelper.cs b/src/Platform/Microsoft.Testing.Platform/CommandLine/ResponseFileHelper.cs index ff9a0b029f..1b9d4c057b 100644 --- a/src/Platform/Microsoft.Testing.Platform/CommandLine/ResponseFileHelper.cs +++ b/src/Platform/Microsoft.Testing.Platform/CommandLine/ResponseFileHelper.cs @@ -153,7 +153,7 @@ public static IEnumerable SplitCommandLine(string commandLine) void Advance() => pos++; - string CurrentToken() => commandLine.Substring(startTokenIndex, IndexOfEndOfToken()).ToString().Replace("\"", string.Empty); + string CurrentToken() => commandLine.Substring(startTokenIndex, IndexOfEndOfToken()).Replace("\"", string.Empty); int IndexOfEndOfToken() => pos - startTokenIndex; diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs index b73e359482..7e9685da11 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs @@ -32,7 +32,7 @@ public void AppendStackFrameFormatsStackTraceLineCorrectly() StringAssert.Contains(terminal.Output, " at Microsoft.Testing.Platform.UnitTests.TerminalTestReporterTests.AppendStackFrameFormatsStackTraceLineCorrectly()"); #endif // Line number without the respective file - Assert.IsFalse(terminal.Output.ToString().Contains(" :0")); + Assert.IsFalse(terminal.Output.Contains(" :0")); } // Code with line when we have symbols From 2306c49d207a6cc7478c1516ea8f161e38af5cef Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 8 Jan 2025 21:57:18 +1100 Subject: [PATCH 246/273] missing usings on MessageBusProxy instances (#4547) --- .../Messages/AsynchronousMessageBusTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/AsynchronousMessageBusTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/AsynchronousMessageBusTests.cs index 727c21ac87..2d6ba5076e 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/AsynchronousMessageBusTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Messages/AsynchronousMessageBusTests.cs @@ -16,7 +16,7 @@ public sealed class AsynchronousMessageBusTests [TestMethod] public async Task UnexpectedTypePublished_ShouldFail() { - MessageBusProxy proxy = new(); + using MessageBusProxy proxy = new(); InvalidTypePublished consumer = new(proxy); AsynchronousMessageBus asynchronousMessageBus = new( [consumer], @@ -36,7 +36,7 @@ public async Task UnexpectedTypePublished_ShouldFail() [TestMethod] public async Task DrainDataAsync_Loop_ShouldFail() { - MessageBusProxy proxy = new(); + using MessageBusProxy proxy = new(); LoopConsumerA consumerA = new(proxy); ConsumerB consumerB = new(proxy); AsynchronousMessageBus asynchronousMessageBus = new( @@ -67,7 +67,7 @@ public async Task DrainDataAsync_Loop_ShouldFail() [TestMethod] public async Task MessageBus_WhenConsumerProducesAndConsumesTheSameType_ShouldNotConsumeWhatProducedByItself() { - MessageBusProxy proxy = new(); + using MessageBusProxy proxy = new(); Consumer consumerA = new(proxy, "consumerA"); Consumer consumerB = new(proxy, "consumerB"); AsynchronousMessageBus asynchronousMessageBus = new( From afc61d9e28474aa398f2e2a01dfe2339d3e63f29 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Wed, 8 Jan 2025 22:07:25 +1100 Subject: [PATCH 247/273] remove object based override of GetTypeDisplayName (#4551) --- .../Microsoft.Testing.Platform/Logging/TypeNameHelper.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Logging/TypeNameHelper.cs b/src/Platform/Microsoft.Testing.Platform/Logging/TypeNameHelper.cs index 529043fd08..addac6ed99 100644 --- a/src/Platform/Microsoft.Testing.Platform/Logging/TypeNameHelper.cs +++ b/src/Platform/Microsoft.Testing.Platform/Logging/TypeNameHelper.cs @@ -31,12 +31,6 @@ internal static class TypeNameHelper { typeof(ushort), "ushort" }, }; - [return: NotNullIfNotNull(nameof(item))] - public static string? GetTypeDisplayName(object? item, bool fullName = true) - => item == null - ? null - : GetTypeDisplayName(item.GetType(), fullName); - /// /// Pretty print a type name. /// From a97ef87853ce441ab71f36a125e8cda98c0f2c71 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 8 Jan 2025 03:22:31 -0800 Subject: [PATCH 248/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2615610 --- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf | 2 +- src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf | 4 ++-- src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf | 4 ++-- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf index e7df9fde23..b743a99782 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + Použít {0} diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf index 55854fb46c..04c9d1631d 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + „{0}“ verwenden diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf index 3ef3c4b74b..afb034c21f 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + '{0}' 사용 diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf index 06b914441c..9511d2b3cb 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + Использовать "{0}" diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf index 67e36132ae..7e0d3ff59b 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf @@ -134,12 +134,12 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Preferujte Assert.ThrowsExactly nebo Assert.ThrowsExactlyAsync před [ExpectedException], protože zajišťuje, že očekávanou výjimku vyvolá pouze očekávané volání. Rozhraní API pro vyhodnocení také poskytují větší flexibilitu a umožňují vyhodnocovat další vlastnosti výjimky. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Preferovat Assert.ThrowsExactly/ThrowsExactlyAsync před [ExpectedException] diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf index 2c47350396..d975c377ec 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf @@ -134,12 +134,12 @@ The type declaring these methods should also respect the following rules: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + '[ExpectedException]' よりも 'Assert.ThrowsExactly' または 'Assert.ThrowsExactlyAsync' を優先します。これは、予期された呼び出しのみが予期された例外をスローするようにするためです。アサート API もさらに柔軟性が高く、これにより例外の追加プロパティをアサートできます。 Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + '[ExpectedException]' よりも 'Assert.ThrowsExactly/ThrowsExactlyAsync' を優先する diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf index 60db122201..978d132ac7 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf @@ -134,12 +134,12 @@ The type declaring these methods should also respect the following rules: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + 예상되는 호출만 예상되는 예외를 던지도록 하기 위해 '[ExpectedException]보다 'Assert.ThrowsExactly' 또는 'Assert.ThrowsExactlyAsync'를 사용하는 것이 좋습니다. 또한 어설션 API는 더 많은 유연성을 제공하고 예외의 추가 속성을 어설션할 수 있습니다. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + '[ExpectedException]'보다 'Assert.ThrowsExactly/ThrowsExactlyAsync' 선호 diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf index 6f569d1da9..9f7c169e0c 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf @@ -134,12 +134,12 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + Prefira 'Assert.ThrowsExactly' ou 'Assert.ThrowsExactlyAsync' em vez de '[ExpectedException]', pois isso garante que apenas a chamada esperada lance a exceção esperada. As APIs de assert também oferecem mais flexibilidade e permitem que você afirme propriedades adicionais da exceção. Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + Prefira 'Assert.ThrowsExactly/ThrowsExactlyAsync' em vez de '[ExpectedException]' diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf index fad2c8e4e5..a6e50d1ef6 100644 --- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf @@ -134,12 +134,12 @@ The type declaring these methods should also respect the following rules: Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. - Prefer 'Assert.ThrowsExactly' or 'Assert.ThrowsExactlyAsync' 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 exception. + 首选“Assert.ThrowsExactly”或“Assert.ThrowsExactlyAsync”,而不是“[ExpectedException]”,因为它确保只有预期调用才会引发预期异常。断言 API 还提供更多的灵活性,并允许你断言异常的额外属性。 Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' - Prefer 'Assert.ThrowsExactly/ThrowsExactlyAsync' over '[ExpectedException]' + 首先“Assert.ThrowsExactly/ThrowsExactlyAsync”而不是“[ExpectedException]” From 47004dc214ef8ef315bd67d4b32c7bbd86f6a95b Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 8 Jan 2025 03:23:56 -0800 Subject: [PATCH 249/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2615610 --- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf index 4ad657b676..8c807e3574 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf @@ -89,7 +89,7 @@ Use '{0}' - Use '{0}' + 使用“{0}” From eb27c4ac00c47f55eaa709ef966c37db54f81a5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jare=C5=A1?= Date: Wed, 8 Jan 2025 14:40:17 +0100 Subject: [PATCH 250/273] Add dotnet test client to be used in dotnet/sdk (#4558) --- TestFx.sln | 7 +++ eng/Build.props | 4 +- eng/verify-nupkgs.ps1 | 18 ++++--- ...t.Testing.Platform.DotNetTestClient.csproj | 54 +++++++++++++++++++ .../PACKAGE.md | 7 +++ .../Microsoft.Testing.Platform.csproj | 1 - .../{IPC => }/DotnetTestDataConsumer.cs | 0 7 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 src/Package/Microsoft.Testing.Platform.DotNetTestClient/Microsoft.Testing.Platform.DotNetTestClient.csproj create mode 100644 src/Package/Microsoft.Testing.Platform.DotNetTestClient/PACKAGE.md rename src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/{IPC => }/DotnetTestDataConsumer.cs (100%) diff --git a/TestFx.sln b/TestFx.sln index d014ea3643..6b11cf4c4f 100644 --- a/TestFx.sln +++ b/TestFx.sln @@ -214,6 +214,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Testing.Extension EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Testing.Extensions.Retry", "src\Platform\Microsoft.Testing.Extensions.Retry\Microsoft.Testing.Extensions.Retry.csproj", "{FB4ED3AA-A12E-4192-861F-4B025876AA0F}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Testing.Platform.DotNetTestClient", "src\Package\Microsoft.Testing.Platform.DotNetTestClient\Microsoft.Testing.Platform.DotNetTestClient.csproj", "{4E4F965E-2EEF-471B-A5DA-A53BFA967A95}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -500,6 +502,10 @@ Global {FB4ED3AA-A12E-4192-861F-4B025876AA0F}.Debug|Any CPU.Build.0 = Debug|Any CPU {FB4ED3AA-A12E-4192-861F-4B025876AA0F}.Release|Any CPU.ActiveCfg = Release|Any CPU {FB4ED3AA-A12E-4192-861F-4B025876AA0F}.Release|Any CPU.Build.0 = Release|Any CPU + {4E4F965E-2EEF-471B-A5DA-A53BFA967A95}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4E4F965E-2EEF-471B-A5DA-A53BFA967A95}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4E4F965E-2EEF-471B-A5DA-A53BFA967A95}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4E4F965E-2EEF-471B-A5DA-A53BFA967A95}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -587,6 +593,7 @@ Global {4A93E1A2-B61E-31B2-33F2-478156A9B5E7} = {E7F15C9C-3928-47AD-8462-64FD29FFCA54} {53EBA540-F6CF-0715-1F62-241A53F537EC} = {6AEE1440-FDF0-4729-8196-B24D0E333550} {FB4ED3AA-A12E-4192-861F-4B025876AA0F} = {6AEE1440-FDF0-4729-8196-B24D0E333550} + {4E4F965E-2EEF-471B-A5DA-A53BFA967A95} = {E374A3A6-C364-4890-B315-D60F5C682B6E} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {31E0F4D5-975A-41CC-933E-545B2201FAF9} diff --git a/eng/Build.props b/eng/Build.props index 5cd34c03f1..e04a3d62ad 100644 --- a/eng/Build.props +++ b/eng/Build.props @@ -6,9 +6,9 @@ - + - + diff --git a/eng/verify-nupkgs.ps1 b/eng/verify-nupkgs.ps1 index c4e8ca3be5..a8c3ba4d07 100644 --- a/eng/verify-nupkgs.ps1 +++ b/eng/verify-nupkgs.ps1 @@ -1,6 +1,6 @@ [CmdletBinding()] Param( - [Parameter(Mandatory=$true)] + [Parameter(Mandatory = $true)] [System.String] $configuration ) @@ -19,12 +19,13 @@ function Unzip { function Confirm-NugetPackages { Write-Verbose "Starting Confirm-NugetPackages." $expectedNumOfFiles = @{ - "MSTest.Sdk" = 15; - "MSTest.Internal.TestFx.Documentation" = 10; - "MSTest.TestFramework" = 148; - "MSTest.TestAdapter" = 75; - "MSTest" = 6; - "MSTest.Analyzers" = 50; + "MSTest.Sdk" = 15 + "MSTest.Internal.TestFx.Documentation" = 10 + "MSTest.TestFramework" = 148 + "MSTest.TestAdapter" = 75 + "MSTest" = 6 + "MSTest.Analyzers" = 50 + "Microsoft.Testing.Platform.DotNetTestClient" = 7 } $packageDirectory = Resolve-Path "$PSScriptRoot/../artifacts/packages/$configuration" @@ -79,7 +80,8 @@ function Confirm-NugetPackages { if ($errors) { Write-Error "Validation of NuGet packages failed with $($errors.Count) errors:`n$($errors -join "`n")" - } else { + } + else { Write-Host "Successfully validated content of NuGet packages" } } diff --git a/src/Package/Microsoft.Testing.Platform.DotNetTestClient/Microsoft.Testing.Platform.DotNetTestClient.csproj b/src/Package/Microsoft.Testing.Platform.DotNetTestClient/Microsoft.Testing.Platform.DotNetTestClient.csproj new file mode 100644 index 0000000000..2e52abf512 --- /dev/null +++ b/src/Package/Microsoft.Testing.Platform.DotNetTestClient/Microsoft.Testing.Platform.DotNetTestClient.csproj @@ -0,0 +1,54 @@ + + + + net9.0 + $(TestingPlatformVersionPrefix) + + + + true + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Package/Microsoft.Testing.Platform.DotNetTestClient/PACKAGE.md b/src/Package/Microsoft.Testing.Platform.DotNetTestClient/PACKAGE.md new file mode 100644 index 0000000000..857a8f0a35 --- /dev/null +++ b/src/Package/Microsoft.Testing.Platform.DotNetTestClient/PACKAGE.md @@ -0,0 +1,7 @@ +# Microsoft.Testing.Platform.DotNetTestClient + +This package contains types that are required by `dotnet test` in dotnet/SDK to communicate with an Microsoft.Testing.Platform test executable. + +Supported platforms: + +- .NET 10 diff --git a/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj b/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj index 65d829e792..2aade9a71e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj +++ b/src/Platform/Microsoft.Testing.Platform/Microsoft.Testing.Platform.csproj @@ -48,7 +48,6 @@ This package provides the core platform and the .NET implementation of the proto - diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/DotnetTestDataConsumer.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestDataConsumer.cs similarity index 100% rename from src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/DotnetTestDataConsumer.cs rename to src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/DotnetTestDataConsumer.cs From 9682c1d6ef850fac69b250a48bb9216b556a8741 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Wed, 8 Jan 2025 20:14:02 +0100 Subject: [PATCH 251/273] Fix flaky `WhenSpecificDataSourceIsIgnoredViaIgnoreMessageProperty` (#4553) --- .../Helpers/System/SystemConsole.cs | 11 ++- .../OutputDevice/Terminal/NonAnsiTerminal.cs | 97 +++++++------------ .../IgnoreTests.cs | 78 ++++++--------- 3 files changed, 74 insertions(+), 112 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs index 996ac44b11..c781997504 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/System/SystemConsole.cs @@ -8,6 +8,8 @@ internal sealed class SystemConsole : IConsole private const int WriteBufferSize = 256; private static readonly StreamWriter CaptureConsoleOutWriter; + internal static TextWriter ConsoleOut { get; } + /// /// Gets the height of the buffer area. /// @@ -25,16 +27,21 @@ internal sealed class SystemConsole : IConsole private bool _suppressOutput; - static SystemConsole() => + static SystemConsole() + { + // This is the console that the ITerminal will be writing to. + // So, this is what NonAnsiTerminal need to "lock" on regardless of whether it changed later. + ConsoleOut = Console.Out; // From https://github.com/dotnet/runtime/blob/main/src/libraries/System.Console/src/System/Console.cs#L236 CaptureConsoleOutWriter = new StreamWriter( stream: Console.OpenStandardOutput(), - encoding: Console.Out.Encoding, + encoding: ConsoleOut.Encoding, bufferSize: WriteBufferSize, leaveOpen: true) { AutoFlush = true, }; + } // the following event does not make sense in the mobile scenarios, user cannot ctrl+c // but can just kill the app in the device via a gesture diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs index 44b8042803..b72fa30d2e 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/NonAnsiTerminal.cs @@ -14,7 +14,6 @@ internal sealed class NonAnsiTerminal : ITerminal { private readonly IConsole _console; private readonly ConsoleColor _defaultForegroundColor; - private readonly StringBuilder _stringBuilder = new(); private bool _isBatching; public NonAnsiTerminal(IConsole console) @@ -28,52 +27,16 @@ public NonAnsiTerminal(IConsole console) public int Height => _console.IsOutputRedirected ? int.MaxValue : _console.BufferHeight; public void Append(char value) - { - if (_isBatching) - { - _stringBuilder.Append(value); - } - else - { - _console.Write(value); - } - } + => _console.Write(value); public void Append(string value) - { - if (_isBatching) - { - _stringBuilder.Append(value); - } - else - { - _console.Write(value); - } - } + => _console.Write(value); public void AppendLine() - { - if (_isBatching) - { - _stringBuilder.AppendLine(); - } - else - { - _console.WriteLine(); - } - } + => _console.WriteLine(); public void AppendLine(string value) - { - if (_isBatching) - { - _stringBuilder.AppendLine(value); - } - else - { - _console.WriteLine(value); - } - } + => _console.WriteLine(value); public void AppendLink(string path, int? lineNumber) { @@ -85,26 +48,10 @@ public void AppendLink(string path, int? lineNumber) } public void SetColor(TerminalColor color) - { - if (_isBatching) - { - _console.Write(_stringBuilder.ToString()); - _stringBuilder.Clear(); - } - - _console.SetForegroundColor(ToConsoleColor(color)); - } + => _console.SetForegroundColor(ToConsoleColor(color)); public void ResetColor() - { - if (_isBatching) - { - _console.Write(_stringBuilder.ToString()); - _stringBuilder.Clear(); - } - - _console.SetForegroundColor(_defaultForegroundColor); - } + => _console.SetForegroundColor(_defaultForegroundColor); public void ShowCursor() { @@ -116,6 +63,9 @@ public void HideCursor() // nop } + // TODO: Refactor NonAnsiTerminal and AnsiTerminal such that we don't need StartUpdate/StopUpdate. + // It's much better if we use lock C# keyword instead of manually calling Monitor.Enter/Exit + // Using lock also ensures we don't accidentally have `await`s in between that could cause Exit to be on a different thread. public void StartUpdate() { if (_isBatching) @@ -123,13 +73,38 @@ public void StartUpdate() throw new InvalidOperationException(PlatformResources.ConsoleIsAlreadyInBatchingMode); } - _stringBuilder.Clear(); + bool lockTaken = false; + // SystemConsole.ConsoleOut is set only once in static ctor. + // So we are sure we will be doing Monitor.Exit on the same instance. + // Note that we need to lock on System.Out for batching to work correctly. + // Consider the following scenario: + // 1. We call StartUpdate + // 2. We call a Write("A") + // 3. User calls Console.Write("B") from another thread. + // 4. We call a Write("C"). + // 5. We call StopUpdate. + // The expectation is that we see either ACB, or BAC, but not ABC. + // Basically, when doing batching, we want to ensure that everything we write is + // written continuously, without anything in-between. + // One option (and we used to do it), is that we append to a StringBuilder while batching + // Then at StopUpdate, we write the whole string at once. + // This works to some extent, but we cannot get it to work when SetColor kicks in. + // Console methods will internally lock on Console.Out, so we are locking on the same thing. + // This locking is the easiest way to get coloring to work correctly while preventing + // interleaving with user's calls to Console.Write methods. + Monitor.Enter(SystemConsole.ConsoleOut, ref lockTaken); + if (!lockTaken) + { + // Can this happen? :/ + throw new InvalidOperationException(); + } + _isBatching = true; } public void StopUpdate() { - _console.Write(_stringBuilder.ToString()); + Monitor.Exit(SystemConsole.ConsoleOut); _isBatching = false; } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs index 519f74159c..65c4843804 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/IgnoreTests.cs @@ -66,55 +66,35 @@ public async Task WhenSpecificDataSourceIsIgnoredViaIgnoreMessageProperty() // Assert testHostResult.AssertExitCodeIs(ExitCodes.Success); - testHostResult.AssertOutputContains(""" - TestInitialize: TestMethod1 (0) - TestCleanup: TestMethod1 (0) - """); - - testHostResult.AssertOutputContains(""" - TestInitialize: TestMethod1 (2) - TestCleanup: TestMethod1 (2) - """); - - testHostResult.AssertOutputContains(""" - TestInitialize: TestMethod2 (0) - TestCleanup: TestMethod2 (0) - """); - - testHostResult.AssertOutputContains(""" - TestInitialize: TestMethod2 (1) - TestCleanup: TestMethod2 (1) - """); - - testHostResult.AssertOutputContains(""" - TestInitialize: TestMethod2 (2) - TestCleanup: TestMethod2 (2) - """); - - testHostResult.AssertOutputContains(""" - TestInitialize: TestMethod3 (0) - TestCleanup: TestMethod3 (0) - """); - - testHostResult.AssertOutputContains(""" - TestInitialize: TestMethod3 (2) - TestCleanup: TestMethod3 (2) - """); - - testHostResult.AssertOutputContains(""" - TestInitialize: TestMethod4 (0) - TestCleanup: TestMethod4 (0) - """); - - testHostResult.AssertOutputContains(""" - TestInitialize: TestMethod4 (1) - TestCleanup: TestMethod4 (1) - """); - - testHostResult.AssertOutputContains(""" - TestInitialize: TestMethod4 (2) - TestCleanup: TestMethod4 (2) - """); + testHostResult.AssertOutputContains("TestInitialize: TestMethod1 (0)"); + testHostResult.AssertOutputContains("TestCleanup: TestMethod1 (0)"); + + testHostResult.AssertOutputContains("TestInitialize: TestMethod1 (2)"); + testHostResult.AssertOutputContains("TestCleanup: TestMethod1 (2)"); + + testHostResult.AssertOutputContains("TestInitialize: TestMethod2 (0)"); + testHostResult.AssertOutputContains("TestCleanup: TestMethod2 (0)"); + + testHostResult.AssertOutputContains("TestInitialize: TestMethod2 (1)"); + testHostResult.AssertOutputContains("TestCleanup: TestMethod2 (1)"); + + testHostResult.AssertOutputContains("TestInitialize: TestMethod2 (2)"); + testHostResult.AssertOutputContains("TestCleanup: TestMethod2 (2)"); + + testHostResult.AssertOutputContains("TestInitialize: TestMethod3 (0)"); + testHostResult.AssertOutputContains("TestCleanup: TestMethod3 (0)"); + + testHostResult.AssertOutputContains("TestInitialize: TestMethod3 (2)"); + testHostResult.AssertOutputContains("TestCleanup: TestMethod3 (2)"); + + testHostResult.AssertOutputContains("TestInitialize: TestMethod4 (0)"); + testHostResult.AssertOutputContains("TestCleanup: TestMethod4 (0)"); + + testHostResult.AssertOutputContains("TestInitialize: TestMethod4 (1)"); + testHostResult.AssertOutputContains("TestCleanup: TestMethod4 (1)"); + + testHostResult.AssertOutputContains("TestInitialize: TestMethod4 (2)"); + testHostResult.AssertOutputContains("TestCleanup: TestMethod4 (2)"); testHostResult.AssertOutputContains("skipped TestMethod1"); testHostResult.AssertOutputContains("skipped TestMethod2"); From 90df6960286e310bd15bd27a86a0534f6d630151 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 9 Jan 2025 07:49:58 +0100 Subject: [PATCH 252/273] Set MTP editorconfig as non-root explicitly (#4567) --- src/Platform/Microsoft.Testing.Platform/.editorconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Platform/Microsoft.Testing.Platform/.editorconfig b/src/Platform/Microsoft.Testing.Platform/.editorconfig index 5c8e5dad5d..a9e2e322b6 100644 --- a/src/Platform/Microsoft.Testing.Platform/.editorconfig +++ b/src/Platform/Microsoft.Testing.Platform/.editorconfig @@ -1,3 +1,5 @@ +root = false + [*.{cs,vb}] # TPEXP: Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed. dotnet_diagnostic.TPEXP.severity = none From 5462e24c95d7c1d32c63f097cdbfbb218108d5e0 Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 8 Jan 2025 23:02:45 -0800 Subject: [PATCH 253/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2616356 --- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf index b743a99782..92113c5428 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + Přesunout podmíněný přístup v kontrolním výrazu, aby se oddělila kontrola Assert.IsNotNull diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf index 04c9d1631d..da9c7cb051 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + Bedingten Zugriff in Assertion auf separate "Assert.IsNotNull"-Überprüfung verschieben diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf index d713d9bc90..402bf5caa5 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + Mover el acceso condicional en la aserción para separar la comprobación 'Assert.IsNotNull' diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf index 52703c000f..c7558f7d6c 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + Déplacer l’accès conditionnel dans l’assertion pour séparer les case activée 'Assert.IsNotNull' diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf index 01427c605a..7c641b301b 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + Sposta l'accesso condizionale nell'asserzione per separare il controllo 'Assert.IsNotNull' diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf index 84c5786c5c..11f9b0e16e 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + アサーション内の条件付きアクセスを個別の 'Assert.IsNotNull' チェックに移動します diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf index afb034c21f..de99bc90b7 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + 어설션의 조건부 액세스를 'Assert.IsNotNull' 검사 구분하도록 이동합니다. diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf index da8b0630df..ac3bcd5f03 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + Przenieś dostęp warunkowy w asercji do oddzielnego sprawdzenia "Assert.IsNotNull" diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf index 0da76f1ca5..27d3ad00ea 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + Mover o acesso condicional na asserção para separar o 'Assert.IsNotNull' marcar diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf index 9511d2b3cb..70a1cb09f2 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + Переместить условный доступ в утверждении, чтобы разделить "Assert.IsNotNull" проверка diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf index 725162bebe..dd75c3d40a 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + Onaylamadaki koşullu erişimi 'Assert.IsNotNull' denetimine ayırmaya taşı From 578fc778973a10cd2155b28a68728b61c09295cc Mon Sep 17 00:00:00 2001 From: dotnet bot Date: Wed, 8 Jan 2025 23:04:06 -0800 Subject: [PATCH 254/273] Localized file check-in by OneLocBuild Task: Build definition ID 1218: Build ID 2616356 --- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf | 2 +- .../MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf index 8c807e3574..62c59a4813 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + 将断言中的条件访问移动到分隔 “Assert.IsNotNull” 检查 diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf index 92274ff135..e449ea07e8 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf @@ -9,7 +9,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - Move conditional access in assertion to separate 'Assert.IsNotNull' check + 將判斷提示中的條件式存取移動到個別的 『Assert.IsNotNull』 檢查 From 35a3f5b0d1212edbf5eb9c29eabe076d9926e2bb Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 07:27:50 +0000 Subject: [PATCH 255/273] [main] Update dependencies from devdiv/DevDiv/vs-code-coverage, microsoft/testanywhere (#4565) Co-authored-by: dotnet-maestro[bot] --- eng/Version.Details.xml | 8 ++++---- eng/Versions.props | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 22787098d4..554abc7e39 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -13,13 +13,13 @@ https://github.com/dotnet/arcade 45d845e04c05fbe5da9838c454bbc3af1df6be81 - + https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage - 3889f929bc86d4f819c62bfa687b01660c9e195d + 0bfbc955e0dc1826412fdeaa4587106f038ec8de - + https://github.com/microsoft/testanywhere - 712ed1a92cec839ca106e0ffdfd134b05925f1ad + d898ece7f4a764f772bf2ec89ac78a960edb3114 diff --git a/eng/Versions.props b/eng/Versions.props index 6becc094b3..94a2168dad 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -8,8 +8,8 @@ 10.0.0-beta.24604.4 - 17.14.0-preview.25056.1 + 17.14.0-preview.25058.3 - 1.0.0-alpha.25056.4 + 1.0.0-alpha.25058.1 From e482b2317389d63cacb3caace1f7fc2fa3b73005 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 9 Jan 2025 19:16:32 +1100 Subject: [PATCH 256/273] make some methods static (#4564) --- .../Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs | 2 +- .../ParameterizedTestTests.cs | 2 +- .../ThreadContextTests.cs | 2 +- .../MSTest.Acceptance.IntegrationTests/TimeoutTests.cs | 6 +++--- .../IntegrationTests/MSTest.IntegrationTests/OutputTests.cs | 2 +- .../Utilities/CLITestBase.discovery.cs | 4 ++-- .../FixturesTests.cs | 2 +- .../DiagnosticTests.cs | 4 ++-- .../TelemetryTests.cs | 4 ++-- .../TrxTests.cs | 2 +- .../ReflectionUtilityTests.cs | 2 +- .../MSTest.Performance.Runner/Steps/PerfviewRunner.cs | 2 +- .../UseAsyncSuffixTestFixtureMethodSuppressorTests.cs | 2 +- .../UseAsyncSuffixTestMethodSuppressorTests.cs | 2 +- .../Discovery/UnitTestDiscovererTests.cs | 2 +- .../Execution/TestMethodInfoTests.cs | 2 +- .../Configuration/ConfigurationExtensionsTests.cs | 2 +- .../ServerMode/FormatterUtilitiesTests.cs | 2 +- test/Utilities/Automation.CLI/CLITestBase.e2e.cs | 2 +- .../Microsoft.Testing.TestInfrastructure/DotnetMuxer.cs | 2 +- 20 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs index ca36e2af56..925b000fd4 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostBuilder.cs @@ -629,7 +629,7 @@ private static async Task LogTestHostCreatedAsync( } } - private async Task BuildTestFrameworkAsync(TestFrameworkBuilderData testFrameworkBuilderData) + private static async Task BuildTestFrameworkAsync(TestFrameworkBuilderData testFrameworkBuilderData) { // Add the message bus proxy ServiceProvider serviceProvider = testFrameworkBuilderData.ServiceProvider; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ParameterizedTestTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ParameterizedTestTests.cs index dc22dbb698..54d66170a0 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ParameterizedTestTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ParameterizedTestTests.cs @@ -43,7 +43,7 @@ public async Task SendingEmptyDataToDynamicDataTest_WithoutSettingConsiderEmptyD public async Task SendingEmptyDataToDataSourceTest_WithoutSettingConsiderEmptyDataSourceAsInconclusive_Fails(string currentTfm) => await RunTestsAsync(currentTfm, DataSourceAssetName, null); - private async Task RunTestsAsync(string currentTfm, string assetName, bool? isEmptyDataInconclusive) + private static async Task RunTestsAsync(string currentTfm, string assetName, bool? isEmptyDataInconclusive) { var testHost = TestHost.LocateFrom(AssetFixture.GetAssetPath(assetName), assetName, currentTfm); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadContextTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadContextTests.cs index 4667b789f7..1c64b26e18 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadContextTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ThreadContextTests.cs @@ -33,7 +33,7 @@ public async Task ThreadingContext_WhenChangedInClassInitialize_IsPassedToTestMe public async Task ThreadingContext_WhenChangedInTestInitialize_IsPassedToTestMethod(string tfm) => await SetCultureInFixtureMethodAndRunTests(tfm, "MSTEST_TEST_SET_CULTURE_TEST_INIT"); - private async Task SetCultureInFixtureMethodAndRunTests(string tfm, string envVarKey) + private static async Task SetCultureInFixtureMethodAndRunTests(string tfm, string envVarKey) { var testHost = TestHost.LocateFrom(AssetFixture.InitToTestProjectPath, TestAssetFixture.InitToTestProjectName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { [envVarKey] = "true" }); diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs index 3e289d95de..28c9eca481 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/TimeoutTests.cs @@ -362,21 +362,21 @@ public async Task CooperativeCancellation_WhenTestCleanupTimeoutExpiresAndUserCh testHostResult.AssertOutputContains("Test cleanup method 'TestClass.TestCleanup' timed out after 1000ms"); } - private async Task RunAndAssertTestWasCanceledAsync(string rootFolder, string assetName, string tfm, string envVarPrefix, string entryKind) + private static async Task RunAndAssertTestWasCanceledAsync(string rootFolder, string assetName, string tfm, string envVarPrefix, string entryKind) { var testHost = TestHost.LocateFrom(rootFolder, assetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { { envVarPrefix + InfoByKind[entryKind].EnvVarSuffix, "1" } }); testHostResult.AssertOutputContains($"{InfoByKind[entryKind].Prefix} method '{InfoByKind[entryKind].MethodFullName}' was canceled"); } - private async Task RunAndAssertTestTimedOutAsync(string rootFolder, string assetName, string tfm, string envVarPrefix, string entryKind) + private static async Task RunAndAssertTestTimedOutAsync(string rootFolder, string assetName, string tfm, string envVarPrefix, string entryKind) { var testHost = TestHost.LocateFrom(rootFolder, assetName, tfm); TestHostResult testHostResult = await testHost.ExecuteAsync(environmentVariables: new() { { envVarPrefix + InfoByKind[entryKind].EnvVarSuffix, "1" } }); testHostResult.AssertOutputContains($"{InfoByKind[entryKind].Prefix} method '{InfoByKind[entryKind].MethodFullName}' timed out after 1000ms"); } - private async Task RunAndAssertWithRunSettingsAsync(string tfm, int timeoutValue, bool assertAttributePrecedence, string entryKind) + private static async Task RunAndAssertWithRunSettingsAsync(string tfm, int timeoutValue, bool assertAttributePrecedence, string entryKind) { string runSettingsEntry = InfoByKind[entryKind].RunSettingsEntryName; string runSettings = $""" diff --git a/test/IntegrationTests/MSTest.IntegrationTests/OutputTests.cs b/test/IntegrationTests/MSTest.IntegrationTests/OutputTests.cs index 2ab4ae7562..1e8284032d 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/OutputTests.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/OutputTests.cs @@ -16,7 +16,7 @@ public class OutputTests : CLITestBase public void OutputIsNotMixedWhenAsyncTestsRunInParallel() => ValidateOutputForClass("UnitTest2"); - private void ValidateOutputForClass(string className) + private static void ValidateOutputForClass(string className) { // LogMessageListener uses an implementation of a string writer that captures output per async context. // This allows us to capture output from tasks even when they are running in parallel. diff --git a/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs b/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs index 05665bf625..31d9057b6f 100644 --- a/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs +++ b/test/IntegrationTests/MSTest.IntegrationTests/Utilities/CLITestBase.discovery.cs @@ -19,7 +19,7 @@ namespace Microsoft.MSTestV2.CLIAutomation; public partial class CLITestBase : TestContainer { - internal ImmutableArray DiscoverTests(string assemblyPath, string testCaseFilter = null) + internal static ImmutableArray DiscoverTests(string assemblyPath, string testCaseFilter = null) { var unitTestDiscoverer = new UnitTestDiscoverer(); var logger = new InternalLogger(); @@ -33,7 +33,7 @@ internal ImmutableArray DiscoverTests(string assemblyPath, string test return sink.DiscoveredTests; } - internal ImmutableArray RunTests(IEnumerable testCases) + internal static ImmutableArray RunTests(IEnumerable testCases) { var testExecutionManager = new TestExecutionManager(); var frameworkHandle = new InternalFrameworkHandle(); diff --git a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/FixturesTests.cs b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/FixturesTests.cs index 56a788a403..a9a3cde76c 100644 --- a/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/FixturesTests.cs +++ b/test/IntegrationTests/MSTest.VstestConsoleWrapper.IntegrationTests/FixturesTests.cs @@ -138,7 +138,7 @@ public void RunSingleTest_ClassInitialize_Failure_Runs_AssemblyFixtures() ValidatePassedTests([AssemblyInitialize, AssemblyCleanup, ClassCleanup]); } - private string GetRunSettings(bool fixturesEnabled, bool assemblyInitialize, bool assemblyCleanup, bool classInitialize, bool classCleanup, bool test) + private static string GetRunSettings(bool fixturesEnabled, bool assemblyInitialize, bool assemblyCleanup, bool classInitialize, bool classCleanup, bool test) => $@" diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs index 2dd83c8e23..d0dae9f7c3 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/DiagnosticTests.cs @@ -194,7 +194,7 @@ public async Task Diag_EnableWithEnvironmentVariables_Disable_Succeeded(string t testHostResult.AssertOutputContains("Diagnostic file"); } - private async Task AssertDiagnosticReportWasGeneratedAsync(TestHostResult testHostResult, string diagPathPattern, string level = "Trace", string flushType = "async") + private static async Task AssertDiagnosticReportWasGeneratedAsync(TestHostResult testHostResult, string diagPathPattern, string level = "Trace", string flushType = "async") { testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); @@ -218,7 +218,7 @@ private async Task AssertDiagnosticReportWasGeneratedAsync(TestHostResul return match.Value; } - private async Task<(bool IsMatch, string Content)> CheckDiagnosticContentsMatchAsync(string path, string pattern) + private static async Task<(bool IsMatch, string Content)> CheckDiagnosticContentsMatchAsync(string path, string pattern) { using var reader = new StreamReader(path); string content = await reader.ReadToEndAsync(); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs index 919edc355b..53abc787a6 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TelemetryTests.cs @@ -110,7 +110,7 @@ public async Task Telemetry_WhenEnableTelemetryIsFalse_WithTestApplicationOption await AssertDiagnosticReportAsync(testHostResult, diagPathPattern, diagContentsPattern); } - private async Task AssertDiagnosticReportAsync(TestHostResult testHostResult, string diagPathPattern, string diagContentsPattern, string level = "Trace", string flushType = "async") + private static async Task AssertDiagnosticReportAsync(TestHostResult testHostResult, string diagPathPattern, string diagContentsPattern, string level = "Trace", string flushType = "async") { testHostResult.AssertExitCodeIs(ExitCodes.ZeroTests); @@ -126,7 +126,7 @@ private async Task AssertDiagnosticReportAsync(TestHostResult testHostRe return match.Value; } - private async Task<(bool IsMatch, string Content)> CheckDiagnosticContentsMatchAsync(string path, string pattern) + private static async Task<(bool IsMatch, string Content)> CheckDiagnosticContentsMatchAsync(string path, string pattern) { using var reader = new StreamReader(path); string content = await reader.ReadToEndAsync(); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs index 1a47db5bac..806eac1bf4 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs @@ -188,7 +188,7 @@ private async Task AssertTrxReportWasGeneratedAsync(TestHostResult testHostResul Assert.IsTrue(await CheckTrxContentsMatchAsync(match.Value, trxContentsPattern), $"Output of the test host is:\n{testHostResult}"); } - private async Task CheckTrxContentsMatchAsync(string path, string pattern) + private static async Task CheckTrxContentsMatchAsync(string path, string pattern) { using StreamReader reader = new(path); return Regex.IsMatch(await reader.ReadToEndAsync(), pattern); diff --git a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs index 227e25def8..42fcd0507a 100644 --- a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs +++ b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs @@ -246,7 +246,7 @@ public void GetSpecificCustomAttributesOnAssemblyShouldReturnAllAttributes() GetAttributeValuePairs(attributes).Should().Equal(expectedAttributes); } - private Assembly ReflectionOnlyOnResolve(object sender, ResolveEventArgs args) + private static Assembly ReflectionOnlyOnResolve(object sender, ResolveEventArgs args) { string assemblyNameToLoad = AppDomain.CurrentDomain.ApplyPolicy(args.Name); diff --git a/test/Performance/MSTest.Performance.Runner/Steps/PerfviewRunner.cs b/test/Performance/MSTest.Performance.Runner/Steps/PerfviewRunner.cs index f83747c6c2..a0d46e9866 100644 --- a/test/Performance/MSTest.Performance.Runner/Steps/PerfviewRunner.cs +++ b/test/Performance/MSTest.Performance.Runner/Steps/PerfviewRunner.cs @@ -103,7 +103,7 @@ public async Task ExecuteAsync(BuildArtifact payload, IContext context) return new Files([sample]); } - private async Task PerfviewExecutable() + private static async Task PerfviewExecutable() { string localPath = Path.Combine(Path.GetTempPath(), "PerfView", "PerfView.exe"); Directory.CreateDirectory(Path.GetDirectoryName(localPath)!); diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs index eddebfd38a..069d599c3e 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestFixtureMethodSuppressorTests.cs @@ -114,7 +114,7 @@ public override void Initialize(AnalysisContext context) context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.Method); } - private void AnalyzeSymbol(SymbolAnalysisContext context) + private static void AnalyzeSymbol(SymbolAnalysisContext context) { var method = (IMethodSymbol)context.Symbol; if (method.Name.EndsWith("Async", StringComparison.Ordinal)) diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs index e40a874a3e..ba566c293c 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseAsyncSuffixTestMethodSuppressorTests.cs @@ -117,7 +117,7 @@ public override void Initialize(AnalysisContext context) context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.Method); } - private void AnalyzeSymbol(SymbolAnalysisContext context) + private static void AnalyzeSymbol(SymbolAnalysisContext context) { var method = (IMethodSymbol)context.Symbol; if (method.Name.EndsWith("Async", StringComparison.Ordinal)) diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/UnitTestDiscovererTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/UnitTestDiscovererTests.cs index ecc7419286..24905444fa 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Discovery/UnitTestDiscovererTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Discovery/UnitTestDiscovererTests.cs @@ -367,7 +367,7 @@ private void SetupNavigation(string source, UnitTestElement test, string classNa SetTestCaseNavigationData(testCase1, testNavigationData.FileName, testNavigationData.MinLineNumber); } - private void SetTestCaseNavigationData(TestCase testCase, string fileName, int lineNumber) + private static void SetTestCaseNavigationData(TestCase testCase, string fileName, int lineNumber) { testCase.LineNumber = lineNumber; testCase.CodeFilePath = fileName; diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs index b7b13af569..400d28d913 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodInfoTests.cs @@ -1531,7 +1531,7 @@ public void ResolveArgumentsShouldReturnPopulatedParamsWithAllProvided() #region helper methods - private void RunWithTestablePlatformService(TestablePlatformServiceProvider testablePlatformServiceProvider, Action action) + private static void RunWithTestablePlatformService(TestablePlatformServiceProvider testablePlatformServiceProvider, Action action) { try { diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationExtensionsTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationExtensionsTests.cs index 0727d1d90b..5e2b7f22c2 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationExtensionsTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/Configuration/ConfigurationExtensionsTests.cs @@ -10,7 +10,7 @@ namespace Microsoft.Testing.Platform.UnitTests; [TestClass] public sealed class ConfigurationExtensionsTests { - private string GetActualValueFromConfiguration(IConfiguration configuration, string key) => key switch + private static string GetActualValueFromConfiguration(IConfiguration configuration, string key) => key switch { PlatformConfigurationConstants.PlatformResultDirectory => configuration.GetTestResultDirectory(), PlatformConfigurationConstants.PlatformCurrentWorkingDirectory => configuration.GetCurrentWorkingDirectory(), diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs index 1e99ae1ed8..3e96e5919a 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/FormatterUtilitiesTests.cs @@ -103,7 +103,7 @@ public void DeserializeSpecificTypes(Type type) } } - private void AssertRequestArgs(Type type, TRequestArgs actualRequest, TRequestArgs expectedRequest) + private static void AssertRequestArgs(Type type, TRequestArgs actualRequest, TRequestArgs expectedRequest) where TRequestArgs : RequestArgsBase { Assert.AreEqual(expectedRequest.RunId, actualRequest.RunId); diff --git a/test/Utilities/Automation.CLI/CLITestBase.e2e.cs b/test/Utilities/Automation.CLI/CLITestBase.e2e.cs index edb40bb821..ebbdedaae4 100644 --- a/test/Utilities/Automation.CLI/CLITestBase.e2e.cs +++ b/test/Utilities/Automation.CLI/CLITestBase.e2e.cs @@ -79,7 +79,7 @@ public static string GetNugetPackageFolder() /// Gets the path to vstest.console.exe. /// /// Full path to vstest.console.exe. - public string GetConsoleRunnerPath() + public static string GetConsoleRunnerPath() { string testPlatformNuGetPackageFolder = Path.Combine( GetNugetPackageFolder(), diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxer.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxer.cs index cb798a263e..83c6254b02 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxer.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxer.cs @@ -107,7 +107,7 @@ public async Task ExecuteAsync( cleanDefaultEnvironmentVariableIfCustomAreProvided: true, timeoutInSeconds: timeoutInSeconds); - private IDictionary MergeEnvironmentVariables( + private static IDictionary MergeEnvironmentVariables( IDictionary environmentVariables1, IDictionary environmentVariables2) { From 9e071211eb6e7388480c81a70d04bf26673f8afc Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 9 Jan 2025 09:17:41 +0100 Subject: [PATCH 257/273] Cleanup unnecessary await CompletedTask (#4562) --- .../AppInsightsProvider.cs | 8 ++++++-- .../Helpers/DisposeHelper.cs | 2 -- .../OutputDevice/TerminalOutputDevice.cs | 14 +++++--------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs index 9bce278cf3..1ba3d3a7dc 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs @@ -269,13 +269,17 @@ private static System.Text.RegularExpressions.Regex GetValidHashPattern() #endif #endif - public async Task LogEventAsync(string eventName, IDictionary paramsMap) + public +#if NETCOREAPP + async +#endif + Task LogEventAsync(string eventName, IDictionary paramsMap) { #if NETCOREAPP await _payloads.Writer.WriteAsync((eventName, paramsMap)); #else _payloads.Add((eventName, paramsMap)); - await Task.CompletedTask; + return Task.CompletedTask; #endif } diff --git a/src/Platform/Microsoft.Testing.Platform/Helpers/DisposeHelper.cs b/src/Platform/Microsoft.Testing.Platform/Helpers/DisposeHelper.cs index 8b588b8877..5ff940fa0b 100644 --- a/src/Platform/Microsoft.Testing.Platform/Helpers/DisposeHelper.cs +++ b/src/Platform/Microsoft.Testing.Platform/Helpers/DisposeHelper.cs @@ -36,8 +36,6 @@ public static async Task DisposeAsync(object? obj) { dcDisposable.Dispose(); } - - await Task.CompletedTask; #endif } } diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs index f5424d4ede..aef2c5bd24 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/TerminalOutputDevice.cs @@ -394,19 +394,13 @@ public async Task DisplayAsync(IOutputDeviceDataProducer producer, IOutputDevice } } - public async Task ConsumeAsync(IDataProducer dataProducer, IData value, CancellationToken cancellationToken) + public Task ConsumeAsync(IDataProducer dataProducer, IData value, CancellationToken cancellationToken) { RoslynDebug.Assert(_terminalTestReporter is not null); - if (_isServerMode) - { - return; - } - - await Task.CompletedTask; - if (cancellationToken.IsCancellationRequested) + if (_isServerMode || cancellationToken.IsCancellationRequested) { - return; + return Task.CompletedTask; } switch (value) @@ -587,6 +581,8 @@ public async Task ConsumeAsync(IDataProducer dataProducer, IData value, Cancella _testRequestExecutionTimeInfo = testRequestExecutionTimeInfo; break; } + + return Task.CompletedTask; } public void Dispose() From f3bf1a51561ba53ca00925cf3e299646b083b2b2 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 9 Jan 2025 20:20:08 +1100 Subject: [PATCH 258/273] remove redundant conditional compilation in TypeCache (#4569) --- src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs index 63997f4b6b..2b13c8384d 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TypeCache.cs @@ -195,11 +195,7 @@ private static bool TryGetUnescapedManagedTypeName(TestMethod testMethod, [NotNu continue; } -#if NETCOREAPP || WINDOWS_UWP if (hierarchyPart.StartsWith('\'') && hierarchyPart.EndsWith('\'')) -#else - if (hierarchyPart.StartsWith("'", StringComparison.Ordinal) && hierarchyPart.EndsWith("'", StringComparison.Ordinal)) -#endif { unescapedTypeNameBuilder.Append(hierarchyPart, 1, hierarchyPart.Length - 2); } From 22edf6dbed24ba74ae92ce8094db32078795f81b Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 9 Jan 2025 21:12:44 +1100 Subject: [PATCH 259/273] deconstruct some KeyValuePair (#4573) --- .../Execution/TestExecutionManager.cs | 8 ++++---- .../Utilities/DeploymentItemUtility.cs | 4 ++-- .../RoslynAnalyzerHelpers/ArrayBuilder.cs | 4 ++-- .../AppInsightsProvider.cs | 8 ++++---- .../Messages/AsynchronousMessageBus.cs | 4 ++-- .../Serializers/HandshakeMessageSerializer.cs | 6 +++--- .../ServerMode/JsonRpc/SerializerUtilities.cs | 18 +++++++++--------- .../PipelinesRunner.cs | 4 ++-- .../DotnetMuxer.cs | 4 ++-- .../ProcessFactory.cs | 6 +++--- 10 files changed, 33 insertions(+), 33 deletions(-) diff --git a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs index fbcf98fd67..a238267e72 100644 --- a/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs +++ b/src/Adapter/MSTest.TestAdapter/Execution/TestExecutionManager.cs @@ -513,15 +513,15 @@ private void ExecuteTestsWithTestRunner( var testContextProperties = new Dictionary(capacity: 8); // Add tcm properties. - foreach (KeyValuePair propertyPair in tcmProperties) + foreach ((TestProperty key, object? value) in tcmProperties) { - testContextProperties[propertyPair.Key.Id] = propertyPair.Value; + testContextProperties[key.Id] = value; } // Add source level parameters. - foreach (KeyValuePair propertyPair in sourceLevelParameters) + foreach ((string key, object value) in sourceLevelParameters) { - testContextProperties[propertyPair.Key] = propertyPair.Value; + testContextProperties[key] = value; } return testContextProperties; diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs index d8f2c5428f..6cf7c7fade 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/DeploymentItemUtility.cs @@ -259,9 +259,9 @@ private static List GetDeploymentItems(IEnumerable deploymentIte IList result = new List(); - foreach (KeyValuePair deploymentItemData in deploymentItemsData) + foreach ((string? key, string? value) in deploymentItemsData) { - AddDeploymentItem(result, new DeploymentItem(deploymentItemData.Key, deploymentItemData.Value)); + AddDeploymentItem(result, new DeploymentItem(key, value)); } return result; diff --git a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ArrayBuilder.cs b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ArrayBuilder.cs index c033cd70fc..c066d9e519 100644 --- a/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ArrayBuilder.cs +++ b/src/Analyzers/MSTest.Analyzers/RoslynAnalyzerHelpers/ArrayBuilder.cs @@ -322,9 +322,9 @@ internal Dictionary> ToDictionary(Func keySelector var dictionary = new Dictionary>(accumulator.Count, comparer); // freeze - foreach (KeyValuePair> pair in accumulator) + foreach ((K? key, ArrayBuilder? value) in accumulator) { - dictionary.Add(pair.Key, pair.Value.ToImmutableAndFree()); + dictionary.Add(key, value.ToImmutableAndFree()); } return dictionary; diff --git a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs index 1ba3d3a7dc..ded7b1ba1a 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs @@ -195,14 +195,14 @@ private async Task IngestLoopAsync() { StringBuilder builder = new(); builder.AppendLine(CultureInfo.InvariantCulture, $"Send telemetry event: {eventName}"); - foreach (KeyValuePair keyValue in properties) + foreach ((string key, string value) in properties) { - builder.AppendLine(CultureInfo.InvariantCulture, $" {keyValue.Key}: {keyValue.Value}"); + builder.AppendLine(CultureInfo.InvariantCulture, $" {key}: {value}"); } - foreach (KeyValuePair keyValue in metrics) + foreach ((string key, double value) in metrics) { - builder.AppendLine(CultureInfo.InvariantCulture, $" {keyValue.Key}: {keyValue.Value.ToString("f", CultureInfo.InvariantCulture)}"); + builder.AppendLine(CultureInfo.InvariantCulture, $" {key}: {value.ToString("f", CultureInfo.InvariantCulture)}"); } await _logger.LogTraceAsync(builder.ToString()); diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs b/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs index a1c0e02066..cfa28eb05e 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs @@ -151,9 +151,9 @@ public override async Task DrainDataAsync() StringBuilder builder = new(); builder.Append(CultureInfo.InvariantCulture, $"Publisher/Consumer loop detected during the drain after {stopwatch.Elapsed}.\n{builder}"); - foreach (KeyValuePair keyValuePair in consumerToDrain) + foreach ((AsyncConsumerDataProcessor key, long value) in consumerToDrain) { - builder.AppendLine(CultureInfo.InvariantCulture, $"Consumer '{keyValuePair.Key.DataConsumer}' payload received {keyValuePair.Value}."); + builder.AppendLine(CultureInfo.InvariantCulture, $"Consumer '{key.DataConsumer}' payload received {value}."); } throw new InvalidOperationException(builder.ToString()); diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/HandshakeMessageSerializer.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/HandshakeMessageSerializer.cs index ae2924a6f9..9940477af9 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/HandshakeMessageSerializer.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/DotnetTest/IPC/Serializers/HandshakeMessageSerializer.cs @@ -35,10 +35,10 @@ public void Serialize(object objectToSerialize, Stream stream) } WriteShort(stream, (ushort)handshakeMessage.Properties.Count); - foreach (KeyValuePair property in handshakeMessage.Properties) + foreach ((byte key, string value) in handshakeMessage.Properties) { - WriteField(stream, property.Key); - WriteField(stream, property.Value); + WriteField(stream, key); + WriteField(stream, value); } } } diff --git a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs index f3e486205d..a9ad5812b3 100644 --- a/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs +++ b/src/Platform/Microsoft.Testing.Platform/ServerMode/JsonRpc/SerializerUtilities.cs @@ -219,11 +219,11 @@ static SerializerUtilities() properties[namedKvpStringProperty.Name] = namedKvpStringProperty.Pairs; #else JsonArray collection = []; - foreach (KeyValuePair item in namedKvpStringProperty.Pairs) + foreach ((string? key, string? value) in namedKvpStringProperty.Pairs) { JsonObject o = new() { - { item.Key, item.Value }, + { key, value }, }; collection.Add(o); } @@ -420,11 +420,11 @@ static SerializerUtilities() values[JsonRpcStrings.EnvironmentVariables] = ev.EnvironmentVariables; #else JsonArray collection = []; - foreach (KeyValuePair item in ev.EnvironmentVariables) + foreach ((string? key, string? value) in ev.EnvironmentVariables) { JsonObject o = new() { - { item.Key, item.Value }, + { key, value }, }; collection.Add(o); } @@ -624,17 +624,17 @@ static SerializerUtilities() string displayName = string.Empty; PropertyBag propertyBag = new(); - foreach (KeyValuePair p in properties) + foreach ((string? key, object? value) in properties) { - if (p.Key == JsonRpcStrings.Uid) + if (key == JsonRpcStrings.Uid) { - uid = p.Value as string ?? string.Empty; + uid = value as string ?? string.Empty; continue; } - if (p.Key == JsonRpcStrings.DisplayName) + if (key == JsonRpcStrings.DisplayName) { - displayName = p.Value as string ?? string.Empty; + displayName = value as string ?? string.Empty; continue; } } diff --git a/test/Performance/MSTest.Performance.Runner/PipelinesRunner.cs b/test/Performance/MSTest.Performance.Runner/PipelinesRunner.cs index c9d7214780..bcc2153539 100644 --- a/test/Performance/MSTest.Performance.Runner/PipelinesRunner.cs +++ b/test/Performance/MSTest.Performance.Runner/PipelinesRunner.cs @@ -41,9 +41,9 @@ public int Run(string pipelineNameFilter, IDictionary? parameter { "PipelineName", pipeline.PipelineName }, }; - foreach (KeyValuePair item in parametersBag) + foreach ((string key, object value) in parametersBag) { - pipelinePropertyBag.Add(item.Key, item.Value); + pipelinePropertyBag.Add(key, value); } pipeline.UpdatePropertyBag?.Invoke(pipelinePropertyBag); diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxer.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxer.cs index 83c6254b02..6be55cb242 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxer.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/DotnetMuxer.cs @@ -122,9 +122,9 @@ public async Task ExecuteAsync( } IDictionary mergedEnvironmentVariables = new Dictionary(environmentVariables1); - foreach (KeyValuePair kvp in environmentVariables2) + foreach ((string key, string? value) in environmentVariables2) { - mergedEnvironmentVariables[kvp.Key] = kvp.Value; + mergedEnvironmentVariables[key] = value; } return mergedEnvironmentVariables; diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessFactory.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessFactory.cs index 4b2e600823..a7a7b0a8fa 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessFactory.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/ProcessFactory.cs @@ -31,14 +31,14 @@ public static IProcessHandle Start(ProcessConfiguration config, bool cleanDefaul processStartInfo.EnvironmentVariables.Clear(); } - foreach (KeyValuePair kvp in config.EnvironmentVariables) + foreach ((string key, string? value) in config.EnvironmentVariables) { - if (kvp.Value is null) + if (value is null) { continue; } - processStartInfo.EnvironmentVariables[kvp.Key] = kvp.Value; + processStartInfo.EnvironmentVariables[key] = value; } } From bbce070a58b80033a80b1103f8cd9663828cd0c6 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 9 Jan 2025 21:13:44 +1100 Subject: [PATCH 260/273] use dictionary Values directly when Key is not used (#4574) --- .../Messages/AsynchronousMessageBus.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs b/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs index cfa28eb05e..b473a41956 100644 --- a/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs +++ b/src/Platform/Microsoft.Testing.Platform/Messages/AsynchronousMessageBus.cs @@ -161,9 +161,9 @@ public override async Task DrainDataAsync() totalNumberOfDrainAttempt--; anotherRound = false; - foreach (KeyValuePair> dataTypeConsumer in _dataTypeConsumers) + foreach (List dataProcessors in _dataTypeConsumers.Values) { - foreach (AsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataTypeConsumer.Value) + foreach (AsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataProcessors) { if (!consumerToDrain.TryGetValue(asyncMultiProducerMultiConsumerDataProcessor, out long _)) { @@ -190,9 +190,9 @@ public override async Task DisableAsync() _disabled = true; - foreach (KeyValuePair> dataTypeConsumer in _dataTypeConsumers) + foreach (List dataProcessors in _dataTypeConsumers.Values) { - foreach (AsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataTypeConsumer.Value) + foreach (AsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataProcessors) { await asyncMultiProducerMultiConsumerDataProcessor.CompleteAddingAsync(); } @@ -201,9 +201,9 @@ public override async Task DisableAsync() public override void Dispose() { - foreach (KeyValuePair> dataTypeConsumer in _dataTypeConsumers) + foreach (List dataProcessors in _dataTypeConsumers.Values) { - foreach (AsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataTypeConsumer.Value) + foreach (AsyncConsumerDataProcessor asyncMultiProducerMultiConsumerDataProcessor in dataProcessors) { asyncMultiProducerMultiConsumerDataProcessor.Dispose(); } From 07b52ea8ef1408a1634d9504f1a0f4120fe8e7b1 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 9 Jan 2025 11:34:49 +0100 Subject: [PATCH 261/273] Update CODEOWNERS (#4576) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2874056945..341dcc1fb6 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-code-owners src/Package/MSTest.Sdk @MarcoRossignoli -src/Platform @MarcoRossignoli @Evangelink +src/Platform @MarcoRossignoli @Youssef1313 @Evangelink From b9eda748aa1752a6d97fd6e269cb459f61f84040 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 9 Jan 2025 22:14:58 +1100 Subject: [PATCH 262/273] inline string literals (#4578) --- .../Services/MSTestAdapterSettings.cs | 2 +- .../Execution/TestMethodFilterTests.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs b/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs index f2e745a748..f8af181afd 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Services/MSTestAdapterSettings.cs @@ -258,7 +258,7 @@ public List GetDirectoryListWithRecursiveProperty(string } else { - warningMessage = $"The Directory: {path}, has following problem: {"This is not an absolute path. A base directory should be provided for this to be used as a relative path."}"; + warningMessage = $"The Directory: {path}, has following problem: This is not an absolute path. A base directory should be provided for this to be used as a relative path."; if (EqtTrace.IsWarningEnabled) { diff --git a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodFilterTests.cs b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodFilterTests.cs index 0d32323d07..5be66c1c2d 100644 --- a/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodFilterTests.cs +++ b/test/UnitTests/MSTestAdapter.UnitTests/Execution/TestMethodFilterTests.cs @@ -58,7 +58,7 @@ public void PropertyProviderValueForInvalidTestCaseReturnsNull() public void PropertyProviderValueForInvalidPropertyNameReturnsNull() { Type type = typeof(DummyTestClassWithTestMethods); - string fullName = $"{type.FullName}.{"TestMethod"}"; + string fullName = $"{type.FullName}.TestMethod"; TestCase testCase = new(fullName, MSTest.TestAdapter.Constants.ExecutorUri, Assembly.GetExecutingAssembly().FullName); object result = _testMethodFilter.PropertyValueProvider(testCase, null); @@ -68,7 +68,7 @@ public void PropertyProviderValueForInvalidPropertyNameReturnsNull() public void PropertyProviderValueForSupportedPropertyNameWhichIsNotSetReturnsNull() { Type type = typeof(DummyTestClassWithTestMethods); - string fullName = $"{type.FullName}.{"TestMethod"}"; + string fullName = $"{type.FullName}.TestMethod"; TestCase testCase = new(fullName, MSTest.TestAdapter.Constants.ExecutorUri, Assembly.GetExecutingAssembly().FullName); object result = _testMethodFilter.PropertyValueProvider(testCase, "Priority"); @@ -78,7 +78,7 @@ public void PropertyProviderValueForSupportedPropertyNameWhichIsNotSetReturnsNul public void PropertyProviderValueForValidTestAndSupportedPropertyNameReturnsValue() { Type type = typeof(DummyTestClassWithTestMethods); - string fullName = $"{type.FullName}.{"TestMethod"}"; + string fullName = $"{type.FullName}.TestMethod"; TestCase testCase = new(fullName, MSTest.TestAdapter.Constants.ExecutorUri, Assembly.GetExecutingAssembly().FullName); From ef3b9855efb3f5d21c8c40d8eecaa3565f0941bb Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 9 Jan 2025 12:16:29 +0100 Subject: [PATCH 263/273] Fix ExpectedException codefix to handle few edge cases (#4560) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- .../AvoidExpectedExceptionAttributeFixer.cs | 85 +++- ...ExpectedExceptionAttributeAnalyzerTests.cs | 385 +++++++++++++++++- 2 files changed, 457 insertions(+), 13 deletions(-) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidExpectedExceptionAttributeFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidExpectedExceptionAttributeFixer.cs index 07191819bf..ee68f392bb 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidExpectedExceptionAttributeFixer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidExpectedExceptionAttributeFixer.cs @@ -86,6 +86,67 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) diagnostic); } + private static (SyntaxNode ExpressionOrStatement, SyntaxNode NodeToReplace)? TryGetExpressionOfInterestAndNodeToFromBlockSyntax(BlockSyntax? block) + { + if (block is null) + { + return null; + } + + for (int i = block.Statements.Count - 1; i >= 0; i--) + { + StatementSyntax statement = block.Statements[i]; + + if (statement is LockStatementSyntax lockStatement) + { + if (lockStatement.Statement is BlockSyntax lockBlock) + { + if (TryGetExpressionOfInterestAndNodeToFromBlockSyntax(lockBlock) is { } resultFromLock) + { + return resultFromLock; + } + + continue; + } + + statement = lockStatement.Statement; + } + + if (statement is LocalFunctionStatementSyntax or EmptyStatementSyntax) + { + continue; + } + else if (statement is BlockSyntax nestedBlock) + { + if (TryGetExpressionOfInterestAndNodeToFromBlockSyntax(nestedBlock) is { } expressionFromNestedBlock) + { + return expressionFromNestedBlock; + } + + // The BlockSyntax doesn't have any meaningful statements/expressions. + // Ignore it. + continue; + } + else if (statement is ExpressionStatementSyntax expressionStatement) + { + return (expressionStatement.Expression, statement); + } + else if (statement is LocalDeclarationStatementSyntax localDeclarationStatementSyntax && + localDeclarationStatementSyntax.Declaration.Variables.Count == 1 && + localDeclarationStatementSyntax.Declaration.Variables[0].Initializer is { } initializer) + { + return (initializer.Value, statement); + } + + return (statement, statement); + } + + return null; + } + + private static (SyntaxNode ExpressionOrStatement, SyntaxNode NodeToReplace)? TryGetExpressionOfInterestAndNodeToFromExpressionBody(MethodDeclarationSyntax method) + => method.ExpressionBody is null ? null : (method.ExpressionBody.Expression, method.ExpressionBody.Expression); + private static async Task WrapLastStatementWithAssertThrowsExceptionAsync( Document document, MethodDeclarationSyntax methodDeclaration, @@ -97,20 +158,28 @@ private static async Task WrapLastStatementWithAssertThrowsExceptionAs DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); editor.RemoveNode(attributeSyntax); - SyntaxNode? oldStatement = (SyntaxNode?)methodDeclaration.Body?.Statements.LastOrDefault() ?? methodDeclaration.ExpressionBody?.Expression; - if (oldStatement is null) + (SyntaxNode ExpressionOrStatement, SyntaxNode NodeToReplace)? expressionAndNodeToReplace = TryGetExpressionOfInterestAndNodeToFromBlockSyntax(methodDeclaration.Body) + ?? TryGetExpressionOfInterestAndNodeToFromExpressionBody(methodDeclaration); + + if (expressionAndNodeToReplace is null) { return editor.GetChangedDocument(); } - SyntaxNode newLambdaExpression = oldStatement switch + SyntaxGenerator generator = editor.Generator; + SyntaxNode expressionToUseInLambda = expressionAndNodeToReplace.Value.ExpressionOrStatement; + + expressionToUseInLambda = expressionToUseInLambda switch { - ExpressionStatementSyntax oldLambdaExpression => oldLambdaExpression.Expression, - _ => oldStatement, + ThrowStatementSyntax { Expression: not null } throwStatement => generator.ThrowExpression(throwStatement.Expression), + // This is the case when the last statement of the method body is a loop for example (e.g, for, foreach, while, do while). + // It can also happen for using statement, or switch statement. + // In that case, we need to wrap in a block syntax (i.e, curly braces) + StatementSyntax expressionToUseAsStatement => SyntaxFactory.Block(expressionToUseAsStatement), + _ => expressionToUseInLambda.WithoutTrivia(), }; - SyntaxGenerator generator = editor.Generator; - newLambdaExpression = generator.VoidReturningLambdaExpression(newLambdaExpression); + SyntaxNode newLambdaExpression = generator.VoidReturningLambdaExpression(expressionToUseInLambda); bool containsAsyncCode = newLambdaExpression.DescendantNodesAndSelf().Any(n => n is AwaitExpressionSyntax); if (containsAsyncCode) @@ -142,7 +211,7 @@ private static async Task WrapLastStatementWithAssertThrowsExceptionAs newStatement = generator.ExpressionStatement(newStatement); } - editor.ReplaceNode(oldStatement, newStatement); + editor.ReplaceNode(expressionAndNodeToReplace.Value.NodeToReplace, newStatement.WithTriviaFrom(expressionAndNodeToReplace.Value.NodeToReplace)); return editor.GetChangedDocument(); } } diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs index ff8dc63b1a..ddc024ba3e 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidExpectedExceptionAttributeAnalyzerTests.cs @@ -450,11 +450,10 @@ public class TestClass public async Task TestMethod() { Console.WriteLine("Hello, world!"); - await Assert.ThrowsExactlyAsync(async () => - // In ideal world, it's best if the codefix can separate await M() to a - // variable, then only wrap M(someVariable) in Assert.ThrowsException - // Let's also have this comment serve as a test for trivia ;) - M(await M())); + // In ideal world, it's best if the codefix can separate await M() to a + // variable, then only wrap M(someVariable) in Assert.ThrowsException + // Let's also have this comment serve as a test for trivia ;) + await Assert.ThrowsExactlyAsync(async () => M(await M())); } private static Task M() => Task.FromResult(0); @@ -465,4 +464,380 @@ await Assert.ThrowsExactlyAsync(async () => await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } + + [TestMethod] + public async Task When_BlockEndsWithLocalFunctions_Should_ConsiderPreviousStatements() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [ExpectedException(typeof(System.Exception))] + [TestMethod] + public void [|TestMethod|]() + { + M1(); + M2(); + + void M1() { } + void M2() { } + } + } + """; + + string fixedCode = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [TestMethod] + public void TestMethod() + { + M1(); + Assert.ThrowsExactly(() => M2()); + + void M1() { } + void M2() { } + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + [TestMethod] + public async Task When_BlockEndsWithLocalVariableDeclaration_Should_NotCrash() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [ExpectedException(typeof(System.Exception))] + [TestMethod] + public void [|TestMethod|]() + { + var x = Console.ReadLine(); + } + } + """; + + string fixedCode = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [TestMethod] + public void TestMethod() + { + Assert.ThrowsExactly(() => Console.ReadLine()); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + [TestMethod] + public async Task When_BlockEndsWithAssignment_Should_NotCrash() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [ExpectedException(typeof(System.Exception))] + [TestMethod] + public void [|TestMethod|]() + { + object x; + x = Console.ReadLine(); + } + + [ExpectedException(typeof(System.Exception))] + [TestMethod] + public void [|TestMethod2|]() + { + _ = Console.ReadLine(); + } + } + """; + + string fixedCode = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [TestMethod] + public void TestMethod() + { + object x; + Assert.ThrowsExactly(() => x = Console.ReadLine()); + } + + [TestMethod] + public void TestMethod2() + { + Assert.ThrowsExactly(() => _ = Console.ReadLine()); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + [TestMethod] + public async Task When_BlockEndsWithNestedBlocks_Should_NotCrash() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [ExpectedException(typeof(System.Exception))] + [TestMethod] + public void [|TestMethod|]() + { + object x; + + { + { + } + { + x = Console.ReadLine(); + } + { + } + } + } + } + """; + + string fixedCode = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [TestMethod] + public void TestMethod() + { + object x; + + { + { + } + { + Assert.ThrowsExactly(() => x = Console.ReadLine()); + } + { + } + } + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + [TestMethod] + public async Task When_BlockEndsWithEmptyStatement_Should_BeIgnored() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [ExpectedException(typeof(System.Exception))] + [TestMethod] + public void [|TestMethod|]() + { + Console.WriteLine();; + } + } + """; + + string fixedCode = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [TestMethod] + public void TestMethod() + { + Assert.ThrowsExactly(() => Console.WriteLine()); ; + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + [TestMethod] + public async Task When_BlockEndsWithForEach_Should_NotCrash() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [ExpectedException(typeof(System.Exception))] + [TestMethod] + public void [|TestMethod|]() + { + foreach (var x in new[] { 1, 2, 3 }) + { + Console.WriteLine(x); + } + } + } + """; + + // TODO: Formatting is so broken here. + // See https://github.com/microsoft/testfx/issues/4570 + string fixedCode = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [TestMethod] + public void TestMethod() + { + Assert.ThrowsExactly(() => + { + foreach (var x in new[] { 1, 2, 3 }) + { + Console.WriteLine(x); + } + }); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + [TestMethod] + public async Task When_BlockEndsWithThrowStatement_Should_NotBeWrappedInBlock() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [ExpectedException(typeof(System.Exception))] + [TestMethod] + public void [|TestMethod|]() + { + throw new Exception(); + } + } + """; + + string fixedCode = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [TestMethod] + public void TestMethod() + { + Assert.ThrowsExactly(() => throw new Exception()); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } + + [TestMethod] + public async Task When_BlockEndsWithNestedLockStatements_Should_NotCrash() + { + string code = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [ExpectedException(typeof(System.Exception))] + [TestMethod] + public void [|TestMethod|]() + { + object x = new(); + lock (x) + { + lock (x) + { + } + lock (x) + { + Console.WriteLine(); + } + lock (x) + { + } + } + } + } + """; + + string fixedCode = """ + using System; + using Microsoft.VisualStudio.TestTools.UnitTesting; + + [TestClass] + public class TestClass + { + [TestMethod] + public void TestMethod() + { + object x = new(); + lock (x) + { + lock (x) + { + } + lock (x) + { + Assert.ThrowsExactly(() => Console.WriteLine()); + } + lock (x) + { + } + } + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); + } } From cd2ac9350b63496d37f98f75f65cf1b78f7c22db Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Thu, 9 Jan 2025 23:10:16 +1100 Subject: [PATCH 264/273] remove redundant string interpolation (#4571) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Amaury Levé --- samples/Playground/DebuggerUtility.cs | 10 +++--- .../HangDumpActivityIndicator.cs | 8 ++--- .../HangDumpProcessLifetimeHandler.cs | 12 +++---- .../RetryOrchestrator.cs | 2 +- .../AppInsightsProvider.cs | 4 +-- .../Tasks/ConfigurationFileTask.cs | 4 +-- .../Tasks/DotnetMuxerLocator.cs | 16 ++++----- .../Tasks/TestingPlatformEntryPointTask.cs | 6 ++-- .../Builder/TestApplication.cs | 2 +- .../Hosts/TestHostControllersTestHost.cs | 8 ++--- .../Terminal/TerminalTestReporter.cs | 2 +- .../Telemetry/TelemetryProperties.cs | 4 +-- .../SdkTests.cs | 2 +- .../ServerModeTests.cs | 8 ++--- .../HelpInfoTests.cs | 4 +-- .../MSBuildTests.Test.cs | 2 +- .../ServerLoggingTests.cs | 2 +- .../TrxTests.cs | 4 +-- .../TestClassShouldBeValidAnalyzerTests.cs | 3 +- .../TestContextShouldBeValidAnalyzerTests.cs | 33 +++++++++++-------- .../TestMethodShouldBeValidAnalyzerTests.cs | 6 ++-- .../ObjectModel/RunContextAdapterTests.cs | 4 +-- .../ObjectModel/RunSettingsPatcherTests.cs | 2 +- .../Terminal/TerminalTestReporterTests.cs | 2 +- .../ServerMode/ServerTests.cs | 6 ++-- .../Automation.CLI/CLITestBase.common.cs | 2 +- .../DebuggerUtility.cs | 10 +++--- 27 files changed, 89 insertions(+), 79 deletions(-) diff --git a/samples/Playground/DebuggerUtility.cs b/samples/Playground/DebuggerUtility.cs index 5070a073d9..babb647424 100644 --- a/samples/Playground/DebuggerUtility.cs +++ b/samples/Playground/DebuggerUtility.cs @@ -21,7 +21,7 @@ private static bool AttachVSToProcess(int? pid, int? vsPid, bool enableLog = fal { if (pid == null) { - Trace($"FAIL: Pid is null.", enabled: enableLog); + Trace("FAIL: Pid is null.", enabled: enableLog); return false; } @@ -37,7 +37,7 @@ private static bool AttachVSToProcess(int? pid, int? vsPid, bool enableLog = fal return true; } - Trace($"Parent VS not found, finding the first VS that started.", enabled: enableLog); + Trace("Parent VS not found, finding the first VS that started.", enabled: enableLog); Process? firstVsProcess = GetFirstVsProcess(); if (firstVsProcess != null) @@ -122,21 +122,21 @@ private static bool AttachVs(Process vs, int pid, bool enableLog = false) Marshal.ThrowExceptionForHR(r); if (bindCtx == null) { - Trace($"BindCtx is null. Cannot attach VS.", enabled: enableLog); + Trace("BindCtx is null. Cannot attach VS.", enabled: enableLog); return false; } bindCtx.GetRunningObjectTable(out runningObjectTable); if (runningObjectTable == null) { - Trace($"RunningObjectTable is null. Cannot attach VS.", enabled: enableLog); + Trace("RunningObjectTable is null. Cannot attach VS.", enabled: enableLog); return false; } runningObjectTable.EnumRunning(out enumMoniker); if (enumMoniker == null) { - Trace($"EnumMoniker is null. Cannot attach VS.", enabled: enableLog); + Trace("EnumMoniker is null. Cannot attach VS.", enabled: enableLog); return false; } diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpActivityIndicator.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpActivityIndicator.cs index 9e3875463e..9469725e51 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpActivityIndicator.cs +++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpActivityIndicator.cs @@ -127,7 +127,7 @@ await _namedPipeClient.RequestReplyAsync( // Wait the connection from the testhost controller await _singleConnectionNamedPipeServer.WaitConnectionAsync(cancellationToken).TimeoutAfterAsync(TimeoutHelper.DefaultHangTimeSpanTimeout, cancellationToken); - await _logger.LogTraceAsync($"Test host controller connected"); + await _logger.LogTraceAsync("Test host controller connected"); } catch (OperationCanceledException ex) when (ex.CancellationToken == cancellationToken) { @@ -224,7 +224,7 @@ private Task SignalActivityIndicatorAsync() _signalActivity.Reset(); } - _logger.LogDebug($"Exit 'SignalActivityIndicatorAsync'"); + _logger.LogDebug("Exit 'SignalActivityIndicatorAsync'"); return Task.CompletedTask; } @@ -242,10 +242,10 @@ public async Task OnTestSessionFinishingAsync(SessionUid sessionUid, Cancellatio await _namedPipeClient.RequestReplyAsync(new SessionEndSerializerRequest(), cancellationToken) .TimeoutAfterAsync(TimeoutHelper.DefaultHangTimeSpanTimeout, cancellationToken); - await _logger.LogDebugAsync($"Signal for test session end'"); + await _logger.LogDebugAsync("Signal for test session end'"); await ExitSignalActivityIndicatorTaskAsync(); - await _logger.LogTraceAsync($"Signaled by process for it's exit"); + await _logger.LogTraceAsync("Signaled by process for it's exit"); _sessionEndCalled = true; } diff --git a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs index 42623822c7..548b15f972 100644 --- a/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs +++ b/src/Platform/Microsoft.Testing.Extensions.HangDump/HangDumpProcessLifetimeHandler.cs @@ -144,7 +144,7 @@ private async Task CallbackAsync(IRequest request) } else if (request is SessionEndSerializerRequest) { - await _logger.LogDebugAsync($"Session end received by the test host"); + await _logger.LogDebugAsync("Session end received by the test host"); _exitActivityIndicatorTask = true; #if NET if (_namedPipeClient is not null) @@ -220,7 +220,7 @@ public async Task OnTestHostProcessExitedAsync(ITestHostProcessInformation testH private async Task ActivityTimerAsync() { - _logger.LogDebug($"Wait for mutex name from the test host"); + _logger.LogDebug("Wait for mutex name from the test host"); if (!_mutexNameReceived.Wait(TimeoutHelper.DefaultHangTimeSpanTimeout)) { @@ -244,7 +244,7 @@ private async Task ActivityTimerAsync() { if (_traceEnabled) { - _logger.LogTrace($"Wait for activity signal"); + _logger.LogTrace("Wait for activity signal"); } if (!_activityIndicatorMutex.WaitOne(_activityTimerValue)) @@ -271,7 +271,7 @@ private async Task ActivityTimerAsync() if (_traceEnabled) { - _logger.LogTrace($"Exit 'ActivityTimerAsync'"); + _logger.LogTrace("Exit 'ActivityTimerAsync'"); } } catch (AbandonedMutexException) @@ -290,7 +290,7 @@ private async Task ActivityTimerAsync() { try { - _logger.LogDebug($"Timeout is not fired release activity mutex handle to allow test host to close"); + _logger.LogDebug("Timeout is not fired release activity mutex handle to allow test host to close"); _activityIndicatorMutex.ReleaseMutex(); } catch (AbandonedMutexException) @@ -306,7 +306,7 @@ private async Task ActivityTimerAsync() } _activityIndicatorMutex.Dispose(); - _logger.LogDebug($"Activity indicator disposed"); + _logger.LogDebug("Activity indicator disposed"); if (timeoutFired) { diff --git a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs index 219bf3121d..4117a5b75e 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Retry/RetryOrchestrator.cs @@ -198,7 +198,7 @@ public async Task OrchestrateTestHostExecutionAsync() using (var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, _serviceProvider.GetTestApplicationCancellationTokenSource().CancellationToken)) using (var linkedToken2 = CancellationTokenSource.CreateLinkedTokenSource(linkedToken.Token, processExitedCancellationToken.Token)) { - await logger.LogDebugAsync($"Wait connection from the test host process"); + await logger.LogDebugAsync("Wait connection from the test host process"); try { #if NETCOREAPP diff --git a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs index ded7b1ba1a..adb1e49b76 100644 --- a/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs +++ b/src/Platform/Microsoft.Testing.Extensions.Telemetry/AppInsightsProvider.cs @@ -131,7 +131,7 @@ private async Task IngestLoopAsync() { _client = null; - await _logger.LogErrorAsync($"Failed to initialize telemetry client", e); + await _logger.LogErrorAsync("Failed to initialize telemetry client", e); return; } @@ -219,7 +219,7 @@ private async Task IngestLoopAsync() // We could do better back-pressure. if (_logger.IsEnabled(LogLevel.Error) && (!lastLoggedError.HasValue || (lastLoggedError.Value - _clock.UtcNow).TotalSeconds > 3)) { - await _logger.LogErrorAsync($"Error during telemetry report.", ex); + await _logger.LogErrorAsync("Error during telemetry report.", ex); lastLoggedError = _clock.UtcNow; } } diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/ConfigurationFileTask.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/ConfigurationFileTask.cs index 475d6fa3a3..d3761b1970 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/ConfigurationFileTask.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/ConfigurationFileTask.cs @@ -45,7 +45,7 @@ public override bool Execute() Log.LogMessage(MessageImportance.Normal, $"Microsoft Testing Platform configuration file: '{TestingPlatformConfigurationFileSource.ItemSpec}'"); if (!_fileSystem.Exist(TestingPlatformConfigurationFileSource.ItemSpec)) { - Log.LogMessage(MessageImportance.Normal, $"Microsoft Testing Platform configuration file not found"); + Log.LogMessage(MessageImportance.Normal, "Microsoft Testing Platform configuration file not found"); return true; } @@ -62,7 +62,7 @@ public override bool Execute() Log.LogMessage(MessageImportance.Normal, $"Configuration file found: '{TestingPlatformConfigurationFileSource.ItemSpec}'"); _fileSystem.CopyFile(TestingPlatformConfigurationFileSource.ItemSpec, finalFileName); FinalTestingPlatformConfigurationFile = new TaskItem(finalFileName); - Log.LogMessage(MessageImportance.Normal, $"Microsoft Testing Platform configuration file written"); + Log.LogMessage(MessageImportance.Normal, "Microsoft Testing Platform configuration file written"); return true; } diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs index 11a28f280b..b54ea3236e 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/DotnetMuxerLocator.cs @@ -82,7 +82,7 @@ public bool TryGetDotnetPathByArchitecture( if ((envVar == null || !Directory.Exists(envVar)) && targetArchitecture == PlatformArchitecture.X86 && isWinOs) { - envKey = $"DOTNET_ROOT(x86)"; + envKey = "DOTNET_ROOT(x86)"; envVar = Environment.GetEnvironmentVariable(envKey); } @@ -124,7 +124,7 @@ public bool TryGetDotnetPathByArchitecture( } } - _resolutionLog($"DotnetHostHelper.TryGetDotnetPathByArchitecture: Muxer was not found using DOTNET_ROOT* env variables."); + _resolutionLog("DotnetHostHelper.TryGetDotnetPathByArchitecture: Muxer was not found using DOTNET_ROOT* env variables."); // Try to search for global registration muxerPath = isWinOs ? GetMuxerFromGlobalRegistrationWin(targetArchitecture) : GetMuxerFromGlobalRegistrationOnUnix(targetArchitecture); @@ -151,7 +151,7 @@ public bool TryGetDotnetPathByArchitecture( return true; } - _resolutionLog($"DotnetHostHelper.TryGetDotnetPathByArchitecture: Muxer not found using global registrations"); + _resolutionLog("DotnetHostHelper.TryGetDotnetPathByArchitecture: Muxer not found using global registrations"); // Try searching in default installation location if it exists if (isWinOs) @@ -219,14 +219,14 @@ public bool TryGetDotnetPathByArchitecture( using var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32); if (hklm == null) { - _resolutionLog($@"DotnetHostHelper.GetMuxerFromGlobalRegistrationWin: Missing SOFTWARE\dotnet\Setup\InstalledVersions subkey"); + _resolutionLog(@"DotnetHostHelper.GetMuxerFromGlobalRegistrationWin: Missing SOFTWARE\dotnet\Setup\InstalledVersions subkey"); return null; } using RegistryKey? dotnetInstalledVersion = hklm.OpenSubKey(@"SOFTWARE\dotnet\Setup\InstalledVersions"); if (dotnetInstalledVersion == null) { - _resolutionLog($@"DotnetHostHelper.GetMuxerFromGlobalRegistrationWin: Missing RegistryHive.LocalMachine for RegistryView.Registry32"); + _resolutionLog(@"DotnetHostHelper.GetMuxerFromGlobalRegistrationWin: Missing RegistryHive.LocalMachine for RegistryView.Registry32"); return null; } @@ -234,7 +234,7 @@ public bool TryGetDotnetPathByArchitecture( string? installLocation = nativeArch?.GetValue("InstallLocation")?.ToString(); if (installLocation == null) { - _resolutionLog($@"DotnetHostHelper.GetMuxerFromGlobalRegistrationWin: Missing registry InstallLocation"); + _resolutionLog(@"DotnetHostHelper.GetMuxerFromGlobalRegistrationWin: Missing registry InstallLocation"); return null; } @@ -307,7 +307,7 @@ public bool TryGetDotnetPathByArchitecture( // Check if the offset is invalid if (peHeader > fs.Length - 5) { - resolutionLog($"[GetMuxerArchitectureByPEHeaderOnWin]Invalid offset"); + resolutionLog("[GetMuxerArchitectureByPEHeaderOnWin]Invalid offset"); validImage = false; } @@ -321,7 +321,7 @@ public bool TryGetDotnetPathByArchitecture( if (reader.ReadUInt32() != 0x00004550) { validImage = false; - resolutionLog($"[GetMuxerArchitectureByPEHeaderOnWin]Missing PE signature"); + resolutionLog("[GetMuxerArchitectureByPEHeaderOnWin]Missing PE signature"); } if (validImage) diff --git a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformEntryPointTask.cs b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformEntryPointTask.cs index ec44b532d6..7620da93eb 100644 --- a/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformEntryPointTask.cs +++ b/src/Platform/Microsoft.Testing.Platform.MSBuild/Tasks/TestingPlatformEntryPointTask.cs @@ -72,7 +72,7 @@ private static string GetEntryPointSourceCode(string language) { if (language == CSharpLanguageSymbol) { - return $$""" + return """ //------------------------------------------------------------------------------ // // This code was generated by Microsoft.Testing.Platform.MSBuild @@ -96,7 +96,7 @@ internal sealed class TestingPlatformEntryPoint } else if (language == VBLanguageSymbol) { - return $$""" + return """ '------------------------------------------------------------------------------ ' ' This code was generated by Microsoft.Testing.Platform.MSBuild @@ -123,7 +123,7 @@ End Module } else if (language == FSharpLanguageSymbol) { - return $$""" + return """ //------------------------------------------------------------------------------ // // This code was generated by Microsoft.Testing.Platform.MSBuild diff --git a/src/Platform/Microsoft.Testing.Platform/Builder/TestApplication.cs b/src/Platform/Microsoft.Testing.Platform/Builder/TestApplication.cs index 63ace972e3..75ae412209 100644 --- a/src/Platform/Microsoft.Testing.Platform/Builder/TestApplication.cs +++ b/src/Platform/Microsoft.Testing.Platform/Builder/TestApplication.cs @@ -127,7 +127,7 @@ private static async Task LogInformationAsync( } else { - await logger.LogInformationAsync($"Version attribute not found"); + await logger.LogInformationAsync("Version attribute not found"); } await logger.LogInformationAsync("Logging mode: " + (syncWrite ? "synchronous" : "asynchronous")); diff --git a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs index 90bab575d7..6eac525c93 100644 --- a/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs +++ b/src/Platform/Microsoft.Testing.Platform/Hosts/TestHostControllersTestHost.cs @@ -223,7 +223,7 @@ protected override async Task InternalRunAsync() string testHostProcessStartupTime = _clock.UtcNow.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture); processStartInfo.EnvironmentVariables.Add($"{EnvironmentVariableConstants.TESTINGPLATFORM_TESTHOSTCONTROLLER_TESTHOSTPROCESSSTARTTIME}_{currentPID}", testHostProcessStartupTime); await _logger.LogDebugAsync($"{EnvironmentVariableConstants.TESTINGPLATFORM_TESTHOSTCONTROLLER_TESTHOSTPROCESSSTARTTIME}_{currentPID} '{testHostProcessStartupTime}'"); - await _logger.LogDebugAsync($"Starting test host process"); + await _logger.LogDebugAsync("Starting test host process"); using IProcess testHostProcess = process.Start(processStartInfo); int? testHostProcessId = null; @@ -250,7 +250,7 @@ protected override async Task InternalRunAsync() using (CancellationTokenSource timeout = new(TimeSpan.FromSeconds(timeoutSeconds))) using (var linkedToken = CancellationTokenSource.CreateLinkedTokenSource(timeout.Token, abortRun)) { - await _logger.LogDebugAsync($"Wait connection from the test host process"); + await _logger.LogDebugAsync("Wait connection from the test host process"); await testHostControllerIpc.WaitConnectionAsync(linkedToken.Token); } @@ -260,7 +260,7 @@ protected override async Task InternalRunAsync() _waitForPid.Wait(timeout.Token); } - await _logger.LogDebugAsync($"Fire OnTestHostProcessStartedAsync"); + await _logger.LogDebugAsync("Fire OnTestHostProcessStartedAsync"); if (_testHostPID is null) { @@ -279,7 +279,7 @@ protected override async Task InternalRunAsync() } } - await _logger.LogDebugAsync($"Wait for test host process exit"); + await _logger.LogDebugAsync("Wait for test host process exit"); await testHostProcess.WaitForExitAsync(); if (_testHostsInformation.LifetimeHandlers.Length > 0) diff --git a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs index c0d4233943..8d9b51950d 100644 --- a/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs +++ b/src/Platform/Microsoft.Testing.Platform/OutputDevice/Terminal/TerminalTestReporter.cs @@ -57,7 +57,7 @@ internal event EventHandler OnProgressStopUpdate #if NET7_0_OR_GREATER // Specifying no timeout, the regex is linear. And the timeout does not measure the regex only, but measures also any // thread suspends, so the regex gets blamed incorrectly. - [GeneratedRegex(@$"^ at ((?.+) in (?.+):line (?\d+)|(?.+))$", RegexOptions.ExplicitCapture)] + [GeneratedRegex(@"^ at ((?.+) in (?.+):line (?\d+)|(?.+))$", RegexOptions.ExplicitCapture)] private static partial Regex GetFrameRegex(); #else private static Regex? s_regex; diff --git a/src/Platform/Microsoft.Testing.Platform/Telemetry/TelemetryProperties.cs b/src/Platform/Microsoft.Testing.Platform/Telemetry/TelemetryProperties.cs index 3de0bc887a..c00cf6f6c7 100644 --- a/src/Platform/Microsoft.Testing.Platform/Telemetry/TelemetryProperties.cs +++ b/src/Platform/Microsoft.Testing.Platform/Telemetry/TelemetryProperties.cs @@ -5,9 +5,9 @@ namespace Microsoft.Testing.Platform.Telemetry; internal static class TelemetryProperties { - public const string VersionPropertyName = $"telemetry version"; + public const string VersionPropertyName = "telemetry version"; public const string SessionId = "session id"; - public const string ReporterIdPropertyName = $"reporter id"; + public const string ReporterIdPropertyName = "reporter id"; public const string IsCIPropertyName = "is ci"; public const string VersionValue = "19"; diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs index ef332f3e8c..8f09d34511 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/SdkTests.cs @@ -297,7 +297,7 @@ public async Task NativeAot_Smoke_Test_Windows() // temporarily set test to be on net9.0 as it's fixing one error that started to happen: error IL3000: System.Net.Quic.MsQuicApi..cctor // see https://github.com/dotnet/sdk/issues/44880. .PatchCodeWithReplace("$TargetFramework$", "net9.0") - .PatchCodeWithReplace("$ExtraProperties$", $""" + .PatchCodeWithReplace("$ExtraProperties$", """ true false """), diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs index 3449eb1a14..154dceb6df 100644 --- a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/ServerModeTests.cs @@ -34,10 +34,10 @@ public async Task DiscoverAndRun(string tfm) ResponseListener runListener = await jsonClient.RunTests(Guid.NewGuid(), runCollector.CollectNodeUpdates); await Task.WhenAll(discoveryListener.WaitCompletion(), runListener.WaitCompletion()); - Assert.AreEqual(1, discoveryCollector.TestNodeUpdates.Count(x => x.Node.NodeType == "action"), $"Wrong number of discovery"); - Assert.AreEqual(2, runCollector.TestNodeUpdates.Count, $"Wrong number of updates"); - Assert.AreNotEqual(0, logs.Count, $"Logs are empty"); - Assert.IsFalse(telemetry.IsEmpty, $"telemetry is empty"); + Assert.AreEqual(1, discoveryCollector.TestNodeUpdates.Count(x => x.Node.NodeType == "action"), "Wrong number of discovery"); + Assert.AreEqual(2, runCollector.TestNodeUpdates.Count, "Wrong number of updates"); + Assert.AreNotEqual(0, logs.Count, "Logs are empty"); + Assert.IsFalse(telemetry.IsEmpty, "telemetry is empty"); await jsonClient.Exit(); Assert.AreEqual(0, await jsonClient.WaitServerProcessExit()); Assert.AreEqual(0, jsonClient.ExitCode); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs index 4006d2af14..52285ac9dc 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/HelpInfoTests.cs @@ -126,7 +126,7 @@ .NET Testing Platform v.+ \[.+\] Version: .+ Dynamic Code Supported: True Runtime information: .+ - {(tfm != TargetFrameworks.NetFramework[0] ? "###SKIP###" : $"Runtime location: .+")} + {(tfm != TargetFrameworks.NetFramework[0] ? "###SKIP###" : "Runtime location: .+")} Test module: .+{TestAssetFixture.NoExtensionAssetName}.* Built-in command line providers: PlatformCommandLineProvider @@ -392,7 +392,7 @@ .NET Testing Platform v* [*] Version: * Dynamic Code Supported: True Runtime information: * - {(tfm != TargetFrameworks.NetFramework[0] ? "###SKIP###" : $"Runtime location: *")} + {(tfm != TargetFrameworks.NetFramework[0] ? "###SKIP###" : "Runtime location: *")} Test module: *{TestAssetFixture.AllExtensionsAssetName}* Built-in command line providers: PlatformCommandLineProvider diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs index fe1344af45..2941e1c4e8 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/MSBuildTests.Test.cs @@ -128,7 +128,7 @@ await DotnetCli.RunAsync( environmentVariables: dotnetRootX86, failIfReturnValueIsNotZero: false); - string outputFileLog = Directory.GetFiles(testAsset.TargetAssetPath, $"MSBuild Tests_net9.0_x86.log", SearchOption.AllDirectories).Single(); + string outputFileLog = Directory.GetFiles(testAsset.TargetAssetPath, "MSBuild Tests_net9.0_x86.log", SearchOption.AllDirectories).Single(); Assert.IsTrue(File.Exists(outputFileLog), $"Expected file '{outputFileLog}'"); string logFileContent = File.ReadAllText(outputFileLog); Assert.IsTrue(Regex.IsMatch(logFileContent, ".*win-x86.*"), logFileContent); diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs index 5327fd60e3..6b01f26fb0 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/ServerLoggingTests.cs @@ -29,7 +29,7 @@ public async Task RunningInServerJsonRpcModeShouldHaveOutputDeviceLogsPushedToTe ResponseListener runListener = await jsonClient.RunTests(Guid.NewGuid(), runCollector.CollectNodeUpdates); await Task.WhenAll(discoveryListener.WaitCompletion(), runListener.WaitCompletion()); - Assert.IsFalse(logs.Count == 0, $"Logs are empty"); + Assert.IsFalse(logs.Count == 0, "Logs are empty"); string logsString = string.Join(Environment.NewLine, logs.Select(l => l.ToString())); string logPath = LogFilePathRegex().Match(logsString).Groups[1].Value; string port = PortRegex().Match(logsString).Groups[1].Value; diff --git a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs index 806eac1bf4..f2f1a5ddca 100644 --- a/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs +++ b/test/IntegrationTests/Microsoft.Testing.Platform.Acceptance.IntegrationTests/TrxTests.cs @@ -150,7 +150,7 @@ public async Task Trx_WhenReportTrxIsSpecifiedWithRelativePath_TrxReportShouldFa public async Task Trx_WhenReportTrxIsNotSpecifiedAndReportTrxPathIsSpecified_ErrorIsDisplayed(string tfm) { var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, TestAssetFixture.AssetName, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync($"--report-trx-filename report.trx"); + TestHostResult testHostResult = await testHost.ExecuteAsync("--report-trx-filename report.trx"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.AssertOutputContains("Error: '--report-trx-filename' requires '--report-trx' to be enabled"); @@ -161,7 +161,7 @@ public async Task Trx_WhenReportTrxIsNotSpecifiedAndReportTrxPathIsSpecified_Err public async Task Trx_WhenReportTrxIsSpecifiedAndListTestsIsSpecified_ErrorIsDisplayed(string tfm) { var testHost = TestInfrastructure.TestHost.LocateFrom(AssetFixture.TargetAssetPath, TestAssetFixture.AssetName, tfm); - TestHostResult testHostResult = await testHost.ExecuteAsync($"--report-trx --list-tests"); + TestHostResult testHostResult = await testHost.ExecuteAsync("--report-trx --list-tests"); testHostResult.AssertExitCodeIs(ExitCodes.InvalidCommandLine); testHostResult.AssertOutputContains("Error: '--report-trx' cannot be enabled when using '--list-tests'"); diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldBeValidAnalyzerTests.cs index b4b74c293a..82c94cc4f3 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestClassShouldBeValidAnalyzerTests.cs @@ -71,7 +71,8 @@ public class OuterClass } """; - string fixedCode = $$""" + string fixedCode = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; public class OuterClass diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs index bba42a6e1e..acd349abd4 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestContextShouldBeValidAnalyzerTests.cs @@ -38,7 +38,8 @@ public class MyTestClass {{accessibility}} TestContext {|#0:{{fieldName}}|}; } """; - string fixedCode = $$""" + string fixedCode = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -110,7 +111,8 @@ public class MyTestClass {{accessibility}} TestContext {|#0:{{propertyName}}|} { get; set; } } """; - string fixedCode = $$""" + string fixedCode = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -287,7 +289,8 @@ public MyTestClass(TestContext testContext) [TestMethod] public async Task WhenTestContextPropertyIsStatic_Diagnostic() { - string code = $$""" + string code = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -296,7 +299,8 @@ public class MyTestClass public static TestContext {|#0:TestContext|} { get; set; } } """; - string fixedCode = $$""" + string fixedCode = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -316,7 +320,8 @@ await VerifyCS.VerifyCodeFixAsync( [TestMethod] public async Task WhenTestContextPropertyIsReadonly_Diagnostic() { - string code = $$""" + string code = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -325,7 +330,8 @@ public class MyTestClass public TestContext {|#0:TestContext|} { get; } } """; - string fixedCode = $$""" + string fixedCode = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -345,7 +351,8 @@ await VerifyCS.VerifyCodeFixAsync( [TestMethod] public async Task WhenTestContextPropertyIsNotCasedCorrectly_Diagnostic() { - string code = $$""" + string code = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -354,7 +361,8 @@ public class MyTestClass public TestContext {|#0:testContext|} { get; set; } } """; - string fixedCode = $$""" + string fixedCode = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -374,7 +382,8 @@ await VerifyCS.VerifyCodeFixAsync( [TestMethod] public async Task WhenTestContextPropertyIsReadonly_AssignedInConstructor_NoDiagnostic() { - string code = $$""" + string code = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -384,7 +393,6 @@ public MyTestClass(TestContext testContext) { TestContext = testContext; } - public TestContext TestContext { get; } } """; @@ -395,19 +403,18 @@ public MyTestClass(TestContext testContext) [TestMethod] public async Task WhenTestContextPropertyIsReadonly_AssignedInConstructorViaField_NoDiagnostic() { - string code = $$""" + string code = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] public class MyTestClass { private readonly TestContext _testContext; - public MyTestClass(TestContext testContext) { _testContext = testContext; } - public TestContext TestContext => _testContext; } """; diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs index 77323cb892..75ba66adbb 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/TestMethodShouldBeValidAnalyzerTests.cs @@ -49,7 +49,8 @@ public class MyTestClass } """; - string fixedCode = $$""" + string fixedCode = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] @@ -68,7 +69,8 @@ public void MyTestMethod() [TestMethod] public async Task WhenMethodIsNotPublicAndNotTestMethod_NoDiagnostic() { - string code = $$""" + string code = + """ using Microsoft.VisualStudio.TestTools.UnitTesting; [TestClass] diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunContextAdapterTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunContextAdapterTests.cs index 20be61bec0..58bcb780a3 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunContextAdapterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunContextAdapterTests.cs @@ -19,7 +19,7 @@ public class RunContextAdapterTests public void TestRunDirectory_IsNotNull_If_ResultsDirectory_Is_Provided() { string runSettings = -$""" +""" /PlatformResultDirectoryFromFile @@ -38,7 +38,7 @@ public void TestRunDirectory_IsNotNull_If_ResultsDirectory_Is_Provided() public void TestRunDirectory_IsNull_If_ResultsDirectory_IsNot_Provided() { string runSettings = -$""" +""" diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs index 1020128690..92c52dbde1 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/RunSettingsPatcherTests.cs @@ -52,7 +52,7 @@ public void Patch_WithRunSettingsProvidedButMissingResultsDirectory_AddsElement( public void Patch_WithRunSettingsContainingResultsDirectory_EntryIsNotOverridden() { string runSettings = -$""" +""" true diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs index 7e9685da11..6692bf7fd5 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/OutputDevice/Terminal/TerminalTestReporterTests.cs @@ -38,7 +38,7 @@ public void AppendStackFrameFormatsStackTraceLineCorrectly() // Code with line when we have symbols [DataRow( " at TestingPlatformEntryPoint.Main(String[]) in /_/TUnit.TestProject/obj/Release/net8.0/osx-x64/TestPlatformEntryPoint.cs:line 16", - $" at TestingPlatformEntryPoint.Main(String[]) in /_/TUnit.TestProject/obj/Release/net8.0/osx-x64/TestPlatformEntryPoint.cs:16")] + " at TestingPlatformEntryPoint.Main(String[]) in /_/TUnit.TestProject/obj/Release/net8.0/osx-x64/TestPlatformEntryPoint.cs:16")] // code without line when we don't have symbols [DataRow( " at TestingPlatformEntryPoint.
(String[])", diff --git a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs index 5eae561595..e2e876c54a 100644 --- a/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs +++ b/test/UnitTests/Microsoft.Testing.Platform.UnitTests/ServerMode/ServerTests.cs @@ -55,7 +55,7 @@ public async Task ServerCanInitialize() { using var server = TcpServer.Create(); - string[] args = ["--no-banner", $"--server", "--client-port", $"{server.Port}", "--internal-testingplatform-skipbuildercheck"]; + string[] args = ["--no-banner", "--server", "--client-port", $"{server.Port}", "--internal-testingplatform-skipbuildercheck"]; TestApplicationHooks testApplicationHooks = new(); ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); builder.TestHost.AddTestApplicationLifecycleCallbacks(_ => testApplicationHooks); @@ -134,7 +134,7 @@ public async Task DiscoveryRequestCanBeCanceled() TaskCompletionSource discoveryStartedTaskCompletionSource = new(); TaskCompletionSource discoveryCanceledTaskCompletionSource = new(); - string[] args = ["--no-banner", $"--server", "--client-port", $"{server.Port}", "--internal-testingplatform-skipbuildercheck"]; + string[] args = ["--no-banner", "--server", "--client-port", $"{server.Port}", "--internal-testingplatform-skipbuildercheck"]; ITestApplicationBuilder builder = await TestApplication.CreateBuilderAsync(args); builder.RegisterTestFramework(_ => new TestFrameworkCapabilities(), (_, __) => new MockTestAdapter { @@ -245,7 +245,7 @@ public async Task DiscoveryRequestCanBeCanceled() private static async Task WriteMessageAsync(StreamWriter writer, string message) { await writer.WriteLineAsync($"Content-Length: {message.Length}"); - await writer.WriteLineAsync($"Content-Type: application/testingplatform"); + await writer.WriteLineAsync("Content-Type: application/testingplatform"); await writer.WriteLineAsync(); await writer.WriteAsync(message); await writer.FlushAsync(); diff --git a/test/Utilities/Automation.CLI/CLITestBase.common.cs b/test/Utilities/Automation.CLI/CLITestBase.common.cs index 2d6da22d70..fdb82562ff 100644 --- a/test/Utilities/Automation.CLI/CLITestBase.common.cs +++ b/test/Utilities/Automation.CLI/CLITestBase.common.cs @@ -35,7 +35,7 @@ protected static XmlDocument ReadCPMFile() protected static string GetTestPlatformVersion() { XmlDocument cpmXml = ReadCPMFile(); - XmlNode testSdkVersion = cpmXml.DocumentElement.SelectSingleNode($"PropertyGroup/MicrosoftNETTestSdkVersion"); + XmlNode testSdkVersion = cpmXml.DocumentElement.SelectSingleNode("PropertyGroup/MicrosoftNETTestSdkVersion"); return testSdkVersion.InnerText; } diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/DebuggerUtility.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/DebuggerUtility.cs index 93f4111b29..2a7839e498 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/DebuggerUtility.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/DebuggerUtility.cs @@ -20,7 +20,7 @@ private static bool AttachVSToProcess(int? pid, int? vsPid, bool enableLog = fal { if (pid == null) { - Trace($"FAIL: Pid is null.", enabled: enableLog); + Trace("FAIL: Pid is null.", enabled: enableLog); return false; } @@ -36,7 +36,7 @@ private static bool AttachVSToProcess(int? pid, int? vsPid, bool enableLog = fal return true; } - Trace($"Parent VS not found, finding the first VS that started.", enabled: enableLog); + Trace("Parent VS not found, finding the first VS that started.", enabled: enableLog); var firstVs = Process.GetProcesses() .Where(p => p.ProcessName == "devenv") .Select(p => @@ -98,21 +98,21 @@ private static bool AttachVs(Process vs, int pid, bool enableLog = false) Marshal.ThrowExceptionForHR(r); if (bindCtx == null) { - Trace($"BindCtx is null. Cannot attach VS.", enabled: enableLog); + Trace("BindCtx is null. Cannot attach VS.", enabled: enableLog); return false; } bindCtx.GetRunningObjectTable(out runningObjectTable); if (runningObjectTable == null) { - Trace($"RunningObjectTable is null. Cannot attach VS.", enabled: enableLog); + Trace("RunningObjectTable is null. Cannot attach VS.", enabled: enableLog); return false; } runningObjectTable.EnumRunning(out enumMoniker); if (enumMoniker == null) { - Trace($"EnumMoniker is null. Cannot attach VS.", enabled: enableLog); + Trace("EnumMoniker is null. Cannot attach VS.", enabled: enableLog); return false; } From 00996f2379fadcd1596bd2cda5e17d68cbea6871 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 10 Jan 2025 00:02:08 +1100 Subject: [PATCH 265/273] fix some nullability warnings (#4581) --- .../Utilities/AppDomainUtilities.cs | 2 +- ...ionArgsShouldBePassedInCorrectOrderFixer.cs | 4 ++-- ...PreferConstructorOverTestInitializeFixer.cs | 4 ++-- .../PreferDisposeOverTestCleanupFixer.cs | 2 +- ...PreferTestInitializeOverConstructorFixer.cs | 2 +- .../DesktopTestSourceHostTests.cs | 2 +- .../ReflectionUtilityTests.cs | 18 +++++++++--------- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs index f76a25f500..a9f194d52a 100644 --- a/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs +++ b/src/Adapter/MSTestAdapter.PlatformServices/Utilities/AppDomainUtilities.cs @@ -41,7 +41,7 @@ internal static void SetAppDomainFrameworkVersionBasedOnTestSource(AppDomainSetu { if (GetTargetFrameworkVersionFromVersionString(frameworkVersionString).CompareTo(Version45) > 0) { - PropertyInfo pInfo = typeof(AppDomainSetup).GetProperty(Constants.TargetFrameworkName); + PropertyInfo? pInfo = typeof(AppDomainSetup).GetProperty(Constants.TargetFrameworkName); pInfo?.SetValue(setup, frameworkVersionString, null); } } diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/AssertionArgsShouldBePassedInCorrectOrderFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/AssertionArgsShouldBePassedInCorrectOrderFixer.cs index 6b0ae32313..a949ea4dfd 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/AssertionArgsShouldBePassedInCorrectOrderFixer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/AssertionArgsShouldBePassedInCorrectOrderFixer.cs @@ -56,8 +56,8 @@ private static Task SwapArgumentsAsync(Document document, SyntaxNode r SeparatedSyntaxList arguments = invocationExpr.ArgumentList.Arguments; - ArgumentSyntax expectedArg = arguments.FirstOrDefault(IsExpectedArgument); - ArgumentSyntax actualArg = arguments.FirstOrDefault(IsActualArgument); + ArgumentSyntax? expectedArg = arguments.FirstOrDefault(IsExpectedArgument); + ArgumentSyntax? actualArg = arguments.FirstOrDefault(IsActualArgument); // Handle positional arguments if named arguments are not found if (expectedArg == null || actualArg == null) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferConstructorOverTestInitializeFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferConstructorOverTestInitializeFixer.cs index 7b02f31dc8..edf1f99822 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferConstructorOverTestInitializeFixer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferConstructorOverTestInitializeFixer.cs @@ -43,7 +43,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } // Find the method declaration identified by the diagnostic. - MethodDeclarationSyntax methodDeclaration = syntaxToken.Parent.AncestorsAndSelf().OfType().FirstOrDefault(); + MethodDeclarationSyntax? methodDeclaration = syntaxToken.Parent.AncestorsAndSelf().OfType().FirstOrDefault(); if (methodDeclaration == null) { return; @@ -64,7 +64,7 @@ private static async Task ReplaceTestInitializeWithConstructorAsync(Do // Find the class containing the method if (testInitializeMethod.Parent is ClassDeclarationSyntax containingClass) { - ConstructorDeclarationSyntax existingConstructor = containingClass.Members + ConstructorDeclarationSyntax? existingConstructor = containingClass.Members .OfType() .FirstOrDefault(); diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferDisposeOverTestCleanupFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferDisposeOverTestCleanupFixer.cs index 1c844f6f61..730be4dc58 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferDisposeOverTestCleanupFixer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferDisposeOverTestCleanupFixer.cs @@ -44,7 +44,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } // Find the TestCleanup method declaration identified by the diagnostic. - MethodDeclarationSyntax testCleanupMethod = syntaxToken.Parent.AncestorsAndSelf().OfType().FirstOrDefault(); + MethodDeclarationSyntax? testCleanupMethod = syntaxToken.Parent.AncestorsAndSelf().OfType().FirstOrDefault(); if (testCleanupMethod == null || !IsTestCleanupMethodValid(testCleanupMethod) || testCleanupMethod.Parent is not TypeDeclarationSyntax containingType) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferTestInitializeOverConstructorFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferTestInitializeOverConstructorFixer.cs index 6f8b9a2923..c48bdbe928 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferTestInitializeOverConstructorFixer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/PreferTestInitializeOverConstructorFixer.cs @@ -43,7 +43,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } // Find the constructor declaration identified by the diagnostic. - ConstructorDeclarationSyntax constructorDeclaration = syntaxToken.Parent.AncestorsAndSelf().OfType().FirstOrDefault(); + ConstructorDeclarationSyntax? constructorDeclaration = syntaxToken.Parent.AncestorsAndSelf().OfType().FirstOrDefault(); if (constructorDeclaration == null) { return; diff --git a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs index 6544bb12c0..51ed1bd2b4 100644 --- a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs +++ b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/DesktopTestSourceHostTests.cs @@ -79,7 +79,7 @@ public void ChildDomainResolutionPathsShouldHaveSearchDirectoriesSpecifiedInRuns // Creating instance of SampleProjectForAssemblyResolution should not throw. // It is present in specified in runsettings - AppDomainUtilities.CreateInstance(_testSourceHost.AppDomain, type, null); + AppDomainUtilities.CreateInstance(_testSourceHost.AppDomain!, type, null); } public void DisposeShouldUnloadChildAppDomain() diff --git a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs index 42fcd0507a..7fc3fc6a6b 100644 --- a/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs +++ b/test/IntegrationTests/PlatformServices.Desktop.IntegrationTests/ReflectionUtilityTests.cs @@ -38,7 +38,7 @@ public ReflectionUtilityTests() public void GetCustomAttributesShouldReturnAllAttributes() { - MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestBaseClass").GetMethod("DummyVTestMethod1"); + MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestBaseClass").GetMethod("DummyVTestMethod1")!; IReadOnlyList attributes = ReflectionUtility.GetCustomAttributes(methodInfo, false); @@ -51,7 +51,7 @@ public void GetCustomAttributesShouldReturnAllAttributes() public void GetCustomAttributesShouldReturnAllAttributesIgnoringBaseInheritance() { - MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClass").GetMethod("DummyVTestMethod1"); + MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClass").GetMethod("DummyVTestMethod1")!; IReadOnlyList attributes = ReflectionUtility.GetCustomAttributes(methodInfo, false); @@ -64,7 +64,7 @@ public void GetCustomAttributesShouldReturnAllAttributesIgnoringBaseInheritance( public void GetCustomAttributesShouldReturnAllAttributesWithBaseInheritance() { - MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClass").GetMethod("DummyVTestMethod1"); + MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClass").GetMethod("DummyVTestMethod1")!; IReadOnlyList attributes = ReflectionUtility.GetCustomAttributes(methodInfo, true); @@ -117,7 +117,7 @@ public void GetCustomAttributesOnTypeShouldReturnAllAttributesWithBaseInheritanc public void GetSpecificCustomAttributesShouldReturnAllAttributes() { - MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestBaseClass").GetMethod("DummyVTestMethod1"); + MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestBaseClass").GetMethod("DummyVTestMethod1")!; IReadOnlyList attributes = ReflectionUtility.GetCustomAttributes(methodInfo, typeof(TestCategoryAttribute), false); @@ -130,7 +130,7 @@ public void GetSpecificCustomAttributesShouldReturnAllAttributes() public void GetSpecificCustomAttributesShouldReturnAllAttributesIgnoringBaseInheritance() { - MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClass").GetMethod("DummyVTestMethod1"); + MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClass").GetMethod("DummyVTestMethod1")!; IReadOnlyList attributes = ReflectionUtility.GetCustomAttributes(methodInfo, typeof(TestCategoryAttribute), false); @@ -144,7 +144,7 @@ public void GetSpecificCustomAttributesShouldReturnAllAttributesIgnoringBaseInhe public void GetSpecificCustomAttributesShouldReturnAllAttributesWithBaseInheritance() { MethodInfo methodInfo = - _testAsset.GetType("TestProjectForDiscovery.AttributeTestClass").GetMethod("DummyVTestMethod1"); + _testAsset.GetType("TestProjectForDiscovery.AttributeTestClass").GetMethod("DummyVTestMethod1")!; IReadOnlyList attributes = ReflectionUtility.GetCustomAttributes(methodInfo, typeof(TestCategoryAttribute), true); @@ -157,7 +157,7 @@ public void GetSpecificCustomAttributesShouldReturnAllAttributesWithBaseInherita public void GetCustomAttributesShouldReturnAllAttributesIncludingUserDefinedAttributes() { - MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClassWithCustomAttributes").GetMethod("DummyVTestMethod1"); + MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClassWithCustomAttributes").GetMethod("DummyVTestMethod1")!; IReadOnlyList attributes = ReflectionUtility.GetCustomAttributes(methodInfo, null, true); @@ -170,7 +170,7 @@ public void GetCustomAttributesShouldReturnAllAttributesIncludingUserDefinedAttr public void GetSpecificCustomAttributesShouldReturnAllAttributesIncludingUserDefinedAttributes() { - MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClassWithCustomAttributes").GetMethod("DummyVTestMethod1"); + MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClassWithCustomAttributes").GetMethod("DummyVTestMethod1")!; IReadOnlyList attributes = ReflectionUtility.GetCustomAttributes(methodInfo, typeof(TestPropertyAttribute), true); @@ -183,7 +183,7 @@ public void GetSpecificCustomAttributesShouldReturnAllAttributesIncludingUserDef public void GetSpecificCustomAttributesShouldReturnArrayAttributesAsWell() { - MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClassWithCustomAttributes").GetMethod("DummyTestMethod2"); + MethodInfo methodInfo = _testAsset.GetType("TestProjectForDiscovery.AttributeTestClassWithCustomAttributes").GetMethod("DummyTestMethod2")!; IReadOnlyList attributes = ReflectionUtility.GetCustomAttributes(methodInfo, typeof(CategoryArrayAttribute), true); From 46c2a7d92d5ec8e89d7933330bb6f76e5ec14236 Mon Sep 17 00:00:00 2001 From: "dotnet-maestro[bot]" <42748379+dotnet-maestro[bot]@users.noreply.github.com> Date: Thu, 9 Jan 2025 14:28:18 +0100 Subject: [PATCH 266/273] [main] Update dependencies from dotnet/arcade (#4258) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: dotnet-maestro[bot] Co-authored-by: Amaury Levé --- Directory.Build.props | 4 +--- Directory.Build.targets | 8 +------- NuGet.config | 4 ++++ eng/Version.Details.xml | 16 ++++++++-------- eng/Versions.props | 2 +- eng/common/core-templates/steps/source-build.yml | 2 +- eng/common/cross/build-rootfs.sh | 8 ++++---- global.json | 6 +++--- ...soft.Testing.Platform.DotNetTestClient.csproj | 8 ++++---- 9 files changed, 27 insertions(+), 31 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index a6ab7b17d8..6e927fe5da 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -25,10 +25,8 @@ - net462 uap10.0.16299 net6.0-windows10.0.18362.0 - net9.0 net6.0;net7.0;net8.0;net9.0 netcoreapp3.1;net6.0;net7.0;net8.0;net9.0 @@ -83,5 +81,5 @@ - + diff --git a/Directory.Build.targets b/Directory.Build.targets index a64f4a9190..4220fbc3f6 100644 --- a/Directory.Build.targets +++ b/Directory.Build.targets @@ -10,11 +10,5 @@ 14.0.0.0 14.0.0.0 - - - - $(NetCurrent) - + diff --git a/NuGet.config b/NuGet.config index b5ce5f5511..712f79ac00 100644 --- a/NuGet.config +++ b/NuGet.config @@ -10,6 +10,7 @@ + @@ -33,5 +34,8 @@ + + + diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml index 554abc7e39..d550616ca3 100644 --- a/eng/Version.Details.xml +++ b/eng/Version.Details.xml @@ -1,17 +1,17 @@ - + https://github.com/dotnet/arcade - 45d845e04c05fbe5da9838c454bbc3af1df6be81 + 61b8f746424762d2e3173ebfaab19346224d591c - + https://github.com/dotnet/arcade - 45d845e04c05fbe5da9838c454bbc3af1df6be81 + 61b8f746424762d2e3173ebfaab19346224d591c - + https://github.com/dotnet/arcade - 45d845e04c05fbe5da9838c454bbc3af1df6be81 + 61b8f746424762d2e3173ebfaab19346224d591c https://dev.azure.com/devdiv/DevDiv/_git/vs-code-coverage @@ -40,9 +40,9 @@ - + https://github.com/dotnet/arcade - 45d845e04c05fbe5da9838c454bbc3af1df6be81 + 61b8f746424762d2e3173ebfaab19346224d591c diff --git a/eng/Versions.props b/eng/Versions.props index 94a2168dad..15569ec0e6 100644 --- a/eng/Versions.props +++ b/eng/Versions.props @@ -7,7 +7,7 @@ preview - 10.0.0-beta.24604.4 + 10.0.0-beta.24606.6 17.14.0-preview.25058.3 1.0.0-alpha.25058.1 diff --git a/eng/common/core-templates/steps/source-build.yml b/eng/common/core-templates/steps/source-build.yml index 4da05afe05..f9ba1625c2 100644 --- a/eng/common/core-templates/steps/source-build.yml +++ b/eng/common/core-templates/steps/source-build.yml @@ -78,7 +78,7 @@ steps: portableBuildArgs= if [ '${{ parameters.platform.portableBuild }}' != '' ]; then - portableBuildArgs='/p:PortabelBuild=${{ parameters.platform.portableBuild }}' + portableBuildArgs='/p:PortableBuild=${{ parameters.platform.portableBuild }}' fi ${{ coalesce(parameters.platform.buildScript, './build.sh') }} --ci \ diff --git a/eng/common/cross/build-rootfs.sh b/eng/common/cross/build-rootfs.sh index 20ae8c2868..096bfe51f1 100644 --- a/eng/common/cross/build-rootfs.sh +++ b/eng/common/cross/build-rootfs.sh @@ -73,8 +73,8 @@ __AlpinePackages+=" krb5-dev" __AlpinePackages+=" openssl-dev" __AlpinePackages+=" zlib-dev" -__FreeBSDBase="13.3-RELEASE" -__FreeBSDPkg="1.17.0" +__FreeBSDBase="13.4-RELEASE" +__FreeBSDPkg="1.21.3" __FreeBSDABI="13" __FreeBSDPackages="libunwind" __FreeBSDPackages+=" icu" @@ -371,7 +371,7 @@ while :; do ;; freebsd14) __CodeName=freebsd - __FreeBSDBase="14.0-RELEASE" + __FreeBSDBase="14.2-RELEASE" __FreeBSDABI="14" __SkipUnmount=1 ;; @@ -574,7 +574,7 @@ elif [[ "$__CodeName" == "freebsd" ]]; then curl -SL "https://download.freebsd.org/ftp/releases/${__FreeBSDArch}/${__FreeBSDMachineArch}/${__FreeBSDBase}/base.txz" | tar -C "$__RootfsDir" -Jxf - ./lib ./usr/lib ./usr/libdata ./usr/include ./usr/share/keys ./etc ./bin/freebsd-version fi echo "ABI = \"FreeBSD:${__FreeBSDABI}:${__FreeBSDMachineArch}\"; FINGERPRINTS = \"${__RootfsDir}/usr/share/keys\"; REPOS_DIR = [\"${__RootfsDir}/etc/pkg\"]; REPO_AUTOUPDATE = NO; RUN_SCRIPTS = NO;" > "${__RootfsDir}"/usr/local/etc/pkg.conf - echo "FreeBSD: { url: \"pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", signature_type: \"fingerprints\", fingerprints: \"${__RootfsDir}/usr/share/keys/pkg\", enabled: yes }" > "${__RootfsDir}"/etc/pkg/FreeBSD.conf + echo "FreeBSD: { url: \"pkg+http://pkg.FreeBSD.org/\${ABI}/quarterly\", mirror_type: \"srv\", signature_type: \"fingerprints\", fingerprints: \"/usr/share/keys/pkg\", enabled: yes }" > "${__RootfsDir}"/etc/pkg/FreeBSD.conf mkdir -p "$__RootfsDir"/tmp # get and build package manager if [[ "$__hasWget" == 1 ]]; then diff --git a/global.json b/global.json index d853cca63e..6534c78b79 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "tools": { - "dotnet": "9.0.100", + "dotnet": "10.0.100-alpha.1.24573.1", "runtimes": { "dotnet": [ "3.1.32", @@ -21,12 +21,12 @@ } }, "sdk": { - "version": "9.0.100", + "version": "10.0.100-alpha.1.24573.1", "allowPrerelease": true, "rollForward": "latestFeature" }, "msbuild-sdks": { - "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.24604.4", + "Microsoft.DotNet.Arcade.Sdk": "10.0.0-beta.24606.6", "MSBuild.Sdk.Extras": "3.0.44" } } diff --git a/src/Package/Microsoft.Testing.Platform.DotNetTestClient/Microsoft.Testing.Platform.DotNetTestClient.csproj b/src/Package/Microsoft.Testing.Platform.DotNetTestClient/Microsoft.Testing.Platform.DotNetTestClient.csproj index 2e52abf512..f5524c8883 100644 --- a/src/Package/Microsoft.Testing.Platform.DotNetTestClient/Microsoft.Testing.Platform.DotNetTestClient.csproj +++ b/src/Package/Microsoft.Testing.Platform.DotNetTestClient/Microsoft.Testing.Platform.DotNetTestClient.csproj @@ -1,7 +1,7 @@ - net9.0 + $(NetCurrent) $(TestingPlatformVersionPrefix) @@ -37,13 +37,13 @@ - + - + @@ -51,4 +51,4 @@ - \ No newline at end of file + From e4877befa10ab8a61b441e56743f8e0d133744db Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 9 Jan 2025 14:28:56 +0100 Subject: [PATCH 267/273] Update CODEOWNERS (#4579) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 341dcc1fb6..804b456c01 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,4 @@ # https://docs.github.com/en/github/creating-cloning-and-archiving-repositories/creating-a-repository-on-github/about-code-owners -src/Package/MSTest.Sdk @MarcoRossignoli +src/Package/MSTest.Sdk @MarcoRossignoli @Evangelink src/Platform @MarcoRossignoli @Youssef1313 @Evangelink From 887175d1e2504f7bffae21b56e213bed3dd98284 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 9 Jan 2025 14:31:52 +0100 Subject: [PATCH 268/273] Implement codefix for 'Are[Not]Same' usage with value types (#4584) --- .../AvoidAssertAreSameWithValueTypesFixer.cs | 72 +++++++++++++++ .../CodeFixResources.Designer.cs | 9 ++ .../CodeFixResources.resx | 5 +- .../xlf/CodeFixResources.cs.xlf | 5 ++ .../xlf/CodeFixResources.de.xlf | 5 ++ .../xlf/CodeFixResources.es.xlf | 5 ++ .../xlf/CodeFixResources.fr.xlf | 5 ++ .../xlf/CodeFixResources.it.xlf | 5 ++ .../xlf/CodeFixResources.ja.xlf | 5 ++ .../xlf/CodeFixResources.ko.xlf | 5 ++ .../xlf/CodeFixResources.pl.xlf | 5 ++ .../xlf/CodeFixResources.pt-BR.xlf | 5 ++ .../xlf/CodeFixResources.ru.xlf | 5 ++ .../xlf/CodeFixResources.tr.xlf | 5 ++ .../xlf/CodeFixResources.zh-Hans.xlf | 5 ++ .../xlf/CodeFixResources.zh-Hant.xlf | 5 ++ ...voidAssertAreSameWithValueTypesAnalyzer.cs | 13 ++- ...ssertAreSameWithValueTypesAnalyzerTests.cs | 90 ++++++++++++++++++- 18 files changed, 247 insertions(+), 7 deletions(-) create mode 100644 src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidAssertAreSameWithValueTypesFixer.cs diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidAssertAreSameWithValueTypesFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidAssertAreSameWithValueTypesFixer.cs new file mode 100644 index 0000000000..81f5f78d5c --- /dev/null +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/AvoidAssertAreSameWithValueTypesFixer.cs @@ -0,0 +1,72 @@ +// 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 System.Composition; + +using Analyzer.Utilities; + +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Editing; + +using MSTest.Analyzers.Helpers; + +namespace MSTest.Analyzers; + +[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(AvoidAssertAreSameWithValueTypesFixer))] +[Shared] +public sealed class AvoidAssertAreSameWithValueTypesFixer : CodeFixProvider +{ + public sealed override ImmutableArray FixableDiagnosticIds { get; } + = ImmutableArray.Create(DiagnosticIds.AvoidAssertAreSameWithValueTypesRuleId); + + public override FixAllProvider GetFixAllProvider() + // See https://github.com/dotnet/roslyn/blob/main/docs/analyzers/FixAllProvider.md for more information on Fix All Providers + => WellKnownFixAllProviders.BatchFixer; + + public override async Task RegisterCodeFixesAsync(CodeFixContext context) + { + SyntaxNode root = await context.Document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + Diagnostic diagnostic = context.Diagnostics[0]; + + string? replacement = diagnostic.Properties[AvoidAssertAreSameWithValueTypesAnalyzer.ReplacemenyKey] + ?? throw ApplicationStateGuard.Unreachable(); + + SyntaxNode diagnosticNode = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); + if (diagnosticNode is not InvocationExpressionSyntax invocation) + { + Debug.Fail($"Is this an interesting scenario where IInvocationOperation for Assert call isn't associated with InvocationExpressionSyntax? SyntaxNode type: '{diagnosticNode.GetType()}', Text: '{diagnosticNode.GetText()}'"); + return; + } + + SyntaxNode methodNameIdentifier = invocation.Expression; + if (methodNameIdentifier is MemberAccessExpressionSyntax memberAccess) + { + methodNameIdentifier = memberAccess.Name; + } + + if (methodNameIdentifier is not SimpleNameSyntax simpleNameSyntax) + { + Debug.Fail($"Is this an interesting scenario where we are unable to retrieve SimpleNameSyntax corresponding to the assert method? SyntaxNode type: '{methodNameIdentifier}', Text: '{methodNameIdentifier.GetText()}'."); + return; + } + + context.RegisterCodeFix( + CodeAction.Create( + title: string.Format(CultureInfo.InvariantCulture, CodeFixResources.AvoidAssertAreSameWithValueTypesFix, replacement), + ct => FixMethodNameAsync(context.Document, simpleNameSyntax, replacement, ct), + equivalenceKey: nameof(AvoidAssertAreSameWithValueTypesFixer)), + diagnostic); + } + + private static async Task FixMethodNameAsync(Document document, SimpleNameSyntax simpleNameSyntax, string properAssertMethodName, CancellationToken cancellationToken) + { + DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false); + editor.ReplaceNode(simpleNameSyntax, simpleNameSyntax.WithIdentifier(SyntaxFactory.Identifier(properAssertMethodName))); + return editor.GetChangedDocument(); + } +} diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs index 8eb5b990f5..a32c10e0bf 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.Designer.cs @@ -87,6 +87,15 @@ internal static string AssertionArgsShouldAvoidConditionalAccessFix { } } + /// + /// Looks up a localized string similar to Use '{0}'. + /// + internal static string AvoidAssertAreSameWithValueTypesFix { + get { + return ResourceManager.GetString("AvoidAssertAreSameWithValueTypesFix", resourceCulture); + } + } + /// /// Looks up a localized string similar to Change method accessibility to 'private'. /// diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx index a72a7039ef..50c67bba6c 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx @@ -174,4 +174,7 @@ Move conditional access in assertion to separate 'Assert.IsNotNull' check - + + Use '{0}' + + \ No newline at end of file diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf index 92113c5428..e756f5cdc7 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf @@ -12,6 +12,11 @@ Přesunout podmíněný přístup v kontrolním výrazu, aby se oddělila kontrola Assert.IsNotNull + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' Změnit přístupnost metody na private diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf index da9c7cb051..255d46d530 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf @@ -12,6 +12,11 @@ Bedingten Zugriff in Assertion auf separate "Assert.IsNotNull"-Überprüfung verschieben + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' Methodenzugriff auf „privat“ ändern diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf index 402bf5caa5..c3b124a711 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf @@ -12,6 +12,11 @@ Mover el acceso condicional en la aserción para separar la comprobación 'Assert.IsNotNull' + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' Cambiar la accesibilidad del método a "private" diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf index c7558f7d6c..a7d4398834 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf @@ -12,6 +12,11 @@ Déplacer l’accès conditionnel dans l’assertion pour séparer les case activée 'Assert.IsNotNull' + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' Remplacer l’accessibilité de la méthode par « privé » diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf index 7c641b301b..80c5591b67 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf @@ -12,6 +12,11 @@ Sposta l'accesso condizionale nell'asserzione per separare il controllo 'Assert.IsNotNull' + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' Modifica l'accessibilità del metodo in 'privato' diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf index 11f9b0e16e..25ffc7b11d 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf @@ -12,6 +12,11 @@ アサーション内の条件付きアクセスを個別の 'Assert.IsNotNull' チェックに移動します + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' メソッドのアクセシビリティを 'private' に変更する diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf index de99bc90b7..e61c0984c3 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf @@ -12,6 +12,11 @@ 어설션의 조건부 액세스를 'Assert.IsNotNull' 검사 구분하도록 이동합니다. + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' 메서드 접근성 '비공개'로 변경하기 diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf index ac3bcd5f03..74fe8fa536 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf @@ -12,6 +12,11 @@ Przenieś dostęp warunkowy w asercji do oddzielnego sprawdzenia "Assert.IsNotNull" + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' Zmień dostępność metody na „private” (prywatna) diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf index 27d3ad00ea..36baaed6b6 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf @@ -12,6 +12,11 @@ Mover o acesso condicional na asserção para separar o 'Assert.IsNotNull' marcar + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' Alterar a acessibilidade do método para 'privado' diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf index 70a1cb09f2..39003005ba 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf @@ -12,6 +12,11 @@ Переместить условный доступ в утверждении, чтобы разделить "Assert.IsNotNull" проверка + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' Изменить доступность метода на "private" diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf index dd75c3d40a..755034dcf3 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf @@ -12,6 +12,11 @@ Onaylamadaki koşullu erişimi 'Assert.IsNotNull' denetimine ayırmaya taşı + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' Yöntem erişilebilirliğini ‘özel’ olarak değiştir diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf index 62c59a4813..1a99753471 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf @@ -12,6 +12,11 @@ 将断言中的条件访问移动到分隔 “Assert.IsNotNull” 检查 + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' 将方法可访问性更改为“private” diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf index e449ea07e8..1cba0d3629 100644 --- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf +++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf @@ -12,6 +12,11 @@ 將判斷提示中的條件式存取移動到個別的 『Assert.IsNotNull』 檢查 + + Use '{0}' + Use '{0}' + + Change method accessibility to 'private' 將方法協助工具變更為 'private' diff --git a/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs index 4da001105c..afa199bd7a 100644 --- a/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs +++ b/src/Analyzers/MSTest.Analyzers/AvoidAssertAreSameWithValueTypesAnalyzer.cs @@ -24,6 +24,8 @@ public sealed class AvoidAssertAreSameWithValueTypesAnalyzer : DiagnosticAnalyze private static readonly LocalizableResourceString MessageFormat = new(nameof(Resources.AvoidAssertAreSameWithValueTypesMessageFormat), Resources.ResourceManager, typeof(Resources)); private static readonly LocalizableResourceString Description = new(nameof(Resources.AvoidAssertAreSameWithValueTypesDescription), Resources.ResourceManager, typeof(Resources)); + internal const string ReplacemenyKey = nameof(ReplacemenyKey); + internal static readonly DiagnosticDescriptor Rule = DiagnosticDescriptorHelper.Create( DiagnosticIds.AvoidAssertAreSameWithValueTypesRuleId, Title, @@ -69,11 +71,16 @@ private static void AnalyzeOperation(OperationAnalysisContext context, INamedTyp return; } - if (argExpected.Value.WalkDownConversion().Type?.IsValueType == true || - argActual.Value.WalkDownConversion().Type?.IsValueType == true) + ITypeSymbol? expectedType = argExpected.Value.WalkDownConversion().Type; + ITypeSymbol? actualType = argActual.Value.WalkDownConversion().Type; + + if (expectedType?.IsValueType == true || + actualType?.IsValueType == true) { string suggestedReplacement = targetMethod.Name == "AreSame" ? "AreEqual" : "AreNotEqual"; - context.ReportDiagnostic(operation.CreateDiagnostic(Rule, targetMethod.Name, suggestedReplacement)); + ImmutableDictionary properties = ImmutableDictionary.Empty + .Add(ReplacemenyKey, suggestedReplacement); + context.ReportDiagnostic(operation.CreateDiagnostic(Rule, properties, targetMethod.Name, suggestedReplacement)); } } } diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs index 11f7b53938..c5910bc905 100644 --- a/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs +++ b/test/UnitTests/MSTest.Analyzers.UnitTests/AvoidAssertAreSameWithValueTypesAnalyzerTests.cs @@ -3,7 +3,7 @@ using VerifyCS = MSTest.Analyzers.Test.CSharpCodeFixVerifier< MSTest.Analyzers.AvoidAssertAreSameWithValueTypesAnalyzer, - Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + MSTest.Analyzers.AvoidAssertAreSameWithValueTypesFixer>; namespace MSTest.Analyzers.UnitTests; @@ -55,7 +55,49 @@ public void TestMethod() } """; - await VerifyCS.VerifyCodeFixAsync(code, code); + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void TestMethod() + { + // Both are value types + Assert.AreEqual(0, 0); + Assert.AreEqual(0, 0, "Message"); + Assert.AreEqual(0, 0, "Message {0}", "Arg"); + Assert.AreEqual(message: "Message", expected: 0, actual: 0); + + Assert.AreEqual(0, 0); + Assert.AreEqual(0, 0, "Message"); + Assert.AreEqual(0, 0, "Message {0}", "Arg"); + Assert.AreEqual(message: "Message", expected: 0, actual: 0); + + // Expected is value type. This is always-failing assert. + Assert.AreEqual("0", 0); + Assert.AreEqual("0", 0, "Message"); + Assert.AreEqual("0", 0, "Message {0}", "Arg"); + Assert.AreEqual(message: "Message", expected: "0", actual: 0); + + // Actual is value type. This is always-failing assert. + Assert.AreEqual(0, "0"); + Assert.AreEqual(0, "0", "Message"); + Assert.AreEqual(0, "0", "Message {0}", "Arg"); + Assert.AreEqual(message: "Message", expected: 0, actual: "0"); + + // Both are reference types. No diagnostic. + Assert.AreSame("0", "0"); + Assert.AreSame("0", "0", "Message"); + Assert.AreSame("0", "0", "Message {0}", "Arg"); + Assert.AreSame(message: "Message", expected: "0", actual: "0"); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } [TestMethod] @@ -103,6 +145,48 @@ public void TestMethod() } """; - await VerifyCS.VerifyCodeFixAsync(code, code); + string fixedCode = """ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using System.Collections.Generic; + + [TestClass] + public class MyTestClass + { + [TestMethod] + public void TestMethod() + { + // Both are value types + Assert.AreNotEqual(0, 1); + Assert.AreNotEqual(0, 1, "Message"); + Assert.AreNotEqual(0, 1, "Message {0}", "Arg"); + Assert.AreNotEqual(message: "Message", notExpected: 0, actual: 1); + + Assert.AreNotEqual(0, 1); + Assert.AreNotEqual(0, 1, "Message"); + Assert.AreNotEqual(0, 1, "Message {0}", "Arg"); + Assert.AreNotEqual(message: "Message", notExpected: 0, actual: 1); + + // Expected is value type. This is always-failing assert. + Assert.AreNotEqual("0", 1); + Assert.AreNotEqual("0", 1, "Message"); + Assert.AreNotEqual("0", 1, "Message {0}", "Arg"); + Assert.AreNotEqual(message: "Message", notExpected: "0", actual: 1); + + // Actual is value type. This is always-failing assert. + Assert.AreNotEqual(0, "1"); + Assert.AreNotEqual(0, "1", "Message"); + Assert.AreNotEqual(0, "1", "Message {0}", "Arg"); + Assert.AreNotEqual(message: "Message", notExpected: 0, actual: "1"); + + // Both are reference types. No diagnostic. + Assert.AreNotSame("0", "1"); + Assert.AreNotSame("0", "1", "Message"); + Assert.AreNotSame("0", "1", "Message {0}", "Arg"); + Assert.AreNotSame(message: "Message", notExpected: "0", actual: "1"); + } + } + """; + + await VerifyCS.VerifyCodeFixAsync(code, fixedCode); } } From 53488cf463d33882113ca7a6fbbb6f93e06251df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Thu, 9 Jan 2025 16:34:27 +0100 Subject: [PATCH 269/273] =?UTF-8?q?[port]=20Fix=20"Found=20multiple=20prop?= =?UTF-8?q?erties=20of=20type=20'Microsoft.Testing.Plat=E2=80=A6=20(#4589)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ObjectModel/ObjectModelConverters.cs | 22 ++++- .../OutputTests.cs | 83 +++++++++++++++++++ .../ObjectModel/ObjectModelConvertersTests.cs | 40 +++++++++ 3 files changed, 141 insertions(+), 4 deletions(-) create mode 100644 test/IntegrationTests/MSTest.Acceptance.IntegrationTests/OutputTests.cs diff --git a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.cs b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.cs index 76bc0af8cb..60377070c1 100644 --- a/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.cs +++ b/src/Platform/Microsoft.Testing.Extensions.VSTestBridge/ObjectModel/ObjectModelConverters.cs @@ -160,21 +160,35 @@ public static TestNode ToTestNode(this TestResult testResult, bool isTrxEnabled, testNode.Properties.Add(new TimingProperty(new(testResult.StartTime, testResult.EndTime, testResult.Duration), [])); + var standardErrorMessages = new List(); + var standardOutputMessages = new List(); foreach (TestResultMessage testResultMessage in testResult.Messages) { if (testResultMessage.Category == TestResultMessage.StandardErrorCategory) { - testNode.Properties.Add(new SerializableKeyValuePairStringProperty("vstest.TestCase.StandardError", testResultMessage.Text ?? string.Empty)); - testNode.Properties.Add(new StandardErrorProperty(testResultMessage.Text ?? string.Empty)); + string message = testResultMessage.Text ?? string.Empty; + testNode.Properties.Add(new SerializableKeyValuePairStringProperty("vstest.TestCase.StandardError", message)); + standardErrorMessages.Add(message); } if (testResultMessage.Category == TestResultMessage.StandardOutCategory) { - testNode.Properties.Add(new SerializableKeyValuePairStringProperty("vstest.TestCase.StandardOutput", testResultMessage.Text ?? string.Empty)); - testNode.Properties.Add(new StandardOutputProperty(testResultMessage.Text ?? string.Empty)); + string message = testResultMessage.Text ?? string.Empty; + testNode.Properties.Add(new SerializableKeyValuePairStringProperty("vstest.TestCase.StandardOutput", message)); + standardOutputMessages.Add(message); } } + if (standardErrorMessages.Count > 0) + { + testNode.Properties.Add(new StandardErrorProperty(string.Join(Environment.NewLine, standardErrorMessages))); + } + + if (standardOutputMessages.Count > 0) + { + testNode.Properties.Add(new StandardOutputProperty(string.Join(Environment.NewLine, standardOutputMessages))); + } + return testNode; } diff --git a/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/OutputTests.cs b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/OutputTests.cs new file mode 100644 index 0000000000..a52aaf0899 --- /dev/null +++ b/test/IntegrationTests/MSTest.Acceptance.IntegrationTests/OutputTests.cs @@ -0,0 +1,83 @@ +// 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.Testing.Platform.Acceptance.IntegrationTests; +using Microsoft.Testing.Platform.Acceptance.IntegrationTests.Helpers; + +namespace MSTest.Acceptance.IntegrationTests; + +[TestClass] +public sealed class OutputTests : AcceptanceTestBase +{ + [TestMethod] + [DynamicData(nameof(TargetFrameworks.AllForDynamicData), typeof(TargetFrameworks))] + public async Task DetailedOutputIsAsExpected(string tfm) + { + var testHost = TestHost.LocateFrom(AssetFixture.ProjectPath, TestAssetFixture.ProjectName, tfm); + TestHostResult testHostResult = await testHost.ExecuteAsync("--output detailed"); + + // Assert + testHostResult.AssertOutputContains("Assert.AreEqual failed. Expected:<1>. Actual:<2>."); + testHostResult.AssertOutputContains(""" + Standard output + Console message + TestContext Messages: + TestContext message + Error output + """); + } + + public sealed class TestAssetFixture() : TestAssetFixtureBase(AcceptanceFixture.NuGetGlobalPackagesFolder) + { + public const string ProjectName = "TestOutput"; + + public string ProjectPath => GetAssetPath(ProjectName); + + public override IEnumerable<(string ID, string Name, string Code)> GetAssetsToGenerate() + { + yield return (ProjectName, ProjectName, + SourceCode + .PatchTargetFrameworks(TargetFrameworks.All) + .PatchCodeWithReplace("$MSTestVersion$", MSTestVersion)); + } + + private const string SourceCode = """ +#file TestOutput.csproj + + + + Exe + true + $TargetFrameworks$ + + + + + + + + + +#file UnitTest1.cs +using System; +using System.Diagnostics; +using Microsoft.VisualStudio.TestTools.UnitTesting; + +[TestClass] +public class UnitTest1 +{ + public TestContext TestContext { get; set; } + + [TestMethod] + public void TestMethod() + { + Debug.WriteLine("Debug message"); + Console.WriteLine("Console message"); + TestContext.WriteLine("TestContext message"); + + Assert.AreEqual(1, 2); + } +} +"""; + } +} diff --git a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.cs b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.cs index c546179a91..9e0d20d5d9 100644 --- a/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.cs +++ b/test/UnitTests/Microsoft.Testing.Extensions.VSTestBridge.UnitTests/ObjectModel/ObjectModelConvertersTests.cs @@ -266,4 +266,44 @@ public void ToTestNode_WhenTestResultHasTraits_TestNodePropertiesContainIt() Assert.AreEqual("key", errorTestNodeStateProperties[0].Pairs[0].Key); Assert.AreEqual("value", errorTestNodeStateProperties[0].Pairs[0].Value); } + + [TestMethod] + public void ToTestNode_WhenTestResultHasMultipleStandardOutputMessages_TestNodePropertiesHasASingleOne() + { + TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")) + { + DisplayName = "TestName", + Messages = + { + new TestResultMessage(TestResultMessage.StandardOutCategory, "message1"), + new TestResultMessage(TestResultMessage.StandardOutCategory, "message2"), + }, + }; + + var testNode = testResult.ToTestNode(false, VSTestClient); + + StandardOutputProperty[] standardOutputProperties = testNode.Properties.OfType().ToArray(); + Assert.IsTrue(standardOutputProperties.Length == 1); + Assert.AreEqual($"message1{Environment.NewLine}message2", standardOutputProperties[0].StandardOutput); + } + + [TestMethod] + public void ToTestNode_WhenTestResultHasMultipleStandardErrorMessages_TestNodePropertiesHasASingleOne() + { + TestResult testResult = new(new TestCase("SomeFqn", new("executor://uri", UriKind.Absolute), "source.cs")) + { + DisplayName = "TestName", + Messages = + { + new TestResultMessage(TestResultMessage.StandardErrorCategory, "message1"), + new TestResultMessage(TestResultMessage.StandardErrorCategory, "message2"), + }, + }; + + var testNode = testResult.ToTestNode(false, VSTestClient); + + StandardErrorProperty[] standardErrorProperties = testNode.Properties.OfType().ToArray(); + Assert.IsTrue(standardErrorProperties.Length == 1); + Assert.AreEqual($"message1{Environment.NewLine}message2", standardErrorProperties[0].StandardError); + } } From 1251143c7b3fcf495b1cd9c1cbd75ec408240590 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 10 Jan 2025 02:36:42 +1100 Subject: [PATCH 270/273] better use of IsInstanceOfType (#4583) --- .../Services/ServiceProvider.cs | 13 +------------ .../Assertions/Assert.IsInstanceOfType.cs | 4 ++-- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/Platform/Microsoft.Testing.Platform/Services/ServiceProvider.cs b/src/Platform/Microsoft.Testing.Platform/Services/ServiceProvider.cs index 22baff7e4e..556e89cc09 100644 --- a/src/Platform/Microsoft.Testing.Platform/Services/ServiceProvider.cs +++ b/src/Platform/Microsoft.Testing.Platform/Services/ServiceProvider.cs @@ -81,8 +81,7 @@ public IEnumerable GetServicesInternal( foreach (object serviceInstance in _services) { -#if !NETCOREAPP - if (serviceType.IsAssignableFrom(serviceInstance.GetType())) + if (serviceType.IsInstanceOfType(serviceInstance)) { yield return serviceInstance; if (stopAtFirst) @@ -90,16 +89,6 @@ public IEnumerable GetServicesInternal( yield break; } } -#else - if (serviceInstance.GetType().IsAssignableTo(serviceType)) - { - yield return serviceInstance; - if (stopAtFirst) - { - yield break; - } - } -#endif } } diff --git a/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs b/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs index 63f62e38ba..d758d4a961 100644 --- a/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs +++ b/src/TestFramework/TestFramework/Assertions/Assert.IsInstanceOfType.cs @@ -390,7 +390,7 @@ public static void IsInstanceOfType([NotNull] object? value, [NotNull] Type? exp } private static bool IsInstanceOfTypeFailing([NotNullWhen(false)] object? value, [NotNullWhen(false)] Type? expectedType) - => expectedType == null || value == null || !expectedType.IsAssignableFrom(value.GetType()); + => expectedType == null || value == null || !expectedType.IsInstanceOfType(value); [DoesNotReturn] private static void ThrowAssertIsInstanceOfTypeFailed(object? value, Type? expectedType, string userMessage) @@ -543,7 +543,7 @@ public static void IsNotInstanceOfType(object? value, [NotNull] Type? wrongType, private static bool IsNotInstanceOfTypeFailing(object? value, [NotNullWhen(false)] Type? wrongType) => wrongType is null || // Null is not an instance of any type. - (value is not null && wrongType.IsAssignableFrom(value.GetType())); + (value is not null && wrongType.IsInstanceOfType(value)); [DoesNotReturn] private static void ThrowAssertIsNotInstanceOfTypeFailed(object? value, Type? wrongType, string userMessage) From 79c2c296d855813dbf8355559dd9403da0282f28 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Fri, 10 Jan 2025 02:38:36 +1100 Subject: [PATCH 271/273] remove redundant StringBuilder in TestHostResult (#4572) --- .../TestHostResult.cs | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHostResult.cs b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHostResult.cs index 6cdb8a76da..8b8647cc85 100644 --- a/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHostResult.cs +++ b/test/Utilities/Microsoft.Testing.TestInfrastructure/TestHostResult.cs @@ -19,17 +19,16 @@ public sealed class TestHostResult(string command, int exitCode, string standard public ReadOnlyCollection StandardErrorLines { get; } = standardErrorLines; - public override string ToString() - { - StringBuilder stringBuilder = new(); - stringBuilder.AppendLine(CultureInfo.InvariantCulture, $"Command: {Command}"); - stringBuilder.AppendLine(CultureInfo.InvariantCulture, $"===================="); - stringBuilder.AppendLine(CultureInfo.InvariantCulture, $"ExitCode: {ExitCode}"); - stringBuilder.AppendLine(CultureInfo.InvariantCulture, $"===================="); - stringBuilder.AppendLine(CultureInfo.InvariantCulture, $"StandardOutput:\n{StandardOutput}"); - stringBuilder.AppendLine(CultureInfo.InvariantCulture, $"===================="); - stringBuilder.AppendLine(CultureInfo.InvariantCulture, $"StandardError:\n{StandardError}"); - - return stringBuilder.ToString(); - } + public override string ToString() => + $""" + Command: {Command} + ==================== + ExitCode: {ExitCode} + ==================== + StandardOutput: + {StandardOutput} + ==================== + StandardError: + {StandardError} + """; } From 2cf523ddf6280c13ffc9d0c50dade57b1a9d4801 Mon Sep 17 00:00:00 2001 From: Youssef Victor Date: Thu, 9 Jan 2025 21:37:41 +0100 Subject: [PATCH 272/273] Add backport GH Actions (#4592) --- .github/workflows/backport-base.yml | 260 ++++++++++++++++++++++++++++ .github/workflows/backport.yml | 23 +++ 2 files changed, 283 insertions(+) create mode 100644 .github/workflows/backport-base.yml create mode 100644 .github/workflows/backport.yml diff --git a/.github/workflows/backport-base.yml b/.github/workflows/backport-base.yml new file mode 100644 index 0000000000..13178ce38b --- /dev/null +++ b/.github/workflows/backport-base.yml @@ -0,0 +1,260 @@ +on: + workflow_call: + inputs: + pr_title_template: + description: 'The template used for the PR title. Special placeholder tokens that will be replaced with a value: %target_branch%, %source_pr_title%, %source_pr_number%, %cc_users%.' + required: false + type: string + default: '[%target_branch%] %source_pr_title%' + pr_description_template: + description: 'The template used for the PR description. Special placeholder tokens that will be replaced with a value: %target_branch%, %source_pr_title%, %source_pr_number%, %cc_users%.' + required: false + type: string + default: | + Backport of #%source_pr_number% to %target_branch% + + /cc %cc_users% + repository_owners: + description: 'A comma-separated list of repository owners where the workflow will run. Defaults to "dotnet,microsoft".' + required: false + type: string + default: 'dotnet,microsoft' + +jobs: + cleanup: + if: ${{ contains(format('{0},', inputs.repository_owners), format('{0},', github.repository_owner)) && github.event_name == 'schedule' }} + runs-on: ubuntu-latest + permissions: + actions: write + steps: + - name: Cleanup workflow runs + uses: actions/github-script@v7 + with: + script: | + const repo_owner = context.payload.repository.owner.login; + const repo_name = context.payload.repository.name; + + // look up workflow from current run + const currentWorkflowRun = await github.rest.actions.getWorkflowRun({ + owner: repo_owner, + repo: repo_name, + run_id: context.runId + }); + + // get runs which are 'completed' (other candidate values of status field are e.g. 'queued' and 'in_progress') + for await (const response of github.paginate.iterator( + github.rest.actions.listWorkflowRuns, { + owner: repo_owner, + repo: repo_name, + workflow_id: currentWorkflowRun.data.workflow_id, + status: 'completed' + } + )) { + // delete each run + for (const run of response.data) { + console.log(`Deleting workflow run ${run.id}`); + await github.rest.actions.deleteWorkflowRun({ + owner: repo_owner, + repo: repo_name, + run_id: run.id + }); + } + } + + run_backport: + if: ${{ contains(format('{0},', inputs.repository_owners), format('{0},', github.repository_owner)) && github.event.issue.pull_request != '' && contains(github.event.comment.body, '/backport to') }} + runs-on: ubuntu-latest + permissions: + contents: write + issues: write + pull-requests: write + steps: + - name: Extract backport target branch + uses: actions/github-script@v7 + id: target-branch-extractor + with: + result-encoding: string + script: | + if (context.eventName !== "issue_comment") throw "Error: This action only works on issue_comment events."; + + // extract the target branch name from the trigger phrase containing these characters: a-z, A-Z, digits, forward slash, dot, hyphen, underscore + const regex = /^\/backport to ([a-zA-Z\d\/\.\-\_]+)/; + target_branch = regex.exec(context.payload.comment.body); + if (target_branch == null) throw "Error: No backport branch found in the trigger phrase."; + + return target_branch[1]; + - name: Unlock comments if PR is locked + uses: actions/github-script@v7 + if: ${{ github.event.issue.locked == true }} + with: + script: | + console.log(`Unlocking locked PR #${context.issue.number}.`); + await github.rest.issues.unlock({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + }); + - name: Post backport started comment to pull request + uses: actions/github-script@v7 + with: + script: | + const target_branch = '${{ steps.target-branch-extractor.outputs.result }}'; + const backport_start_body = `Started backporting to ${target_branch}: https://github.com/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`; + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: backport_start_body + }); + - name: Checkout repo + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Run backport + uses: actions/github-script@v7 + env: + BACKPORT_PR_TITLE_TEMPLATE: ${{ inputs.pr_title_template }} + BACKPORT_PR_DESCRIPTION_TEMPLATE: ${{ inputs.pr_description_template }} + with: + script: | + const target_branch = '${{ steps.target-branch-extractor.outputs.result }}'; + const repo_owner = context.payload.repository.owner.login; + const repo_name = context.payload.repository.name; + const pr_number = context.payload.issue.number; + const comment_user = context.payload.comment.user.login; + + try { + // verify the comment user is a repo collaborator + try { + await github.rest.repos.checkCollaborator({ + owner: repo_owner, + repo: repo_name, + username: comment_user + }); + console.log(`Verified ${comment_user} is a repo collaborator.`); + } catch (error) { + console.log(error); + throw new Error(`Error: @${comment_user} is not a repo collaborator, backporting is not allowed. If you're a collaborator please make sure your ${repo_owner} team membership visibility is set to Public on https://github.com/orgs/${repo_owner}/people?query=${comment_user}`); + } + + try { await exec.exec(`git ls-remote --exit-code --heads origin ${target_branch}`) } catch { throw new Error(`Error: The specified backport target branch ${target_branch} wasn't found in the repo.`); } + console.log(`Backport target branch: ${target_branch}`); + + console.log("Applying backport patch"); + + await exec.exec(`git checkout ${target_branch}`); + await exec.exec(`git clean -xdff`); + + // configure git + await exec.exec(`git config user.name "github-actions"`); + await exec.exec(`git config user.email "github-actions@github.com"`); + + // create temporary backport branch + const temp_branch = `backport/pr-${pr_number}-to-${target_branch}`; + await exec.exec(`git checkout -b ${temp_branch}`); + + // skip opening PR if the branch already exists on the origin remote since that means it was opened + // by an earlier backport and force pushing to the branch updates the existing PR + let should_open_pull_request = true; + try { + await exec.exec(`git ls-remote --exit-code --heads origin ${temp_branch}`); + should_open_pull_request = false; + } catch { } + + // download and apply patch + await exec.exec(`curl -sSL "${context.payload.issue.pull_request.patch_url}" --output changes.patch`); + + const git_am_command = "git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch"; + let git_am_output = `$ ${git_am_command}\n\n`; + let git_am_failed = false; + try { + await exec.exec(git_am_command, [], { + listeners: { + stdout: function stdout(data) { git_am_output += data; }, + stderr: function stderr(data) { git_am_output += data; } + } + }); + } catch (error) { + git_am_output += error; + git_am_failed = true; + } + + if (git_am_failed) { + const git_am_failed_body = `@${context.payload.comment.user.login} backporting to ${target_branch} failed, the patch most likely resulted in conflicts:\n\n\`\`\`shell\n${git_am_output}\n\`\`\`\n\nPlease backport manually!`; + await github.rest.issues.createComment({ + owner: repo_owner, + repo: repo_name, + issue_number: pr_number, + body: git_am_failed_body + }); + core.setFailed("Error: git am failed, most likely due to a merge conflict."); + return; + } + else { + // push the temp branch to the repository + await exec.exec(`git push --force --set-upstream origin HEAD:${temp_branch}`); + } + + if (!should_open_pull_request) { + console.log("Backport temp branch already exists, skipping opening a PR."); + return; + } + + // prepare the GitHub PR details + + // get users to cc (append PR author if different from user who issued the backport command) + let cc_users = `@${comment_user}`; + if (comment_user != context.payload.issue.user.login) cc_users += ` @${context.payload.issue.user.login}`; + + // replace the special placeholder tokens with values + const { BACKPORT_PR_TITLE_TEMPLATE, BACKPORT_PR_DESCRIPTION_TEMPLATE } = process.env + + const backport_pr_title = BACKPORT_PR_TITLE_TEMPLATE + .replace(/%target_branch%/g, target_branch) + .replace(/%source_pr_title%/g, context.payload.issue.title) + .replace(/%source_pr_number%/g, context.payload.issue.number) + .replace(/%cc_users%/g, cc_users); + + const backport_pr_description = BACKPORT_PR_DESCRIPTION_TEMPLATE + .replace(/%target_branch%/g, target_branch) + .replace(/%source_pr_title%/g, context.payload.issue.title) + .replace(/%source_pr_number%/g, context.payload.issue.number) + .replace(/%cc_users%/g, cc_users); + + // open the GitHub PR + await github.rest.pulls.create({ + owner: repo_owner, + repo: repo_name, + title: backport_pr_title, + body: backport_pr_description, + head: temp_branch, + base: target_branch + }); + + console.log("Successfully opened the GitHub PR."); + } catch (error) { + + core.setFailed(error); + + // post failure to GitHub comment + const unknown_error_body = `@${comment_user} an error occurred while backporting to ${target_branch}, please check the run log for details!\n\n${error.message}`; + await github.rest.issues.createComment({ + owner: repo_owner, + repo: repo_name, + issue_number: pr_number, + body: unknown_error_body + }); + } + + - name: Re-lock PR comments + uses: actions/github-script@v7 + if: ${{ github.event.issue.locked == true && (success() || failure()) }} + with: + script: | + console.log(`Locking previously locked PR #${context.issue.number} again.`); + await github.rest.issues.lock({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + lock_reason: "resolved" + }); \ No newline at end of file diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml new file mode 100644 index 0000000000..8f8e3af3d7 --- /dev/null +++ b/.github/workflows/backport.yml @@ -0,0 +1,23 @@ +name: Backport PR to branch +on: + issue_comment: + types: [created] + schedule: + # once a day at 13:00 UTC to cleanup old runs + - cron: '0 13 * * *' + +permissions: + contents: write + issues: write + pull-requests: write + actions: write + +jobs: + backport: + if: ${{ contains(github.event.comment.body, '/backport to') || github.event_name == 'schedule' }} + uses: microsoft/testfx/.github/workflows/backport-base.yml@main + with: + pr_description_template: | + Backport of #%source_pr_number% to %target_branch% + + /cc %cc_users% \ No newline at end of file From 4231021aa03a190a90e09e3ebff36e3bd2e0a90d Mon Sep 17 00:00:00 2001 From: Youssef1313 Date: Thu, 9 Jan 2025 22:11:07 +0100 Subject: [PATCH 273/273] GH Actions backport --- .github/workflows/backport-base.yml | 115 +++++++++++++++------------- .github/workflows/backport.yml | 2 +- 2 files changed, 61 insertions(+), 56 deletions(-) diff --git a/.github/workflows/backport-base.yml b/.github/workflows/backport-base.yml index 13178ce38b..8518144320 100644 --- a/.github/workflows/backport-base.yml +++ b/.github/workflows/backport-base.yml @@ -164,74 +164,74 @@ jobs: // download and apply patch await exec.exec(`curl -sSL "${context.payload.issue.pull_request.patch_url}" --output changes.patch`); - const git_am_command = "git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch"; - let git_am_output = `$ ${git_am_command}\n\n`; - let git_am_failed = false; - try { - await exec.exec(git_am_command, [], { - listeners: { - stdout: function stdout(data) { git_am_output += data; }, - stderr: function stderr(data) { git_am_output += data; } - } - }); - } catch (error) { - git_am_output += error; - git_am_failed = true; - } + // const git_am_command = "git am --3way --empty=keep --ignore-whitespace --keep-non-patch changes.patch"; + // let git_am_output = `$ ${git_am_command}\n\n`; + // let git_am_failed = false; + // try { + // await exec.exec(git_am_command, [], { + // listeners: { + // stdout: function stdout(data) { git_am_output += data; }, + // stderr: function stderr(data) { git_am_output += data; } + // } + // }); + // } catch (error) { + // git_am_output += error; + // git_am_failed = true; + // } - if (git_am_failed) { - const git_am_failed_body = `@${context.payload.comment.user.login} backporting to ${target_branch} failed, the patch most likely resulted in conflicts:\n\n\`\`\`shell\n${git_am_output}\n\`\`\`\n\nPlease backport manually!`; - await github.rest.issues.createComment({ - owner: repo_owner, - repo: repo_name, - issue_number: pr_number, - body: git_am_failed_body - }); - core.setFailed("Error: git am failed, most likely due to a merge conflict."); - return; - } - else { - // push the temp branch to the repository - await exec.exec(`git push --force --set-upstream origin HEAD:${temp_branch}`); - } + // if (git_am_failed) { + // const git_am_failed_body = `@${context.payload.comment.user.login} backporting to ${target_branch} failed, the patch most likely resulted in conflicts:\n\n\`\`\`shell\n${git_am_output}\n\`\`\`\n\nPlease backport manually!`; + // await github.rest.issues.createComment({ + // owner: repo_owner, + // repo: repo_name, + // issue_number: pr_number, + // body: git_am_failed_body + // }); + // core.setFailed("Error: git am failed, most likely due to a merge conflict."); + // return; + // } + // else { + // // push the temp branch to the repository + // await exec.exec(`git push --force --set-upstream origin HEAD:${temp_branch}`); + // } - if (!should_open_pull_request) { - console.log("Backport temp branch already exists, skipping opening a PR."); - return; - } + // if (!should_open_pull_request) { + // console.log("Backport temp branch already exists, skipping opening a PR."); + // return; + // } // prepare the GitHub PR details // get users to cc (append PR author if different from user who issued the backport command) - let cc_users = `@${comment_user}`; - if (comment_user != context.payload.issue.user.login) cc_users += ` @${context.payload.issue.user.login}`; + // let cc_users = `@${comment_user}`; + // if (comment_user != context.payload.issue.user.login) cc_users += ` @${context.payload.issue.user.login}`; // replace the special placeholder tokens with values - const { BACKPORT_PR_TITLE_TEMPLATE, BACKPORT_PR_DESCRIPTION_TEMPLATE } = process.env + // const { BACKPORT_PR_TITLE_TEMPLATE, BACKPORT_PR_DESCRIPTION_TEMPLATE } = process.env - const backport_pr_title = BACKPORT_PR_TITLE_TEMPLATE - .replace(/%target_branch%/g, target_branch) - .replace(/%source_pr_title%/g, context.payload.issue.title) - .replace(/%source_pr_number%/g, context.payload.issue.number) - .replace(/%cc_users%/g, cc_users); + // const backport_pr_title = BACKPORT_PR_TITLE_TEMPLATE + // .replace(/%target_branch%/g, target_branch) + // .replace(/%source_pr_title%/g, context.payload.issue.title) + // .replace(/%source_pr_number%/g, context.payload.issue.number) + // .replace(/%cc_users%/g, cc_users); - const backport_pr_description = BACKPORT_PR_DESCRIPTION_TEMPLATE - .replace(/%target_branch%/g, target_branch) - .replace(/%source_pr_title%/g, context.payload.issue.title) - .replace(/%source_pr_number%/g, context.payload.issue.number) - .replace(/%cc_users%/g, cc_users); + // const backport_pr_description = BACKPORT_PR_DESCRIPTION_TEMPLATE + // .replace(/%target_branch%/g, target_branch) + // .replace(/%source_pr_title%/g, context.payload.issue.title) + // .replace(/%source_pr_number%/g, context.payload.issue.number) + // .replace(/%cc_users%/g, cc_users); // open the GitHub PR - await github.rest.pulls.create({ - owner: repo_owner, - repo: repo_name, - title: backport_pr_title, - body: backport_pr_description, - head: temp_branch, - base: target_branch - }); + // await github.rest.pulls.create({ + // owner: repo_owner, + // repo: repo_name, + // title: backport_pr_title, + // body: backport_pr_description, + // head: temp_branch, + // base: target_branch + // }); - console.log("Successfully opened the GitHub PR."); + // console.log("Successfully opened the GitHub PR."); } catch (error) { core.setFailed(error); @@ -246,6 +246,11 @@ jobs: }); } + - uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # v7 + with: + token: ${{ secrets.BACKPORT_MACHINE_USER_PAT }} + push-to-fork: youssef-backport-bot/testfx + - name: Re-lock PR comments uses: actions/github-script@v7 if: ${{ github.event.issue.locked == true && (success() || failure()) }} diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 8f8e3af3d7..f0a13576ad 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -20,4 +20,4 @@ jobs: pr_description_template: | Backport of #%source_pr_number% to %target_branch% - /cc %cc_users% \ No newline at end of file + /cc %cc_users%