Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions docs/core/testing/mstest-analyzers/mstest0051.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
title: "MSTEST0051: Assert.Throws should contain only a single statement"
description: "Learn about code analysis rule MSTEST0051: Assert.Throws should contain only a single statement"
ms.date: 10/01/2025
f1_keywords:
- MSTEST0051
- AssertThrowsShouldContainSingleStatementAnalyzer
helpviewer_keywords:
- AssertThrowsShouldContainSingleStatementAnalyzer
- MSTEST0051
author: Youssef1313
ms.author: ygerges
ai-usage: ai-generated
---
# MSTEST0051: Assert.Throws should contain only a single statement

| Property | Value |
|-------------------------------------|------------------------------------------------------------------------------------------|
| **Rule ID** | MSTEST0051 |
| **Title** | Assert.Throws should contain only a single statement |
| **Category** | Usage |
| **Fix is breaking or non-breaking** | Non-breaking |
| **Enabled by default** | Yes |
| **Default severity** | Info |
| **Introduced in version** | 3.11.0 |
| **Is there a code fix** | No |

## Cause

A call to <xref:Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Throws%2A>, <xref:Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsAsync%2A>, <xref:Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactly%2A>, or <xref:Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactlyAsync%2A> contains multiple statements in the action delegate.

## Rule description

To ensure that only the specific method call that is expected to throw an exception is tested, the action delegate passed to `Assert.Throws`, `Assert.ThrowsAsync`, `Assert.ThrowsExactly`, or `Assert.ThrowsExactlyAsync` should contain exactly one statement. Including multiple statements can lead to passing tests when the exception is thrown by a statement that is not intended to throw. If it's not the last statement in the action that is intended to throw, then the test has dead code. If it's the last statement, the intent should be clearly stated.

## How to fix violations

Refactor the test to ensure that the action delegate contains only the single statement that is expected to throw the exception. Move any setup code outside the assertion call.

For example, change this:

```csharp
[TestMethod]
public void TestMethod()
{
var obj = new MyClass();
Assert.ThrowsExactly<InvalidOperationException>(() =>
{
obj.Initialize();
obj.Execute(); // Only this should be inside the assertion
});
}
```

To this:

```csharp
[TestMethod]
public void TestMethod()
{
var obj = new MyClass();
obj.Initialize();
Assert.ThrowsExactly<InvalidOperationException>(() => obj.Execute());
}
```

## When to suppress warnings

Don't suppress warnings from this rule. Including multiple statements in the action delegate can make it unclear which operation is being tested and can lead to passing tests when the original intent is violated.
76 changes: 76 additions & 0 deletions docs/core/testing/mstest-analyzers/mstest0052.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
title: "MSTEST0052: Avoid passing an explicit 'DynamicDataSourceType' and use the default auto detect behavior"
description: "Learn about code analysis rule MSTEST0052: Avoid passing an explicit 'DynamicDataSourceType' and use the default auto detect behavior"
ms.date: 10/01/2025
f1_keywords:
- MSTEST0052
- AvoidExplicitDynamicDataSourceTypeAnalyzer
helpviewer_keywords:
- AvoidExplicitDynamicDataSourceTypeAnalyzer
- MSTEST0052
author: Youssef1313
ms.author: ygerges
ai-usage: ai-generated
---
# MSTEST0052: Avoid passing an explicit 'DynamicDataSourceType' and use the default auto detect behavior

| Property | Value |
|-------------------------------------|--------------------------------------------------------------------------------------------|
| **Rule ID** | MSTEST0052 |
| **Title** | Avoid passing an explicit 'DynamicDataSourceType' and use the default auto detect behavior |
| **Category** | Usage |
| **Fix is breaking or non-breaking** | Non-breaking |
| **Enabled by default** | Yes |
| **Default severity** | Warning |
| **Introduced in version** | 3.11.0 |
| **Is there a code fix** | Yes |

## Cause

A <xref:Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute> explicitly specifies <xref:Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Property> or <xref:Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Method> instead of using the default <xref:Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.AutoDetect>.

## Rule description

Starting with MSTest 3.8, `DynamicDataSourceType.AutoDetect` is the default value for the `DynamicDataSourceType` parameter in the `DynamicDataAttribute` constructor. This enhancement automatically detects whether the data source is a property, method, or field, eliminating the need to explicitly specify the source type. Using `AutoDetect` makes the code more maintainable and reduces verbosity.

## How to fix violations

Remove the explicit `DynamicDataSourceType` parameter from the `DynamicData` attribute and let the framework auto-detect the source type.

For example, change this:

```csharp
public static IEnumerable<object[]> TestData { get; } = new[]
{
new object[] { 1, 2, 3 },
new object[] { 4, 5, 9 }
};

[TestMethod]
[DynamicData(nameof(TestData), DynamicDataSourceType.Property)]
public void TestMethod(int a, int b, int expected)
{
Assert.AreEqual(expected, a + b);
}
```

To this:

```csharp
public static IEnumerable<object[]> TestData { get; } = new[]
{
new object[] { 1, 2, 3 },
new object[] { 4, 5, 9 }
};

[TestMethod]
[DynamicData(nameof(TestData))]
public void TestMethod(int a, int b, int expected)
{
Assert.AreEqual(expected, a + b);
}
```

## When to suppress warnings

Don't suppress warnings from this rule. Following the analyzer suggestion leads to less noise in the test code.
66 changes: 66 additions & 0 deletions docs/core/testing/mstest-analyzers/mstest0053.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: "MSTEST0053: Avoid using Assert methods with format parameters"
description: "Learn about code analysis rule MSTEST0053: Avoid using Assert methods with format parameters"
ms.date: 10/01/2025
f1_keywords:
- MSTEST0053
- AvoidAssertFormatParametersAnalyzer
helpviewer_keywords:
- AvoidAssertFormatParametersAnalyzer
- MSTEST0053
author: Youssef1313
ms.author: ygerges
ai-usage: ai-generated
---
# MSTEST0053: Avoid using Assert methods with format parameters

| Property | Value |
|-------------------------------------|------------------------------------------------------------------------------------------|
| **Rule ID** | MSTEST0053 |
| **Title** | Avoid using Assert methods with format parameters |
| **Category** | Usage |
| **Fix is breaking or non-breaking** | Non-breaking |
| **Enabled by default** | Yes |
| **Default severity** | Warning |
| **Introduced in version** | 3.11.0 |
| **Is there a code fix** | Yes |

## Cause

An assertion method call uses the `message` and `parameters` arguments for string formatting instead of using string interpolation.

## Rule description

Using the assertion overloads that accept `message` and `parameters` are no longer recommended. These overloads are removed in MSTest v4. It's advised to use string interpolation instead.

## How to fix violations

Replace calls that use message format parameters with string interpolation.

For example, change this:

```csharp
[TestMethod]
public void TestMethod()
{
int expected = 5;
int actual = GetValue();
Assert.AreEqual(expected, actual, "Expected {0} but got {1}", expected, actual);
}
```

To this:

```csharp
[TestMethod]
public void TestMethod()
{
int expected = 5;
int actual = GetValue();
Assert.AreEqual(expected, actual, $"Expected {expected} but got {actual}");
}
```

## When to suppress warnings

Don't suppress warnings from this rule. These overloads are removed in MSTest v4 and are not recommended.
66 changes: 66 additions & 0 deletions docs/core/testing/mstest-analyzers/mstest0054.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: "MSTEST0054: Use TestContext.CancellationToken instead of TestContext.CancellationTokenSource.Token"
description: "Learn about code analysis rule MSTEST0054: Use TestContext.CancellationToken instead of TestContext.CancellationTokenSource.Token"
ms.date: 10/01/2025
f1_keywords:
- MSTEST0054
- UseCancellationTokenPropertyAnalyzer
helpviewer_keywords:
- UseCancellationTokenPropertyAnalyzer
- MSTEST0054
author: Youssef1313
ms.author: ygerges
ai-usage: ai-generated
---
# MSTEST0054: Use cancellation token from TestContext.CancellationToken

| Property | Value |
|-------------------------------------|------------------------------------------------------------------------------------------|
| **Rule ID** | MSTEST0054 |
| **Title** | Use TestContext.CancellationToken instead of TestContext.CancellationTokenSource.Token |
| **Category** | Usage |
| **Fix is breaking or non-breaking** | Non-breaking |
| **Enabled by default** | Yes |
| **Default severity** | Info |
| **Introduced in version** | 3.11.0 |
| **Is there a code fix** | Yes |

## Cause

Accessing `CancellationToken` via `TestContext.CancellationTokenSource.Token` instead of using the `TestContext.CancellationToken` property.

## Rule description

MSTest provides a cancellation token through the `TestContext.CancellationToken` property. Accessing `TestContext.CancellationTokenSource` is not recommended, and it might be removed in a future release. It's also simpler to use `TestContext.CancellationToken` compared to `TestContext.CancellationTokenSource.Token`.

## How to fix violations

Use the `TestContext.CancellationToken` property instead of `TestContext.CancellationTokenSource.Token`.

For example, change this:

```csharp
public TestContext TestContext { get; set; }

[TestMethod]
public async Task TestMethod()
{
await Task.Delay(1000, TestContext.CancellationTokenSource.Token);
}
```

To this:

```csharp
public TestContext TestContext { get; set; }

[TestMethod]
public async Task TestMethod()
{
await Task.Delay(1000, TestContext.CancellationToken);
}
```

## When to suppress warnings

Don't suppress warnings from this rule. The use of `CancellationTokenSource` property is not recommended and might be removed in a future release.
64 changes: 64 additions & 0 deletions docs/core/testing/mstest-analyzers/mstest0055.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: "MSTEST0055: Do not ignore the return value of string methods"
description: "Learn about code analysis rule MSTEST0055: Do not ignore the return value of string methods"
ms.date: 10/01/2025
f1_keywords:
- MSTEST0055
- IgnoreStringMethodReturnValueAnalyzer
helpviewer_keywords:
- IgnoreStringMethodReturnValueAnalyzer
- MSTEST0055
author: Youssef1313
ms.author: ygerges
ai-usage: ai-generated
---
# MSTEST0055: Do not ignore the return value of string methods

| Property | Value |
|-------------------------------------|------------------------------------------------------------------------------------------|
| **Rule ID** | MSTEST0055 |
| **Title** | Do not ignore the return value of string methods |
| **Category** | Usage |
| **Fix is breaking or non-breaking** | Non-breaking |
| **Enabled by default** | Yes |
| **Default severity** | Warning |
| **Introduced in version** | 3.11.0 |
| **Is there a code fix** | No |

## Cause

A call to `string.Contains`, `string.StartsWith`, or `string.EndsWith` is made and its return value is ignored.

## Rule description

Those methods don't have any side effects and ignoring the return result is always wrong. It's more likely that the original intent of those calls are to assert that they are true.

## How to fix violations

Capture and use the return value from string methods, or use a proper assertion method.

For example, change this:

```csharp
[TestMethod]
public void TestMethod()
{
string value = "Hello world";
value.StartsWith("Hello");
}
```

To this:

```csharp
[TestMethod]
public void TestMethod()
{
string value = "Hello world";
Assert.IsTrue(value.StartsWith("Hello")); // or, Assert.StartsWith("Hello", value);
}
```

## When to suppress warnings

Don't suppress warnings from this rule. Calling string methods without using their return value is always a bug or a dead code.
7 changes: 6 additions & 1 deletion docs/core/testing/mstest-analyzers/usage-rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: MSTest Usage rules (code analysis)
description: Learn about MSTest code analysis usage rules.
author: evangelink
ms.author: amauryleve
ms.date: 01/03/2024
ms.date: 10/01/2025
---

# MSTest usage rules
Expand Down Expand Up @@ -44,3 +44,8 @@ Identifier | Name | Description
[MSTEST0048](mstest0048.md) | TestContextPropertyUsageAnalyzer | A fixture method (methods with <xref:Microsoft.VisualStudio.TestTools.UnitTesting.AssemblyInitializeAttribute>, <xref:Microsoft.VisualStudio.TestTools.UnitTesting.AssemblyCleanupAttribute>, <xref:Microsoft.VisualStudio.TestTools.UnitTesting.ClassInitializeAttribute>, or <xref:Microsoft.VisualStudio.TestTools.UnitTesting.ClassCleanupAttribute>) accesses restricted <xref:Microsoft.VisualStudio.TestTools.UnitTesting.TestContext> properties.
[MSTEST0049](mstest0049.md) | FlowTestContextCancellationTokenAnalyzer | A method call within a test context doesn't use the <xref:System.Threading.CancellationToken> available from <xref:Microsoft.VisualStudio.TestTools.UnitTesting.TestContext> when the called method has a parameter or overload that accepts a <xref:System.Threading.CancellationToken>.
[MSTEST0050](mstest0050.md) | GlobalTestFixtureShouldBeValidAnalyzer | A global test fixture method (marked with `GlobalTestInitializeAttribute` or `GlobalTestCleanupAttribute`) doesn't follow the required layout or has invalid configuration.
[MSTEST0051](mstest0051.md) | AssertThrowsShouldContainSingleStatementAnalyzer | A call to <xref:Microsoft.VisualStudio.TestTools.UnitTesting.Assert.Throws%2A>, <xref:Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsAsync%2A>, <xref:Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactly%2A>, or <xref:Microsoft.VisualStudio.TestTools.UnitTesting.Assert.ThrowsExactlyAsync%2A> contains multiple statements in the action delegate.
[MSTEST0052](mstest0052.md) | AvoidExplicitDynamicDataSourceTypeAnalyzer | A <xref:Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataAttribute> explicitly specifies <xref:Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Property> or <xref:Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.Method> instead of using the default <xref:Microsoft.VisualStudio.TestTools.UnitTesting.DynamicDataSourceType.AutoDetect>.
[MSTEST0053](mstest0053.md) | AvoidAssertFormatParametersAnalyzer | An assertion method call uses the `message` and `parameters` arguments for string formatting instead of using string interpolation.
[MSTEST0054](mstest0054.md) | UseCancellationTokenPropertyAnalyzer | Accessing `CancellationToken` via `TestContext.CancellationTokenSource.Token` instead of using the `TestContext.CancellationToken` property.
[MSTEST0055](mstest0055.md) | IgnoreStringMethodReturnValueAnalyzer | A call to `string.Contains`, `string.StartsWith`, or `string.EndsWith` is made and its return value is ignored.
10 changes: 10 additions & 0 deletions docs/navigate/devops-testing/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,16 @@ items:
href: ../../core/testing/mstest-analyzers/mstest0049.md
- name: MSTEST0050
href: ../../core/testing/mstest-analyzers/mstest0050.md
- name: MSTEST0051
href: ../../core/testing/mstest-analyzers/mstest0051.md
- name: MSTEST0052
href: ../../core/testing/mstest-analyzers/mstest0052.md
- name: MSTEST0053
href: ../../core/testing/mstest-analyzers/mstest0053.md
- name: MSTEST0054
href: ../../core/testing/mstest-analyzers/mstest0054.md
- name: MSTEST0055
href: ../../core/testing/mstest-analyzers/mstest0055.md
- name: Test platforms
items:
- name: Microsoft.Testing.Platform
Expand Down