dotnet-unittest
Provides guidance for generating comprehensive C# unit tests in .NET projects. Use when writing, scaffolding, or improving unit tests for C# code using MSTest, NUnit, or xUnit frameworks. Covers framework detection, test structure, edge-case analysis, mocking rules, and best practices. DO NOT use for integration tests, end-to-end tests, or non-.NET languages.
What this skill does
# .NET Unit Test Generation Guidance for producing high-quality, comprehensive C# unit tests in .NET projects. This skill covers how to detect the test framework in use (MSTest, NUnit, or xUnit) and how to structure well-formed tests that follow best practices, cover edge cases, and avoid common pitfalls. ## When to Use - Writing unit tests for new or existing C# code - Scaffolding a test class for a production class - Improving test coverage with edge-case and error-condition tests - Generating parameterized tests for methods with varied inputs ## When Not to Use - The target file contains only interfaces or delegates (no testable logic) - Writing integration tests or end-to-end tests (different patterns apply) - The project is not a .NET / C# project ## Inputs | Input | Required | Description | |-------|----------|-------------| | Source code to test | Yes | The C# class, method, or file that needs tests | | Existing test project | Recommended | Helps detect the test framework and coding conventions | ## Workflow ### Step 1: Detect the test framework Check the project for existing test framework references: 1. Look for NuGet package references in `.csproj` files 2. Scan existing test files for framework-specific attributes 3. Match against known frameworks: - **MSTest**: `MSTest` or `Microsoft.VisualStudio.TestTools.UnitTesting` package - **NUnit**: `NUnit` package, `NUnit3TestAdapter` - **xUnit**: `xunit` package, `xunit.runner.visualstudio` 4. If no framework is detected, ask the user which framework to use ### Step 2: Load framework-specific guidance Based on the detected framework, load the corresponding reference: - MSTest → [references/mstest.md](references/mstest.md) - NUnit → [references/nunit.md](references/nunit.md) - xUnit → [references/xunit.md](references/xunit.md) ### Step 3: Analyze the source code Before generating tests, analyze the code thoroughly: 1. Read the source code line by line, understanding what each section does 2. Document all parameters, their purposes, constraints, and valid/invalid value ranges 3. Identify potential edge cases and error conditions based on implementation details 4. Describe the expected behavior of each method under different input conditions 5. Simulate an execution flow to understand how different inputs affect the code path 6. Note any dependencies, interfaces, or external systems that will need to be mocked 7. Consider how concurrency, resource management, or other special conditions might affect behavior 8. Identify any domain-specific validation or business rules that need testing ### Step 4: Generate the test class Apply the framework-specific conventions from Step 2 and the common guidelines below. Produce a complete, compilable test file. ### Step 5: Validate - [ ] Test file compiles without errors - [ ] All using directives are present and sorted alphabetically - [ ] Test class and methods follow naming conventions - [ ] Framework-specific attributes are applied correctly - [ ] Arrange-Act-Assert pattern is clearly followed - [ ] Edge cases and error conditions are covered - [ ] No fake/stub/dummy classes were created — only mocking framework is used - [ ] Code respects the project's C# language version and nullable reference type settings ## Key Testing Goals - **Minimal but Comprehensive**: Avoid redundant tests. Prefer parameterized tests over duplicate methods. - **Logical Coverage and Bug Detection**: Focus primarily on meaningful edge cases, domain-specific inputs, boundary values, and scenarios likely to reveal functional bugs or unexpected behavior. - **Clarity and Best Practices**: Clearly use the Arrange-Act-Assert pattern, proper naming conventions (`Method_Condition_ExpectedResult`), and XML comments explaining test purposes. ## When NOT to Generate Tests If the provided file or scope only contains interfaces or delegates, do not generate tests. ## Minimizing Hallucinations and Improving Accuracy - NEVER invent or assume behaviors, methods, constructors, or properties that are not explicitly present in the provided source code. - If you encounter incomplete or unclear source code or design, explicitly generate a partial test method with explanatory comments guiding users on how to proceed. Prefer this approach over generating incorrect or invalid test code. - NEVER add additional types other than test classes — no dummy, fake, or stub classes. Use mocking instead. The only exception is a helper class inside the test class or production type overrides for exposing protected members. Even then, never place those outside the test class. ## Test Class Structure For each public, protected, or internal class in the provided scope: - Create a corresponding test class named `[ClassName]Tests` - Place the test class in namespace `[SourceNamespace].UnitTests` - If the tested source class is partial, the test class must also be partial - Follow the initialization pattern that matches the detected test framework (see framework references) ## Test Method Conventions ### Naming - Use meaningful, descriptive, and standardized naming: `MethodName_Condition_ExpectedOutcome` - Follow the existing test naming conventions found in the project - Each test method must include a clear XML documentation comment explaining: - The test purpose - The specific input conditions being tested - The expected result or exception ### Structure - Clearly follow the Arrange-Act-Assert (AAA) pattern - Keep tests focused on a single behavior - Avoid testing multiple behaviors in one test method - Avoid using multiple assertions in one test method — prefer multiple focused tests - When testing multiple preconditions, write a separate test for each - When testing multiple outcomes for one precondition, use parameterized tests - Tests should be able to run in any order or in parallel ## Input and Edge Case Analysis For **every parameter type**, ensure the following edge cases are tested: ### Numeric Parameters - `int.MinValue`, `int.MaxValue`, `0`, negative and positive boundary values - For floating-point: `double.NaN`, `double.PositiveInfinity`, `double.NegativeInfinity` ### String Parameters - `null` (if nullable), empty strings (`""`), whitespace-only strings - Very long strings, strings with special/control/invalid characters ### Domain-Specific Parameters - Identify and test invalid, boundary, and special-case values based on parameter names and context - Examples: for `"path"` → invalid file paths; for `"age"` → negative, zero, unreasonably large; for `"email"` → invalid formats ### Nullable Parameters - Explicitly test `null` inputs - Strictly follow the source code's nullability annotations ### Collections and Arrays - `null` (if nullable), empty, single-item, duplicates, invalid elements ### Enums - Test all defined values - Test values outside the defined range (using casting) if possible ## Exception and Error Condition Testing For all methods, explicitly test scenarios expected to throw exceptions: - Invalid arguments, `null` values for non-nullable parameters, out-of-range values, invalid state - Ensure the correct exception type is validated - Where possible, validate the exception message - If the method is not expected to throw, verify that no exception is thrown for valid inputs - Use framework-specific async exception assertion methods for async code ## Dependency Handling and Mocking ### Strict Prohibition on Custom Implementations - **STRICT PROHIBITION**: DO NOT create any custom, fake, stub, or dummy classes for dependencies under any circumstances - DO NOT create stub classes (e.g., `StubLogger`, `StubRepository`) - DO NOT create dummy classes (e.g., `DummyService`, `DummyContext`) - DO NOT create fake types (e.g., `FakeDatabase`, `FakeDependency`) - DO NOT create test-specific implementations of interfaces or abstract classes - NEVER create a fake or custom implementation for abstract classes — all major .NET mocking fra
Related in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.