---
name: MSTest Testing
description: Microsoft's built-in .NET testing framework covering test classes, data-driven tests, assertions, lifecycle management, mocking with Moq, and integration testing for C# applications.
version: 1.0.0
author: thetestingacademy
license: MIT
tags: [mstest, csharp, dotnet, unit-testing, mocking, moq, data-driven, assertions]
testingTypes: [unit, integration]
frameworks: [mstest]
languages: [csharp]
domains: [web, api, backend]
agents: [claude-code, cursor, github-copilot, windsurf, codex, aider, continue, cline, zed, bolt]
---
# MSTest Testing Skill
You are an expert C# developer specializing in testing with MSTest, Microsoft's built-in testing framework for .NET. When the user asks you to write, review, or debug MSTest tests, follow these detailed instructions to produce reliable, well-structured test suites for .NET applications.
## Core Principles
1. **Test behavior, not implementation** -- Verify what the code does from a caller's perspective, not internal mechanics that change during refactoring.
2. **One logical assertion per test** -- Each `[TestMethod]` should verify a single behavior so failures pinpoint the exact issue.
3. **Arrange-Act-Assert** -- Structure every test into setup, execution, and verification sections separated by comments or blank lines.
4. **Isolate external dependencies** -- Use Moq to mock databases, HTTP clients, and third-party services in unit tests.
5. **Descriptive test names** -- Name tests as `MethodName_Scenario_ExpectedResult` for self-documenting test output.
6. **Use data-driven tests** -- Leverage `[DataRow]` and `[DynamicData]` to test multiple inputs without duplicating test methods.
7. **Clean lifecycle management** -- Use `[TestInitialize]` and `[TestCleanup]` to ensure consistent state before and after each test.
## Project Structure
```
Solution/
src/
MyApp/
Services/
UserService.cs
PaymentService.cs
Models/
User.cs
Order.cs
Repositories/
IUserRepository.cs
UserRepository.cs
Utilities/
Validators.cs
tests/
MyApp.UnitTests/
Services/
UserServiceTests.cs
PaymentServiceTests.cs
Models/
UserTests.cs
OrderTests.cs
Utilities/
ValidatorsTests.cs
Fixtures/
TestDataFactory.cs
MyApp.UnitTests.csproj
MyApp.IntegrationTests/
UserPaymentFlowTests.cs
MyApp.IntegrationTests.csproj
Solution.sln
```
## Dependencies
### .csproj
```xml
net8.0false
```
### Running Tests
```bash
# Run all tests
dotnet test
# Run specific project
dotnet test tests/MyApp.UnitTests
# Run with filter
dotnet test --filter "FullyQualifiedName~UserServiceTests"
# Run specific test
dotnet test --filter "FullyQualifiedName=MyApp.UnitTests.Services.UserServiceTests.CreateUser_WithValidData_ReturnsUser"
# Run with category
dotnet test --filter "TestCategory=Unit"
# Run with coverage
dotnet test --collect:"XPlat Code Coverage"
# Verbose output
dotnet test --verbosity detailed
```
## Basic Test Structure
```csharp
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace MyApp.UnitTests.Services;
[TestClass]
public class UserServiceTests
{
private UserService _userService = null!;
private InMemoryUserRepository _userRepository = null!;
[TestInitialize]
public void SetUp()
{
_userRepository = new InMemoryUserRepository();
_userService = new UserService(_userRepository);
}
[TestCleanup]
public void TearDown()
{
_userRepository = null!;
_userService = null!;
}
[TestMethod]
[TestCategory("Unit")]
public void CreateUser_WithValidData_ReturnsUser()
{
// Arrange
var request = new CreateUserRequest("Alice", "alice@example.com", 30);
// Act
var user = _userService.CreateUser(request);
// Assert
Assert.IsNotNull(user);
Assert.AreEqual("Alice", user.Name);
Assert.AreEqual("alice@example.com", user.Email);
}
[TestMethod]
[TestCategory("Unit")]
[ExpectedException(typeof(ArgumentException))]
public void CreateUser_WithoutEmail_ThrowsArgumentException()
{
var request = new CreateUserRequest("Bob", null!, 25);
_userService.CreateUser(request);
}
[TestMethod]
[TestCategory("Unit")]
public void CreateUser_WithDuplicateEmail_ThrowsException()
{
var request = new CreateUserRequest("Alice", "alice@example.com", 30);
_userService.CreateUser(request);
Assert.ThrowsException(
() => _userService.CreateUser(request));
}
}
```
## Assertion Methods Reference
```csharp
[TestClass]
public class AssertionExamplesTests
{
[TestMethod]
public void EqualityAssertions()
{
Assert.AreEqual(4, 2 + 2);
Assert.AreNotEqual(5, 2 + 2);
Assert.AreEqual(0.3, 0.1 + 0.2, 0.001); // Delta for floating point
}
[TestMethod]
public void BooleanAssertions()
{
Assert.IsTrue(10 > 5);
Assert.IsFalse(5 > 10);
Assert.IsNull(null);
Assert.IsNotNull("value");
}
[TestMethod]
public void TypeAssertions()
{
Assert.IsInstanceOfType(42, typeof(int));
Assert.IsInstanceOfType("hello", typeof(string));
Assert.IsNotInstanceOfType("hello", typeof(int));
}
[TestMethod]
public void StringAssertions()
{
StringAssert.Contains("hello world", "world");
StringAssert.StartsWith("hello world", "hello");
StringAssert.EndsWith("hello world", "world");
StringAssert.Matches("abc123", new System.Text.RegularExpressions.Regex(@"\d+"));
}
[TestMethod]
public void CollectionAssertions()
{
var list = new List { 1, 2, 3 };
CollectionAssert.Contains(list, 2);
CollectionAssert.DoesNotContain(list, 4);
CollectionAssert.AreEqual(new List { 1, 2, 3 }, list);
CollectionAssert.AreEquivalent(new List { 3, 1, 2 }, list);
CollectionAssert.AllItemsAreNotNull(list.Cast