From d7161448250a9f2ece844713dd422cfedf65c126 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 26 Oct 2025 18:27:31 +0000
Subject: [PATCH 01/10] Initial plan
From d4997e48a349d07415886a3cfcc9b63999719293 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 26 Oct 2025 18:43:12 +0000
Subject: [PATCH 02/10] Add TaskRunTestMethodAttribute and update
analyzer/fixer
- Created TaskRunTestMethodAttribute that wraps test execution in Task.Run
- Updated UseCooperativeCancellationForTimeoutAnalyzer resources to mention TaskRunTestMethod
- Updated UseCooperativeCancellationForTimeoutFixer to offer TaskRunTestMethod as alternative
- Added test for new code fix option
- Updated PublicAPI.Unshipped.txt with new public API
- Updated all XLF localization files
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
---
.../CodeFixResources.resx | 3 +
...eCooperativeCancellationForTimeoutFixer.cs | 57 ++++++++++++-
.../xlf/CodeFixResources.cs.xlf | 25 ++++++
.../xlf/CodeFixResources.de.xlf | 25 ++++++
.../xlf/CodeFixResources.es.xlf | 25 ++++++
.../xlf/CodeFixResources.fr.xlf | 25 ++++++
.../xlf/CodeFixResources.it.xlf | 25 ++++++
.../xlf/CodeFixResources.ja.xlf | 25 ++++++
.../xlf/CodeFixResources.ko.xlf | 25 ++++++
.../xlf/CodeFixResources.pl.xlf | 25 ++++++
.../xlf/CodeFixResources.pt-BR.xlf | 25 ++++++
.../xlf/CodeFixResources.ru.xlf | 25 ++++++
.../xlf/CodeFixResources.tr.xlf | 25 ++++++
.../xlf/CodeFixResources.zh-Hans.xlf | 25 ++++++
.../xlf/CodeFixResources.zh-Hant.xlf | 25 ++++++
src/Analyzers/MSTest.Analyzers/Resources.resx | 6 +-
.../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 +--
.../TestMethod/TaskRunTestMethodAttribute.cs | 85 +++++++++++++++++++
.../PublicAPI/PublicAPI.Unshipped.txt | 4 +
...tiveCancellationForTimeoutAnalyzerTests.cs | 38 +++++++++
32 files changed, 591 insertions(+), 83 deletions(-)
create mode 100644 src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx
index 569baca6de..38e70f5be7 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/CodeFixResources.resx
@@ -180,6 +180,9 @@
Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+
Use 'Assert.{0}' instead of 'StringAssert'
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/UseCooperativeCancellationForTimeoutFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/UseCooperativeCancellationForTimeoutFixer.cs
index a3052a78f1..26e4a525ca 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/UseCooperativeCancellationForTimeoutFixer.cs
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/UseCooperativeCancellationForTimeoutFixer.cs
@@ -48,13 +48,25 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
return;
}
- // Register a code action that will invoke the fix
+ // Register code fix to add CooperativeCancellation = true
context.RegisterCodeFix(
CodeAction.Create(
title: CodeFixResources.UseCooperativeCancellationForTimeoutFix,
createChangedDocument: c => AddCooperativeCancellationAsync(context.Document, attributeSyntax, c),
- equivalenceKey: nameof(UseCooperativeCancellationForTimeoutFixer)),
+ equivalenceKey: $"{nameof(UseCooperativeCancellationForTimeoutFixer)}.AddCooperativeCancellation"),
diagnostic);
+
+ // Register code fix to replace [TestMethod] with [TaskRunTestMethod]
+ // Find the test method to check if it uses [TestMethod] attribute
+ if (attributeSyntax.Parent?.Parent is MethodDeclarationSyntax methodDeclaration)
+ {
+ context.RegisterCodeFix(
+ CodeAction.Create(
+ title: CodeFixResources.UseTaskRunTestMethodFix,
+ createChangedDocument: c => ReplaceWithTaskRunTestMethodAsync(context.Document, methodDeclaration, c),
+ equivalenceKey: $"{nameof(UseCooperativeCancellationForTimeoutFixer)}.UseTaskRunTestMethod"),
+ diagnostic);
+ }
}
private static async Task AddCooperativeCancellationAsync(Document document, AttributeSyntax attributeSyntax, CancellationToken cancellationToken)
@@ -118,4 +130,45 @@ private static async Task AddCooperativeCancellationAsync(Document doc
return editor.GetChangedDocument();
}
+
+ private static async Task ReplaceWithTaskRunTestMethodAsync(Document document, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken)
+ {
+ DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
+
+ // Find the TestMethod attribute
+ AttributeSyntax? testMethodAttribute = null;
+ foreach (AttributeListSyntax attributeList in methodDeclaration.AttributeLists)
+ {
+ foreach (AttributeSyntax attribute in attributeList.Attributes)
+ {
+ string attributeName = attribute.Name.ToString();
+ if (attributeName is "TestMethod" or "TestMethodAttribute")
+ {
+ testMethodAttribute = attribute;
+ break;
+ }
+ }
+
+ if (testMethodAttribute is not null)
+ {
+ break;
+ }
+ }
+
+ if (testMethodAttribute is null)
+ {
+ // No TestMethod attribute found, return unchanged document
+ return document;
+ }
+
+ // Create the new TaskRunTestMethod attribute preserving any arguments
+ AttributeSyntax newAttribute = SyntaxFactory.Attribute(
+ SyntaxFactory.IdentifierName("TaskRunTestMethod"),
+ testMethodAttribute.ArgumentList);
+
+ // Replace the TestMethod attribute with TaskRunTestMethod
+ editor.ReplaceNode(testMethodAttribute, newAttribute);
+
+ return editor.GetChangedDocument();
+ }
}
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf
index 8f9a0a8393..3c61950443 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.cs.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Použijte „CooperativeCancellation = true“
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf
index 374b6d3bde..8ddb440d14 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.de.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Verwenden Sie „CooperativeCancellation = true“.
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf
index 66742db404..f4f4227367 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.es.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Usa "CooperativeCancellation = true"
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf
index ec66aaf4da..e6b7432578 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.fr.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Utilisez 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf
index fad6511ba2..8ebcf86586 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.it.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Usa "CooperativeCancellation = true"
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf
index 422dd62c24..d5dc334ed9 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ja.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ 'CooperativeCancellation = true' を使用する
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf
index 2bd87cf1af..a9b98227fc 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ko.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ 'CooperativeCancellation = true'를 사용하세요.
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf
index 3ce2f0eda3..d1358104cf 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pl.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Użyj opcji „CooperativeCancellation = true”
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
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 3e7f19fb87..c04f99db77 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.pt-BR.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Usar “CooperativoCancellation = true”
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf
index e442c31ee5..18c84c357f 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.ru.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Использовать "CooperativeCancellation = true"
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf
index 28c764a1ea..0b130079be 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.tr.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ 'CooperativeCancellation = true' kullanın
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
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 6563ec971c..415845ae21 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hans.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ 使用 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
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 bca5bd3526..bfa0092e03 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/xlf/CodeFixResources.zh-Hant.xlf
@@ -138,8 +138,33 @@
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ Use 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+ 使用 'CooperativeCancellation = true'
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
+
+
+
+
+ Use '[TaskRunTestMethod]'
+ Use '[TaskRunTestMethod]'
diff --git a/src/Analyzers/MSTest.Analyzers/Resources.resx b/src/Analyzers/MSTest.Analyzers/Resources.resx
index 0c8a17d969..e50ed6c081 100644
--- a/src/Analyzers/MSTest.Analyzers/Resources.resx
+++ b/src/Analyzers/MSTest.Analyzers/Resources.resx
@@ -589,13 +589,13 @@ The type declaring these methods should also respect the following rules:
'DataTestMethodAttribute' is obsolete and provides no additional functionality over 'TestMethodAttribute'. Use 'TestMethodAttribute' for all test methods, including parameterized tests.
- Use 'CooperativeCancellation = true' with '[Timeout]'
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.TestContext property cannot be accessed in this context
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf
index ba62836f66..e0aabea84f 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.cs.xlf
@@ -900,18 +900,18 @@ Typ deklarující tyto metody by měl také respektovat následující pravidla:
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- Použití „[Timeout]“ bez explicitního nastavení „CooperativeCancellation = true“ se nedoporučuje. V budoucí verzi se kooperativní zrušení stane výchozím chováním. Nastavte „CooperativeCancellation = true“, abyste zapnuli doporučené chování a vyhnuli se změnám, které by mohly způsobit problémy.
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ Použití „[Timeout]“ bez explicitního nastavení „CooperativeCancellation = true“ se nedoporučuje. V budoucí verzi se kooperativní zrušení stane výchozím chováním. Nastavte „CooperativeCancellation = true“, abyste zapnuli doporučené chování a vyhnuli se změnám, které by mohly způsobit problémy.
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- Použijte „CooperativeCancellation = true“ s „[Timeout]“, abyste povolili chování kooperativního zrušení
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ Použijte „CooperativeCancellation = true“ s „[Timeout]“, abyste povolili chování kooperativního zrušení
- Use 'CooperativeCancellation = true' with '[Timeout]'
- Použijte „CooperativeCancellation = true“ s „[Timeout]“
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ Použijte „CooperativeCancellation = true“ s „[Timeout]“
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf
index 76737e3938..627eec058a 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.de.xlf
@@ -901,18 +901,18 @@ Der Typ, der diese Methoden deklariert, sollte auch die folgenden Regeln beachte
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- Es wird davon abgeraten, „[Timeout]“ ohne die explizite Festlegung von „CooperativeCancellation = true“ zu verwenden. In einer zukünftigen Version wird der kooperative Abbruch das Standardverhalten sein. Legen Sie „CooperativeCancellation = true“ fest, um das empfohlene Verhalten zu aktivieren und Breaking Changes zu vermeiden.
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ Es wird davon abgeraten, „[Timeout]“ ohne die explizite Festlegung von „CooperativeCancellation = true“ zu verwenden. In einer zukünftigen Version wird der kooperative Abbruch das Standardverhalten sein. Legen Sie „CooperativeCancellation = true“ fest, um das empfohlene Verhalten zu aktivieren und Breaking Changes zu vermeiden.
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- Verwenden Sie „CooperativeCancellation = true“ mit „[Timeout]“, um das kooperative Abbruchverhalten zu aktivieren.
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ Verwenden Sie „CooperativeCancellation = true“ mit „[Timeout]“, um das kooperative Abbruchverhalten zu aktivieren.
- Use 'CooperativeCancellation = true' with '[Timeout]'
- Verwenden Sie „CooperativeCancellation = true“ mit „[Timeout]“.
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ Verwenden Sie „CooperativeCancellation = true“ mit „[Timeout]“.
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf
index 3e7bb27bc0..e860405726 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.es.xlf
@@ -900,18 +900,18 @@ El tipo que declara estos métodos también debe respetar las reglas siguientes:
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- No se recomienda usar "[Timeout]" sin establecer explícitamente "CooperativeCancellation = true". En una versión futura, la cancelación cooperativa se convertirá en el comportamiento predeterminado. Establece "CooperativeCancellation = true" para participar en el comportamiento recomendado y evitar cambios importantes.
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ No se recomienda usar "[Timeout]" sin establecer explícitamente "CooperativeCancellation = true". En una versión futura, la cancelación cooperativa se convertirá en el comportamiento predeterminado. Establece "CooperativeCancellation = true" para participar en el comportamiento recomendado y evitar cambios importantes.
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- Usa "CooperativeCancellation = true" con "[Timeout]" para habilitar el comportamiento de cancelación cooperativa.
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ Usa "CooperativeCancellation = true" con "[Timeout]" para habilitar el comportamiento de cancelación cooperativa.
- Use 'CooperativeCancellation = true' with '[Timeout]'
- Usa "CooperativeCancellation = true" con "[Timeout]"
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ Usa "CooperativeCancellation = true" con "[Timeout]"
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf
index 8b30fdd14e..d422f79a0a 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.fr.xlf
@@ -900,18 +900,18 @@ Le type doit être une classe
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- L’utilisation de '[Timeout]' sans définir explicitement 'CooperativeCancellation = true' est déconseillée. Dans une future version, l’annulation coopérative deviendra le comportement par défaut. Définissez 'CooperativeCancellation = true' pour adopter le comportement recommandé et éviter les changements incompatibles.
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ L’utilisation de '[Timeout]' sans définir explicitement 'CooperativeCancellation = true' est déconseillée. Dans une future version, l’annulation coopérative deviendra le comportement par défaut. Définissez 'CooperativeCancellation = true' pour adopter le comportement recommandé et éviter les changements incompatibles.
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- Utilisez 'CooperativeCancellation = true' avec '[Timeout]' pour activer le comportement d’annulation coopératif
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ Utilisez 'CooperativeCancellation = true' avec '[Timeout]' pour activer le comportement d’annulation coopératif
- Use 'CooperativeCancellation = true' with '[Timeout]'
- Utiliser 'CooperativeCancellation = true' avec '[Timeout]'
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ Utiliser 'CooperativeCancellation = true' avec '[Timeout]'
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf
index 06dd23cd42..8e0c6c630d 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.it.xlf
@@ -900,18 +900,18 @@ Anche il tipo che dichiara questi metodi deve rispettare le regole seguenti:
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- L'uso di "[Timeout]" senza impostare esplicitamente "CooperativeCancellation = true" è sconsigliato. In una versione futura l'annullamento cooperativo diventerà il comportamento predefinito. Impostare "CooperativeCancellation = true" per acconsentire esplicitamente al comportamento consigliato ed evitare modifiche che causano un'interruzione.
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ L'uso di "[Timeout]" senza impostare esplicitamente "CooperativeCancellation = true" è sconsigliato. In una versione futura l'annullamento cooperativo diventerà il comportamento predefinito. Impostare "CooperativeCancellation = true" per acconsentire esplicitamente al comportamento consigliato ed evitare modifiche che causano un'interruzione.
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- Usare "CooperativeCancellation = true" con "[Timeout]" per abilitare il comportamento di annullamento cooperativo
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ Usare "CooperativeCancellation = true" con "[Timeout]" per abilitare il comportamento di annullamento cooperativo
- Use 'CooperativeCancellation = true' with '[Timeout]'
- Usa "CooperativeCancellation = true" con "[Timeout]"
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ Usa "CooperativeCancellation = true" con "[Timeout]"
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf
index ab704cbb51..d3cf1a9a89 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ja.xlf
@@ -900,18 +900,18 @@ The type declaring these methods should also respect the following rules:
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- 'CooperativeCancellation = true' を明示的にを設定せずに '[Timeout]' を使用することは推奨されません。将来のバージョンでは、協調的キャンセルが既定の動作になります。推奨される動作をオプトインし、破壊的な変更を避けるために、'CooperativeCancellation = true' を設定します。
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ 'CooperativeCancellation = true' を明示的にを設定せずに '[Timeout]' を使用することは推奨されません。将来のバージョンでは、協調的キャンセルが既定の動作になります。推奨される動作をオプトインし、破壊的な変更を避けるために、'CooperativeCancellation = true' を設定します。
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- '[Timeout]' と共に 'CooperativeCancellation = true' を使用して、協調的キャンセルの動作を有効にします
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ '[Timeout]' と共に 'CooperativeCancellation = true' を使用して、協調的キャンセルの動作を有効にします
- Use 'CooperativeCancellation = true' with '[Timeout]'
- '[Timeout]' と共に 'CooperativeCancellation = true' を使用する
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ '[Timeout]' と共に 'CooperativeCancellation = true' を使用する
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf
index e1579bc142..c68103bc37 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ko.xlf
@@ -900,18 +900,18 @@ The type declaring these methods should also respect the following rules:
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- 'CooperativeCancellation = true'를 명시적으로 설정하지 않고 '[Timeout]'을 사용하는 것은 권장되지 않습니다. 향후 버전에서는 협동 취소가 기본 동작으로 설정될 것입니다. 권장 동작을 선택하고 변경 사항으로 인한 문제를 피하려면 'CooperativeCancellation = true'를 설정하세요.
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ 'CooperativeCancellation = true'를 명시적으로 설정하지 않고 '[Timeout]'을 사용하는 것은 권장되지 않습니다. 향후 버전에서는 협동 취소가 기본 동작으로 설정될 것입니다. 권장 동작을 선택하고 변경 사항으로 인한 문제를 피하려면 'CooperativeCancellation = true'를 설정하세요.
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- '[Timeout]'와 함께 'CooperativeCancellation = true'를 사용하여 협동 취소 동작을 활성화하세요.
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ '[Timeout]'와 함께 'CooperativeCancellation = true'를 사용하여 협동 취소 동작을 활성화하세요.
- Use 'CooperativeCancellation = true' with '[Timeout]'
- '[Timeout]'와 함께 'CooperativeCancellation = true'를 사용하세요.
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ '[Timeout]'와 함께 'CooperativeCancellation = true'를 사용하세요.
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf
index 8b72c8d6e2..fc4b1280e6 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pl.xlf
@@ -900,18 +900,18 @@ Typ deklarujący te metody powinien również przestrzegać następujących regu
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- Nie rekomenduje się używania elementu „[Timeout]” bez jawnego ustawiania wartości „CooperativeCancellation = true”. W przyszłej wersji anulowanie trybu współpracy będzie zachowaniem domyślnym. Ustaw opcję „CooperativeCancellation = true”, aby włączyć rekomendowane zachowanie i uniknąć zmian powodujących niezgodność.
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ Nie rekomenduje się używania elementu „[Timeout]” bez jawnego ustawiania wartości „CooperativeCancellation = true”. W przyszłej wersji anulowanie trybu współpracy będzie zachowaniem domyślnym. Ustaw opcję „CooperativeCancellation = true”, aby włączyć rekomendowane zachowanie i uniknąć zmian powodujących niezgodność.
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- Użyj opcji „CooperativeCancellation = true” z limitem czasu „[Timeout]”, aby włączyć zachowanie anulowania trybu współpracy
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ Użyj opcji „CooperativeCancellation = true” z limitem czasu „[Timeout]”, aby włączyć zachowanie anulowania trybu współpracy
- Use 'CooperativeCancellation = true' with '[Timeout]'
- Użyj opcji „CooperativeCancellation = true” w limitem czasu „[Timeout]”
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ Użyj opcji „CooperativeCancellation = true” w limitem czasu „[Timeout]”
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf
index 3e9f3a2913..ab4c7a09fc 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.pt-BR.xlf
@@ -900,18 +900,18 @@ O tipo que declara esses métodos também deve respeitar as seguintes regras:
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- Usar '\[Timeout]' sem definir explicitamente 'CooperativeCancellation = true' não é recomendado. Em uma versão futura, o cancelamento cooperativo se tornará o comportamento padrão. Defina 'CooperativeCancellation = true' para optar pelo comportamento recomendado e evitar quebras.
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ Usar '\[Timeout]' sem definir explicitamente 'CooperativeCancellation = true' não é recomendado. Em uma versão futura, o cancelamento cooperativo se tornará o comportamento padrão. Defina 'CooperativeCancellation = true' para optar pelo comportamento recomendado e evitar quebras.
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- Use 'CooperativeCancellation = true' com '\[Timeout]' para habilitar o comportamento de cancelamento cooperativo
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ Use 'CooperativeCancellation = true' com '\[Timeout]' para habilitar o comportamento de cancelamento cooperativo
- Use 'CooperativeCancellation = true' with '[Timeout]'
- Use 'CooperativeCancellation = true' com '\[Timeout]'
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ Use 'CooperativeCancellation = true' com '\[Timeout]'
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf
index 2a32db08a3..64f17d2cbb 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.ru.xlf
@@ -912,18 +912,18 @@ The type declaring these methods should also respect the following rules:
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- Использование "[Timeout]" без явной настройки "CooperativeCancellation = true" не рекомендуется. В будущей версии кооперативная отмена станет поведением по умолчанию. Настройте "CooperativeCancellation = true", чтобы согласиться с рекомендуемым поведением и избежать критических изменений.
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ Использование "[Timeout]" без явной настройки "CooperativeCancellation = true" не рекомендуется. В будущей версии кооперативная отмена станет поведением по умолчанию. Настройте "CooperativeCancellation = true", чтобы согласиться с рекомендуемым поведением и избежать критических изменений.
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- Используйте "CooperativeCancellation = true" с "[Timeout]", чтобы включить поведение кооперативной отмены
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ Используйте "CooperativeCancellation = true" с "[Timeout]", чтобы включить поведение кооперативной отмены
- Use 'CooperativeCancellation = true' with '[Timeout]'
- Использовать "CooperativeCancellation = true" с "[Timeout]"
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ Использовать "CooperativeCancellation = true" с "[Timeout]"
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf
index 4c959ae0e5..c31db20b29 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.tr.xlf
@@ -902,18 +902,18 @@ Bu yöntemleri bildiren tipin ayrıca aşağıdaki kurallara uyması gerekir:
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- '[Timeout]' ayarını 'CooperativeCancellation = true' olarak açıkça ayarlamadan kullanmak önerilmez. Gelecek bir sürümde, birlikte iptal etme varsayılan davranış haline gelecektir. Önerilen davranışı kabul etmek ve uyumsuzlukları önlemek için 'CooperativeCancellation = true' değerini ayarlayın.
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ '[Timeout]' ayarını 'CooperativeCancellation = true' olarak açıkça ayarlamadan kullanmak önerilmez. Gelecek bir sürümde, birlikte iptal etme varsayılan davranış haline gelecektir. Önerilen davranışı kabul etmek ve uyumsuzlukları önlemek için 'CooperativeCancellation = true' değerini ayarlayın.
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- '[Timeout]' ile 'CooperativeCancellation = true' kullanarak birlikte iptal etme davranışını etkinleştirin
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ '[Timeout]' ile 'CooperativeCancellation = true' kullanarak birlikte iptal etme davranışını etkinleştirin
- Use 'CooperativeCancellation = true' with '[Timeout]'
- '[Timeout]' ile 'CooperativeCancellation = true' kullanın
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ '[Timeout]' ile 'CooperativeCancellation = true' 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 2058347afa..f44eff9922 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hans.xlf
@@ -900,18 +900,18 @@ The type declaring these methods should also respect the following rules:
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- 不建议在不显式设置 'CooperativeCancellation = true' 的情况下使用 '[Timeout]'。在将来的版本中,协作取消将成为默认行为。设置 'CooperativeCancellation = true' 以选择加入建议的行为,并避免中断性变更。
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ 不建议在不显式设置 'CooperativeCancellation = true' 的情况下使用 '[Timeout]'。在将来的版本中,协作取消将成为默认行为。设置 'CooperativeCancellation = true' 以选择加入建议的行为,并避免中断性变更。
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- 将 'CooperativeCancellation = true' 与 '[Timeout]' 配合使用以启用协作取消行为
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ 将 'CooperativeCancellation = true' 与 '[Timeout]' 配合使用以启用协作取消行为
- Use 'CooperativeCancellation = true' with '[Timeout]'
- 将 'CooperativeCancellation = true' 与 '[Timeout]' 配合使用
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ 将 'CooperativeCancellation = true' 与 '[Timeout]' 配合使用
diff --git a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf
index 228d78acdd..5ffc34a291 100644
--- a/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf
+++ b/src/Analyzers/MSTest.Analyzers/xlf/Resources.zh-Hant.xlf
@@ -900,18 +900,18 @@ The type declaring these methods should also respect the following rules:
- Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' is discouraged. In a future version, cooperative cancellation will become the default behavior. Set 'CooperativeCancellation = true' to opt into the recommended behavior and avoid breaking changes.
- 在未明確設定 'CooperativeCancellation = true' 的情況下,不建議使用 '[Timeout]'。在未來的版本中,合作取消將成為預設行為。請設定 'CooperativeCancellation = true' 以選擇加入推薦的行為,並避免破壞性變更。
+ Using '[Timeout]' without explicitly setting 'CooperativeCancellation = true' or using '[TaskRunTestMethod]' is discouraged as it can lead to dangling tasks. Use '[TaskRunTestMethod]' to run tests in Task.Run with proper timeout handling, or set 'CooperativeCancellation = true' to enable cooperative cancellation behavior.
+ 在未明確設定 'CooperativeCancellation = true' 的情況下,不建議使用 '[Timeout]'。在未來的版本中,合作取消將成為預設行為。請設定 'CooperativeCancellation = true' 以選擇加入推薦的行為,並避免破壞性變更。
- Use 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior
- 使用 'CooperativeCancellation = true' 搭配 '[Timeout]' 以啟用合作取消行為
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]' to enable cooperative cancellation behavior and avoid dangling tasks
+ 使用 'CooperativeCancellation = true' 搭配 '[Timeout]' 以啟用合作取消行為
- Use 'CooperativeCancellation = true' with '[Timeout]'
- 使用 'CellCancellation = true' 搭配 '[Timeout]'
+ Use '[TaskRunTestMethod]' or 'CooperativeCancellation = true' with '[Timeout]'
+ 使用 'CellCancellation = true' 搭配 '[Timeout]'
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
new file mode 100644
index 0000000000..3414fbdf41
--- /dev/null
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
@@ -0,0 +1,85 @@
+// 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;
+
+///
+/// The TaskRun test method attribute.
+///
+///
+///
+/// This attribute is designed to handle test method execution with timeout by running the test code within a .
+/// This allows the test runner to stop watching the task in case of timeout, preventing dangling tasks that can lead to
+/// confusion or errors because the test method is still running in the background.
+///
+///
+/// When a timeout occurs:
+///
+/// The test is marked as timed out.
+/// The cancellation token from is canceled.
+/// The test runner stops awaiting the test task, allowing it to complete in the background.
+///
+///
+///
+/// For best results, test methods should observe the cancellation token and cancel cooperatively.
+/// If the test method does not handle cancellation properly, the task may continue running after the timeout,
+/// which can still lead to issues, but the test runner will not block waiting for it to complete.
+///
+///
+[AttributeUsage(AttributeTargets.Method)]
+public class TaskRunTestMethodAttribute : TestMethodAttribute
+{
+ private readonly TestMethodAttribute? _testMethodAttribute;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public TaskRunTestMethodAttribute([CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = -1)
+ : base(callerFilePath, callerLineNumber)
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ /// This constructor is intended to be called by test class attributes to wrap an existing test method attribute.
+ ///
+ /// The wrapped test method.
+ public TaskRunTestMethodAttribute(TestMethodAttribute testMethodAttribute)
+ : base(testMethodAttribute.DeclaringFilePath, testMethodAttribute.DeclaringLineNumber ?? -1)
+ => _testMethodAttribute = testMethodAttribute;
+
+ ///
+ /// Executes a test method by wrapping it in a to allow timeout handling.
+ ///
+ /// The test method to execute.
+ /// An array of TestResult objects that represent the outcome(s) of the test.
+ public override async Task ExecuteAsync(ITestMethod testMethod)
+ {
+ if (_testMethodAttribute is not null)
+ {
+ return await ExecuteWithTaskRunAsync(() => _testMethodAttribute.ExecuteAsync(testMethod)).ConfigureAwait(false);
+ }
+
+ return await ExecuteWithTaskRunAsync(() => testMethod.InvokeAsync(null)).ConfigureAwait(false);
+ }
+
+ private static async Task ExecuteWithTaskRunAsync(Func> executeFunc)
+ {
+ // Run the test method in Task.Run so that we can stop awaiting it on timeout
+ // while allowing it to complete in the background
+ Task testTask = Task.Run(executeFunc);
+
+ TestResult result = await testTask.ConfigureAwait(false);
+ return [result];
+ }
+
+ private static async Task ExecuteWithTaskRunAsync(Func> executeFunc)
+ {
+ // Run the test method in Task.Run so that we can stop awaiting it on timeout
+ // while allowing it to complete in the background
+ Task testTask = Task.Run(executeFunc);
+
+ TestResult[] results = await testTask.ConfigureAwait(false);
+ return results;
+ }
+}
diff --git a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt
index 7dc5c58110..1050aa7571 100644
--- a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt
+++ b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt
@@ -1 +1,5 @@
#nullable enable
+Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute
+Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute.ExecuteAsync(Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod testMethod) -> System.Threading.Tasks.Task!
+Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute.TaskRunTestMethodAttribute(Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute! testMethodAttribute) -> void
+Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute.TaskRunTestMethodAttribute(string! callerFilePath = "", int callerLineNumber = -1) -> void
diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs
index 5d090b4bae..067f8973a7 100644
--- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs
+++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs
@@ -440,4 +440,42 @@ public static void MyAssemblyCleanup()
await VerifyCS.VerifyCodeFixAsync(code, fixedCode);
}
+
+ [TestMethod]
+ public async Task WhenTimeoutAttributeWithoutCooperativeCancellation_CodeFixOffersTaskRunTestMethod()
+ {
+ string code = """
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class MyTestClass
+ {
+ [TestMethod]
+ [{|#0:Timeout(5000)|}]
+ public void MyTestMethod()
+ {
+ }
+ }
+ """;
+
+ string fixedCodeWithTaskRunTestMethod = """
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class MyTestClass
+ {
+ [TaskRunTestMethod]
+ [{|#0:Timeout(5000)|}]
+ public void MyTestMethod()
+ {
+ }
+ }
+ """;
+
+ await VerifyCS.VerifyCodeFixAsync(
+ code,
+ VerifyCS.Diagnostic().WithLocation(0),
+ fixedCodeWithTaskRunTestMethod,
+ codeFixIndex: 1); // Second code fix option
+ }
}
From f9d1af13cf4ffbca39b13c07cd0c010e47ddd208 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 26 Oct 2025 18:45:18 +0000
Subject: [PATCH 03/10] Fix TaskRunTestMethodAttribute implementation
- Simplified ExecuteAsync to avoid duplicate helper methods
- Fixed logic for wrapping test invocation in Task.Run
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
---
.../Attributes/TestMethod/TaskRunTestMethodAttribute.cs | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
index 3414fbdf41..ebd2a0cbf5 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
@@ -60,15 +60,9 @@ public override async Task ExecuteAsync(ITestMethod testMethod)
return await ExecuteWithTaskRunAsync(() => _testMethodAttribute.ExecuteAsync(testMethod)).ConfigureAwait(false);
}
- return await ExecuteWithTaskRunAsync(() => testMethod.InvokeAsync(null)).ConfigureAwait(false);
- }
-
- private static async Task ExecuteWithTaskRunAsync(Func> executeFunc)
- {
// Run the test method in Task.Run so that we can stop awaiting it on timeout
// while allowing it to complete in the background
- Task testTask = Task.Run(executeFunc);
-
+ Task testTask = Task.Run(() => testMethod.InvokeAsync(null));
TestResult result = await testTask.ConfigureAwait(false);
return [result];
}
From 7dc7c3dc10aff04f76495f0632eae2d13cdb9d8d Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 26 Oct 2025 18:47:17 +0000
Subject: [PATCH 04/10] Refactor TaskRunTestMethodAttribute to use consistent
helper pattern
- Use ExecuteWithTaskRunAsync helper for both code paths to reduce duplication
- Ensures consistent Task.Run wrapping logic
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
---
.../TestMethod/TaskRunTestMethodAttribute.cs | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
index ebd2a0cbf5..5089f07564 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
@@ -60,11 +60,11 @@ public override async Task ExecuteAsync(ITestMethod testMethod)
return await ExecuteWithTaskRunAsync(() => _testMethodAttribute.ExecuteAsync(testMethod)).ConfigureAwait(false);
}
- // Run the test method in Task.Run so that we can stop awaiting it on timeout
- // while allowing it to complete in the background
- Task testTask = Task.Run(() => testMethod.InvokeAsync(null));
- TestResult result = await testTask.ConfigureAwait(false);
- return [result];
+ return await ExecuteWithTaskRunAsync(async () =>
+ {
+ TestResult result = await testMethod.InvokeAsync(null).ConfigureAwait(false);
+ return new[] { result };
+ }).ConfigureAwait(false);
}
private static async Task ExecuteWithTaskRunAsync(Func> executeFunc)
@@ -72,7 +72,6 @@ private static async Task ExecuteWithTaskRunAsync(Func testTask = Task.Run(executeFunc);
-
TestResult[] results = await testTask.ConfigureAwait(false);
return results;
}
From 2edb2b4aafa8e1cc9d26fdddca5ef01a60a32e08 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 26 Oct 2025 18:50:28 +0000
Subject: [PATCH 05/10] Update analyzer to not warn when
TaskRunTestMethodAttribute is used
- Modified UseCooperativeCancellationForTimeoutAnalyzer to check for TaskRunTestMethodAttribute
- When TaskRunTestMethodAttribute is present, no diagnostic is reported since it provides Task.Run behavior
- Added test to verify TaskRunTestMethodAttribute with Timeout doesn't trigger diagnostic
- Fixed test to remove diagnostic marker from fixed code
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
---
...operativeCancellationForTimeoutAnalyzer.cs | 14 ++++++++++--
...tiveCancellationForTimeoutAnalyzerTests.cs | 22 ++++++++++++++++++-
2 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs
index ee452b0af7..02fa6bcacb 100644
--- a/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs
+++ b/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs
@@ -57,17 +57,27 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo
var methodSymbol = (IMethodSymbol)context.Symbol;
AttributeData? timeoutAttribute = null;
+ bool hasTaskRunTestMethodAttribute = false;
+
foreach (AttributeData attribute in methodSymbol.GetAttributes())
{
if (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, timeoutAttributeSymbol))
{
timeoutAttribute = attribute;
- break;
+ }
+
+ // Check if the method uses TaskRunTestMethodAttribute
+ string? attributeName = attribute.AttributeClass?.Name;
+ if (attributeName is "TaskRunTestMethodAttribute" or "TaskRunTestMethod")
+ {
+ hasTaskRunTestMethodAttribute = true;
}
}
- // Report diagnostic if CooperativeCancellation is not explicitly set to true
+ // Don't report diagnostic if using TaskRunTestMethodAttribute (it provides Task.Run behavior)
+ // or if CooperativeCancellation is explicitly set to true
if (timeoutAttribute is not null
+ && !hasTaskRunTestMethodAttribute
&& !timeoutAttribute.NamedArguments.Any(x => x.Key == "CooperativeCancellation" && x.Value.Value is bool boolValue && boolValue))
{
if (timeoutAttribute.ApplicationSyntaxReference?.GetSyntax() is { } syntax)
diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs
index 067f8973a7..606230283d 100644
--- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs
+++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs
@@ -465,7 +465,7 @@ public void MyTestMethod()
public class MyTestClass
{
[TaskRunTestMethod]
- [{|#0:Timeout(5000)|}]
+ [Timeout(5000)]
public void MyTestMethod()
{
}
@@ -478,4 +478,24 @@ await VerifyCS.VerifyCodeFixAsync(
fixedCodeWithTaskRunTestMethod,
codeFixIndex: 1); // Second code fix option
}
+
+ [TestMethod]
+ public async Task WhenTaskRunTestMethodAttributeWithTimeout_NoDiagnostic()
+ {
+ string code = """
+ using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+ [TestClass]
+ public class MyTestClass
+ {
+ [TaskRunTestMethod]
+ [Timeout(5000)]
+ public void MyTestMethod()
+ {
+ }
+ }
+ """;
+
+ await VerifyCS.VerifyCodeFixAsync(code, code);
+ }
}
From bebad3ee061141fb8eff7ff6f030634961f2b7af Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 26 Oct 2025 18:52:39 +0000
Subject: [PATCH 06/10] Use proper symbol comparison in analyzer
- Added TaskRunTestMethodAttribute to WellKnownTypeNames
- Updated analyzer to use SymbolEqualityComparer instead of string comparison
- Supports inheritance from TaskRunTestMethodAttribute
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
---
.../Helpers/WellKnownTypeNames.cs | 1 +
...operativeCancellationForTimeoutAnalyzer.cs | 23 ++++++++++++-------
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs b/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs
index f2ed45a0f9..81e3665fed 100644
--- a/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs
+++ b/src/Analyzers/MSTest.Analyzers/Helpers/WellKnownTypeNames.cs
@@ -32,6 +32,7 @@ internal static class WellKnownTypeNames
public const string MicrosoftVisualStudioTestToolsUnitTestingPriorityAttribute = "Microsoft.VisualStudio.TestTools.UnitTesting.PriorityAttribute";
public const string MicrosoftVisualStudioTestToolsUnitTestingRetryBaseAttribute = "Microsoft.VisualStudio.TestTools.UnitTesting.RetryBaseAttribute";
public const string MicrosoftVisualStudioTestToolsUnitTestingStringAssert = "Microsoft.VisualStudio.TestTools.UnitTesting.StringAssert";
+ public const string MicrosoftVisualStudioTestToolsUnitTestingTaskRunTestMethodAttribute = "Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute";
public const string MicrosoftVisualStudioTestToolsUnitTestingTestClassAttribute = "Microsoft.VisualStudio.TestTools.UnitTesting.TestClassAttribute";
public const string MicrosoftVisualStudioTestToolsUnitTestingTestCleanupAttribute = "Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute";
public const string MicrosoftVisualStudioTestToolsUnitTestingTestContext = "Microsoft.VisualStudio.TestTools.UnitTesting.TestContext";
diff --git a/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs
index 02fa6bcacb..c6ad1c0ded 100644
--- a/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs
+++ b/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs
@@ -43,16 +43,21 @@ public override void Initialize(AnalysisContext context)
context.RegisterCompilationStartAction(context =>
{
- if (context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTimeoutAttribute, out INamedTypeSymbol? timeoutAttributeSymbol))
+ if (!context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTimeoutAttribute, out INamedTypeSymbol? timeoutAttributeSymbol))
{
- context.RegisterSymbolAction(
- context => AnalyzeSymbol(context, timeoutAttributeSymbol),
- SymbolKind.Method);
+ return;
}
+
+ // Try to get TaskRunTestMethodAttribute symbol (it's a new attribute so it might not exist in older versions)
+ context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTaskRunTestMethodAttribute, out INamedTypeSymbol? taskRunTestMethodAttributeSymbol);
+
+ context.RegisterSymbolAction(
+ context => AnalyzeSymbol(context, timeoutAttributeSymbol, taskRunTestMethodAttributeSymbol),
+ SymbolKind.Method);
});
}
- private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol timeoutAttributeSymbol)
+ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbol timeoutAttributeSymbol, INamedTypeSymbol? taskRunTestMethodAttributeSymbol)
{
var methodSymbol = (IMethodSymbol)context.Symbol;
@@ -66,9 +71,11 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo
timeoutAttribute = attribute;
}
- // Check if the method uses TaskRunTestMethodAttribute
- string? attributeName = attribute.AttributeClass?.Name;
- if (attributeName is "TaskRunTestMethodAttribute" or "TaskRunTestMethod")
+ // Check if the method uses TaskRunTestMethodAttribute or any derived type
+ if (taskRunTestMethodAttributeSymbol is not null &&
+ attribute.AttributeClass is not null &&
+ (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, taskRunTestMethodAttributeSymbol) ||
+ attribute.AttributeClass.InheritsFromOrEquals(taskRunTestMethodAttributeSymbol)))
{
hasTaskRunTestMethodAttribute = true;
}
From e0e03a93fab8f0d09d06058420ad8d1c9d207e16 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Sun, 26 Oct 2025 18:54:18 +0000
Subject: [PATCH 07/10] Refactor analyzer for better readability
- Improved comment about TaskRunTestMethodAttribute symbol handling
- Extracted IsTaskRunTestMethodAttribute helper method for cleaner code
- Better separation of concerns in the analyzer logic
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
---
...operativeCancellationForTimeoutAnalyzer.cs | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs b/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs
index c6ad1c0ded..60d9930b4f 100644
--- a/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs
+++ b/src/Analyzers/MSTest.Analyzers/UseCooperativeCancellationForTimeoutAnalyzer.cs
@@ -48,7 +48,8 @@ public override void Initialize(AnalysisContext context)
return;
}
- // Try to get TaskRunTestMethodAttribute symbol (it's a new attribute so it might not exist in older versions)
+ // Try to get TaskRunTestMethodAttribute symbol. It might not exist in older versions,
+ // but that's OK - the analyzer will still work, just without the suppression logic.
context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftVisualStudioTestToolsUnitTestingTaskRunTestMethodAttribute, out INamedTypeSymbol? taskRunTestMethodAttributeSymbol);
context.RegisterSymbolAction(
@@ -72,10 +73,7 @@ private static void AnalyzeSymbol(SymbolAnalysisContext context, INamedTypeSymbo
}
// Check if the method uses TaskRunTestMethodAttribute or any derived type
- if (taskRunTestMethodAttributeSymbol is not null &&
- attribute.AttributeClass is not null &&
- (SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, taskRunTestMethodAttributeSymbol) ||
- attribute.AttributeClass.InheritsFromOrEquals(taskRunTestMethodAttributeSymbol)))
+ if (IsTaskRunTestMethodAttribute(attribute, taskRunTestMethodAttributeSymbol))
{
hasTaskRunTestMethodAttribute = true;
}
@@ -93,4 +91,15 @@ attribute.AttributeClass is not null &&
}
}
}
+
+ private static bool IsTaskRunTestMethodAttribute(AttributeData attribute, INamedTypeSymbol? taskRunTestMethodAttributeSymbol)
+ {
+ if (taskRunTestMethodAttributeSymbol is null || attribute.AttributeClass is null)
+ {
+ return false;
+ }
+
+ return SymbolEqualityComparer.Default.Equals(attribute.AttributeClass, taskRunTestMethodAttributeSymbol)
+ || attribute.AttributeClass.InheritsFromOrEquals(taskRunTestMethodAttributeSymbol);
+ }
}
From 2e87e1faca9a1ba695a55e7edf48f9a93236d115 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Amaury=20Lev=C3=A9?=
Date: Mon, 27 Oct 2025 08:20:01 +0100
Subject: [PATCH 08/10] Update
src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
Co-authored-by: Youssef Victor
---
.../Attributes/TestMethod/TaskRunTestMethodAttribute.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
index 5089f07564..bd76be2a2d 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
@@ -26,7 +26,6 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting;
/// which can still lead to issues, but the test runner will not block waiting for it to complete.
///
///
-[AttributeUsage(AttributeTargets.Method)]
public class TaskRunTestMethodAttribute : TestMethodAttribute
{
private readonly TestMethodAttribute? _testMethodAttribute;
From cb78ce5f0aa6f75b71c3ced143b6a7554ca8a346 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Amaury=20Lev=C3=A9?=
Date: Mon, 27 Oct 2025 08:23:37 +0100
Subject: [PATCH 09/10] Update
src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
Co-authored-by: Youssef Victor
---
.../Attributes/TestMethod/TaskRunTestMethodAttribute.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
index bd76be2a2d..90753e292b 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
@@ -26,7 +26,7 @@ namespace Microsoft.VisualStudio.TestTools.UnitTesting;
/// which can still lead to issues, but the test runner will not block waiting for it to complete.
///
///
-public class TaskRunTestMethodAttribute : TestMethodAttribute
+public sealed class TaskRunTestMethodAttribute : TestMethodAttribute
{
private readonly TestMethodAttribute? _testMethodAttribute;
From ac903bb7389abb5f2a5c946a0de0b5fac535ebf9 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Mon, 27 Oct 2025 07:49:26 +0000
Subject: [PATCH 10/10] Add timeout parameter to TaskRunTestMethodAttribute
- Added timeout parameter to TaskRunTestMethodAttribute constructors
- Implemented timeout handling with Task.WhenAny for non-cooperative timeout
- Added STA thread handling to respect thread apartment state
- Updated code fix to extract timeout from Timeout attribute and pass to TaskRunTestMethod
- Updated tests to use TaskRunTestMethod(5000) instead of separate Timeout attribute
- Updated PublicAPI.Unshipped.txt with new signatures
Addresses comments from @Youssef1313 and @Evangelink about needing timeout parameter and STA thread handling.
Co-authored-by: Evangelink <11340282+Evangelink@users.noreply.github.com>
---
...eCooperativeCancellationForTimeoutFixer.cs | 50 +++++--
.../TestMethod/TaskRunTestMethodAttribute.cs | 133 ++++++++++++++----
.../PublicAPI/PublicAPI.Unshipped.txt | 5 +-
...tiveCancellationForTimeoutAnalyzerTests.cs | 10 +-
4 files changed, 153 insertions(+), 45 deletions(-)
diff --git a/src/Analyzers/MSTest.Analyzers.CodeFixes/UseCooperativeCancellationForTimeoutFixer.cs b/src/Analyzers/MSTest.Analyzers.CodeFixes/UseCooperativeCancellationForTimeoutFixer.cs
index 26e4a525ca..ee55e7247c 100644
--- a/src/Analyzers/MSTest.Analyzers.CodeFixes/UseCooperativeCancellationForTimeoutFixer.cs
+++ b/src/Analyzers/MSTest.Analyzers.CodeFixes/UseCooperativeCancellationForTimeoutFixer.cs
@@ -134,40 +134,68 @@ private static async Task AddCooperativeCancellationAsync(Document doc
private static async Task ReplaceWithTaskRunTestMethodAsync(Document document, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken)
{
DocumentEditor editor = await DocumentEditor.CreateAsync(document, cancellationToken).ConfigureAwait(false);
+ SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
- // Find the TestMethod attribute
+ if (root is null)
+ {
+ return document;
+ }
+
+ // Find the TestMethod and Timeout attributes
AttributeSyntax? testMethodAttribute = null;
+ AttributeSyntax? timeoutAttribute = null;
+ int timeoutValue = 0;
+
foreach (AttributeListSyntax attributeList in methodDeclaration.AttributeLists)
{
foreach (AttributeSyntax attribute in attributeList.Attributes)
{
string attributeName = attribute.Name.ToString();
+
if (attributeName is "TestMethod" or "TestMethodAttribute")
{
testMethodAttribute = attribute;
- break;
}
- }
-
- if (testMethodAttribute is not null)
- {
- break;
+ else if (attributeName is "Timeout" or "TimeoutAttribute")
+ {
+ timeoutAttribute = attribute;
+
+ // Extract timeout value from the first argument
+ if (attribute.ArgumentList?.Arguments.Count > 0)
+ {
+ var firstArg = attribute.ArgumentList.Arguments[0];
+ if (firstArg.Expression is LiteralExpressionSyntax literalExpr &&
+ literalExpr.Token.Value is int value)
+ {
+ timeoutValue = value;
+ }
+ }
+ }
}
}
- if (testMethodAttribute is null)
+ if (testMethodAttribute is null || timeoutAttribute is null)
{
- // No TestMethod attribute found, return unchanged document
+ // Can't apply the fix without both attributes
return document;
}
- // Create the new TaskRunTestMethod attribute preserving any arguments
+ // Create the new TaskRunTestMethod attribute with timeout parameter
+ AttributeArgumentSyntax timeoutArg = SyntaxFactory.AttributeArgument(
+ SyntaxFactory.LiteralExpression(
+ SyntaxKind.NumericLiteralExpression,
+ SyntaxFactory.Literal(timeoutValue)));
+
AttributeSyntax newAttribute = SyntaxFactory.Attribute(
SyntaxFactory.IdentifierName("TaskRunTestMethod"),
- testMethodAttribute.ArgumentList);
+ SyntaxFactory.AttributeArgumentList(
+ SyntaxFactory.SingletonSeparatedList(timeoutArg)));
// Replace the TestMethod attribute with TaskRunTestMethod
editor.ReplaceNode(testMethodAttribute, newAttribute);
+
+ // Remove the Timeout attribute
+ editor.RemoveNode(timeoutAttribute);
return editor.GetChangedDocument();
}
diff --git a/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
index 90753e292b..8eca350387 100644
--- a/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
+++ b/src/TestFramework/TestFramework/Attributes/TestMethod/TaskRunTestMethodAttribute.cs
@@ -4,28 +4,20 @@
namespace Microsoft.VisualStudio.TestTools.UnitTesting;
///
-/// The TaskRun test method attribute.
+/// Test method attribute that runs tests in a Task.Run with non-cooperative timeout handling.
///
///
///
-/// This attribute is designed to handle test method execution with timeout by running the test code within a .
-/// This allows the test runner to stop watching the task in case of timeout, preventing dangling tasks that can lead to
-/// confusion or errors because the test method is still running in the background.
+/// This attribute runs test methods in and implements non-cooperative timeout handling.
+/// When a timeout occurs, the test is marked as timed out and the test runner stops awaiting the task,
+/// allowing it to complete in the background. This prevents blocking but may lead to dangling tasks.
///
///
-/// When a timeout occurs:
-///
-/// The test is marked as timed out.
-/// The cancellation token from is canceled.
-/// The test runner stops awaiting the test task, allowing it to complete in the background.
-///
-///
-///
-/// For best results, test methods should observe the cancellation token and cancel cooperatively.
-/// If the test method does not handle cancellation properly, the task may continue running after the timeout,
-/// which can still lead to issues, but the test runner will not block waiting for it to complete.
+/// For cooperative timeout handling where tests are awaited until completion, use
+/// with CooperativeCancellation = true instead.
///
///
+[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public sealed class TaskRunTestMethodAttribute : TestMethodAttribute
{
private readonly TestMethodAttribute? _testMethodAttribute;
@@ -33,9 +25,11 @@ public sealed class TaskRunTestMethodAttribute : TestMethodAttribute
///
/// Initializes a new instance of the class.
///
- public TaskRunTestMethodAttribute([CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = -1)
+ /// The timeout in milliseconds. If not specified or 0, no timeout is applied.
+ public TaskRunTestMethodAttribute(int timeout = 0, [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int callerLineNumber = -1)
: base(callerFilePath, callerLineNumber)
{
+ Timeout = timeout;
}
///
@@ -43,12 +37,21 @@ public TaskRunTestMethodAttribute([CallerFilePath] string callerFilePath = "", [
/// This constructor is intended to be called by test class attributes to wrap an existing test method attribute.
///
/// The wrapped test method.
- public TaskRunTestMethodAttribute(TestMethodAttribute testMethodAttribute)
+ /// The timeout in milliseconds. If not specified or 0, no timeout is applied.
+ public TaskRunTestMethodAttribute(TestMethodAttribute testMethodAttribute, int timeout = 0)
: base(testMethodAttribute.DeclaringFilePath, testMethodAttribute.DeclaringLineNumber ?? -1)
- => _testMethodAttribute = testMethodAttribute;
+ {
+ _testMethodAttribute = testMethodAttribute;
+ Timeout = timeout;
+ }
///
- /// Executes a test method by wrapping it in a to allow timeout handling.
+ /// Gets the timeout in milliseconds.
+ ///
+ public int Timeout { get; }
+
+ ///
+ /// Executes a test method with non-cooperative timeout handling.
///
/// The test method to execute.
/// An array of TestResult objects that represent the outcome(s) of the test.
@@ -56,22 +59,96 @@ public override async Task ExecuteAsync(ITestMethod testMethod)
{
if (_testMethodAttribute is not null)
{
- return await ExecuteWithTaskRunAsync(() => _testMethodAttribute.ExecuteAsync(testMethod)).ConfigureAwait(false);
+ return await ExecuteWithTimeoutAsync(() => _testMethodAttribute.ExecuteAsync(testMethod), testMethod).ConfigureAwait(false);
}
- return await ExecuteWithTaskRunAsync(async () =>
+ return await ExecuteWithTimeoutAsync(async () =>
{
TestResult result = await testMethod.InvokeAsync(null).ConfigureAwait(false);
return new[] { result };
- }).ConfigureAwait(false);
+ }, testMethod).ConfigureAwait(false);
}
- private static async Task ExecuteWithTaskRunAsync(Func> executeFunc)
+ private async Task ExecuteWithTimeoutAsync(Func> executeFunc, ITestMethod testMethod)
{
- // Run the test method in Task.Run so that we can stop awaiting it on timeout
- // while allowing it to complete in the background
- Task testTask = Task.Run(executeFunc);
- TestResult[] results = await testTask.ConfigureAwait(false);
- return results;
+ if (Timeout <= 0)
+ {
+ // No timeout, run directly with Task.Run
+ return await RunOnThreadPoolOrCustomThreadAsync(executeFunc).ConfigureAwait(false);
+ }
+
+ // Run with timeout
+ Task testTask = RunOnThreadPoolOrCustomThreadAsync(executeFunc);
+ Task completedTask = await Task.WhenAny(testTask, Task.Delay(Timeout)).ConfigureAwait(false);
+
+ if (completedTask == testTask)
+ {
+ // Test completed before timeout
+ return await testTask.ConfigureAwait(false);
+ }
+
+ // Timeout occurred - return timeout result and let task continue in background
+ return
+ [
+ new TestResult
+ {
+ Outcome = UnitTestOutcome.Timeout,
+ TestFailureException = new TestFailedException(
+ UnitTestOutcome.Timeout,
+ string.Format(
+ CultureInfo.InvariantCulture,
+ "Test '{0}.{1}' exceeded timeout of {2}ms.",
+ testMethod.TestClassName,
+ testMethod.TestMethodName,
+ Timeout)),
+ },
+ ];
+ }
+
+ private static Task RunOnThreadPoolOrCustomThreadAsync(Func> executeFunc)
+ {
+ // Check if we need to handle STA threading
+ // If current thread is STA and we're on Windows, create a new STA thread
+ // Otherwise, use Task.Run (thread pool)
+#if NETFRAMEWORK
+ if (Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
+ {
+ return RunOnSTAThreadAsync(executeFunc);
+ }
+#else
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) &&
+ Thread.CurrentThread.GetApartmentState() == ApartmentState.STA)
+ {
+ return RunOnSTAThreadAsync(executeFunc);
+ }
+#endif
+
+ // Use thread pool for non-STA scenarios
+ return Task.Run(executeFunc);
+ }
+
+ private static Task RunOnSTAThreadAsync(Func> executeFunc)
+ {
+ var tcs = new TaskCompletionSource();
+ var thread = new Thread(() =>
+ {
+ try
+ {
+ TestResult[] result = executeFunc().GetAwaiter().GetResult();
+ tcs.SetResult(result);
+ }
+ catch (Exception ex)
+ {
+ tcs.SetException(ex);
+ }
+ })
+ {
+ Name = "TaskRunTestMethodAttribute STA thread",
+ };
+
+ thread.SetApartmentState(ApartmentState.STA);
+ thread.Start();
+
+ return tcs.Task;
}
}
diff --git a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt
index 1050aa7571..a312657052 100644
--- a/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt
+++ b/src/TestFramework/TestFramework/PublicAPI/PublicAPI.Unshipped.txt
@@ -1,5 +1,6 @@
#nullable enable
Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute
Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute.ExecuteAsync(Microsoft.VisualStudio.TestTools.UnitTesting.ITestMethod testMethod) -> System.Threading.Tasks.Task!
-Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute.TaskRunTestMethodAttribute(Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute! testMethodAttribute) -> void
-Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute.TaskRunTestMethodAttribute(string! callerFilePath = "", int callerLineNumber = -1) -> void
+Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute.TaskRunTestMethodAttribute(int timeout = 0, string! callerFilePath = "", int callerLineNumber = -1) -> void
+Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute.TaskRunTestMethodAttribute(Microsoft.VisualStudio.TestTools.UnitTesting.TestMethodAttribute! testMethodAttribute, int timeout = 0) -> void
+Microsoft.VisualStudio.TestTools.UnitTesting.TaskRunTestMethodAttribute.Timeout.get -> int
diff --git a/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs b/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs
index 606230283d..38f9f7e9ab 100644
--- a/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs
+++ b/test/UnitTests/MSTest.Analyzers.UnitTests/UseCooperativeCancellationForTimeoutAnalyzerTests.cs
@@ -464,8 +464,7 @@ public void MyTestMethod()
[TestClass]
public class MyTestClass
{
- [TaskRunTestMethod]
- [Timeout(5000)]
+ [TaskRunTestMethod(5000)]
public void MyTestMethod()
{
}
@@ -488,8 +487,7 @@ public async Task WhenTaskRunTestMethodAttributeWithTimeout_NoDiagnostic()
[TestClass]
public class MyTestClass
{
- [TaskRunTestMethod]
- [Timeout(5000)]
+ [TaskRunTestMethod(5000)]
public void MyTestMethod()
{
}
@@ -498,4 +496,8 @@ public void MyTestMethod()
await VerifyCS.VerifyCodeFixAsync(code, code);
}
+ """;
+
+ await VerifyCS.VerifyCodeFixAsync(code, code);
+ }
}