Skills 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.
install
source · Clone the upstream repo
git clone https://github.com/dotnet/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/dotnet/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/dotnet-experimental/skills/exp-dotnet-test-frameworks" ~/.claude/skills/dotnet-skills-exp-dotnet-test-frameworks && rm -rf "$T"
manifest:
plugins/dotnet-experimental/skills/exp-dotnet-test-frameworks/SKILL.mdsource content
.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 | | , |
| xUnit | (none — convention-based) | , |
| NUnit | | , , |
| TUnit | | |
Assertion APIs by Framework
| Category | MSTest | xUnit | NUnit |
|---|---|---|---|
| Equality | | | |
| Boolean | / | / | |
| Null | / | / | |
| Exception | / | | |
| Collection | | | |
| String | | | |
| Type | | | |
| Inconclusive | | skip via | |
| Fail | | (.NET 10+) | |
Third-party assertion libraries:
Should* (Shouldly), .Should() (FluentAssertions / AwesomeAssertions), Verify() (Verify).
Sleep/Delay Patterns
| Pattern | Example |
|---|---|
| Thread sleep | |
| Task delay | |
| SpinWait | |
Skip/Ignore Annotations
| Framework | Annotation | With reason |
|---|---|---|
| MSTest | | |
| xUnit | | (reason is required) |
| NUnit | | (reason is required) |
| TUnit | | (reason is required) |
| Conditional | / | (no reason possible) |
Exception Handling — Idiomatic Alternatives
When a test uses
try/catch to verify exceptions, suggest the framework-native alternative:
MSTest:
// 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:
var ex = Assert.Throws<InvalidOperationException>( () => processor.ProcessOrder(emptyOrder)); Assert.Equal("Order must contain at least one item", ex.Message);
NUnit:
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 | , , , , with hard-coded paths |
| Database | , (without in-memory provider), |
| Network | without override, , |
| Environment | , |
| Acceptable | , , database providers, custom |
Integration Test Markers
Recognize these as integration tests (adjust smell severity accordingly):
- Class name contains
,Integration
,E2E
, orEndToEndAcceptance
(MSTest)[TestCategory("Integration")]
(xUnit)[Trait("Category", "Integration")]
(NUnit)[Category("Integration")]- Project name ending in
or.IntegrationTests.E2ETests
Setup/Teardown Methods
| Framework | Setup | Teardown |
|---|---|---|
| MSTest | or constructor | or / |
| xUnit | constructor | / |
| NUnit | | |
| MSTest (class) | | |
| NUnit (class) | | |
| xUnit (class) | | fixture's |