Agent skill

exp-dotnet-test-frameworks

Reference data for .NET test framework detection patterns, assertion APIs, skip annotations, setup/teardown methods, and common test smell indicators across MSTest, xUnit, NUnit, and TUnit. DO NOT USE directly — loaded by test analysis skills (exp-test-smell-detection, exp-assertion-quality, exp-test-maintainability, exp-test-tagging) when they need framework-specific lookup tables.

Stars 302
Forks 22

Install this agent skill to your Project

npx add-skill https://github.com/managedcode/dotnet-skills/tree/main/catalog/Platform/Official-DotNet-Experimental/skills/exp-dotnet-test-frameworks

SKILL.md

.NET Test Framework Reference

Language-specific detection patterns for .NET test frameworks (MSTest, xUnit, NUnit, TUnit).

Test File Identification

Framework Test class markers Test method markers
MSTest [TestClass] [TestMethod], [DataTestMethod]
xUnit (none — convention-based) [Fact], [Theory]
NUnit [TestFixture] [Test], [TestCase], [TestCaseSource]
TUnit [ClassDataSource] [Test]

Assertion APIs by Framework

Category MSTest xUnit NUnit
Equality Assert.AreEqual Assert.Equal Assert.That(x, Is.EqualTo(y))
Boolean Assert.IsTrue / Assert.IsFalse Assert.True / Assert.False Assert.That(x, Is.True)
Null Assert.IsNull / Assert.IsNotNull Assert.Null / Assert.NotNull Assert.That(x, Is.Null)
Exception Assert.Throws<T>() / Assert.ThrowsExactly<T>() Assert.Throws<T>() Assert.That(() => ..., Throws.TypeOf<T>())
Collection CollectionAssert.Contains Assert.Contains Assert.That(col, Has.Member(x))
String StringAssert.Contains Assert.Contains(str, sub) Assert.That(str, Does.Contain(sub))
Type Assert.IsInstanceOfType Assert.IsAssignableFrom Assert.That(x, Is.InstanceOf<T>())
Inconclusive Assert.Inconclusive() skip via [Fact(Skip)] Assert.Inconclusive()
Fail Assert.Fail() Assert.Fail() (.NET 10+) Assert.Fail()

Third-party assertion libraries: Should* (Shouldly), .Should() (FluentAssertions / AwesomeAssertions), Verify() (Verify).

Sleep/Delay Patterns

Pattern Example
Thread sleep Thread.Sleep(2000)
Task delay await Task.Delay(1000)
SpinWait SpinWait.SpinUntil(() => condition, timeout)

Skip/Ignore Annotations

Framework Annotation With reason
MSTest [Ignore] [Ignore("reason")]
xUnit [Fact(Skip = "reason")] (reason is required)
NUnit [Ignore("reason")] (reason is required)
TUnit [Skip("reason")] (reason is required)
Conditional #if false / #if NEVER (no reason possible)

Exception Handling — Idiomatic Alternatives

When a test uses try/catch to verify exceptions, suggest the framework-native alternative:

MSTest:

csharp
// Instead of try/catch (matches exact type):
var ex = Assert.ThrowsExactly<InvalidOperationException>(
    () => processor.ProcessOrder(emptyOrder));
Assert.AreEqual("Order must contain at least one item", ex.Message);

// Or (also matches derived types):
var ex = Assert.Throws<InvalidOperationException>(
    () => processor.ProcessOrder(emptyOrder));
Assert.AreEqual("Order must contain at least one item", ex.Message);

xUnit:

csharp
var ex = Assert.Throws<InvalidOperationException>(
    () => processor.ProcessOrder(emptyOrder));
Assert.Equal("Order must contain at least one item", ex.Message);

NUnit:

csharp
var ex = Assert.Throws<InvalidOperationException>(
    () => processor.ProcessOrder(emptyOrder));
Assert.That(ex.Message, Is.EqualTo("Order must contain at least one item"));

Mystery Guest — Common .NET Patterns

Smell indicator What to look for
File system File.ReadAllText, File.Exists, File.WriteAllBytes, Directory.GetFiles, Path.Combine with hard-coded paths
Database SqlConnection, DbContext (without in-memory provider), SqlCommand
Network HttpClient without HttpMessageHandler override, WebRequest, TcpClient
Environment Environment.GetEnvironmentVariable, Environment.CurrentDirectory
Acceptable MemoryStream, StringReader, InMemory database providers, custom DelegatingHandler

Integration Test Markers

Recognize these as integration tests (adjust smell severity accordingly):

  • Class name contains Integration, E2E, EndToEnd, or Acceptance
  • [TestCategory("Integration")] (MSTest)
  • [Trait("Category", "Integration")] (xUnit)
  • [Category("Integration")] (NUnit)
  • Project name ending in .IntegrationTests or .E2ETests

Setup/Teardown Methods

Framework Setup Teardown
MSTest [TestInitialize] or constructor [TestCleanup] or IDisposable.Dispose / IAsyncDisposable.DisposeAsync
xUnit constructor IDisposable.Dispose / IAsyncDisposable.DisposeAsync
NUnit [SetUp] [TearDown]
MSTest (class) [ClassInitialize] [ClassCleanup]
NUnit (class) [OneTimeSetUp] [OneTimeTearDown]
xUnit (class) IClassFixture<T> fixture's Dispose

Expand your agent's capabilities with these related and highly-rated skills.

managedcode/dotnet-skills

dotnet-project-setup

Create or reorganize .NET solutions with clean project boundaries, repeatable SDK settings, and a maintainable baseline for libraries, apps, tests, CI, and local development.

302 22
Explore
managedcode/dotnet-skills

csharp-scripts

Run single-file C# programs as scripts (file-based apps) for quick experimentation, prototyping, and concept testing. Use when the user wants to write and execute a small C# program without creating a full project.

302 22
Explore
managedcode/dotnet-skills

dotnet-pinvoke

Correctly call native (C/C++) libraries from .NET using P/Invoke and LibraryImport. Covers function signatures, string marshalling, memory lifetime, SafeHandle, and cross-platform patterns. USE FOR: writing new P/Invoke or LibraryImport declarations, reviewing or debugging existing native interop code, wrapping a C or C++ library for use in .NET, diagnosing crashes, memory leaks, or corruption at the managed/native boundary. DO NOT USE FOR: COM interop, C++/CLI mixed-mode assemblies, or pure managed code with no native dependencies.

302 22
Explore
managedcode/dotnet-skills

nuget-trusted-publishing

Set up NuGet trusted publishing (OIDC) on a GitHub Actions repo — replaces long-lived API keys with short-lived tokens. USE FOR: trusted publishing, NuGet OIDC, keyless NuGet publish, migrate from NuGet API key, NuGet/login, secure NuGet publishing. DO NOT USE FOR: publishing to private feeds or Azure Artifacts (OIDC is nuget.org only). INVOKES: shell (powershell or bash), edit, create, ask_user for guided repo setup.

302 22
Explore
managedcode/dotnet-skills

dotnet-legacy-aspnet

Maintain classic ASP.NET applications on .NET Framework, including Web Forms, older MVC, and legacy hosting patterns, while planning realistic modernization boundaries.

302 22
Explore
managedcode/dotnet-skills

dotnet-code-review

Review .NET changes for bugs, regressions, architectural drift, missing tests, incorrect async or disposal behavior, and platform-specific pitfalls before you approve or merge them.

302 22
Explore

Didn't find tool you were looking for?

Be as detailed as possible for better results