ワンクリックで
csharp-unit-tests
Best practices for C# unit and integration testing with NUnit and Shouldly. Use this when writing or reviewing C# tests.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Best practices for C# unit and integration testing with NUnit and Shouldly. Use this when writing or reviewing C# tests.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | csharp-unit-tests |
| description | Best practices for C# unit and integration testing with NUnit and Shouldly. Use this when writing or reviewing C# tests. |
[Test] / [TestCase] / [TestCaseSource])Assert.*[Category("unit")] or [Category("smoke")] — required on every test class to be included in CIFixture suffix: Section.cs → SectionFixture.csFixture suffix do not need [TestFixture] — NUnit discovers them automatically via their [Test] methodsinternal sealedTest method names use descriptive PascalCase — no underscores, no prefixes like Constructor_ or ToString_:
// ✅ correct
WhenEndExceedsMaxLengthThrows
ToStringReturnsEndValue
MissingSectionsLineThrows
WithValidRangeCreatesSection
// ❌ avoid
Constructor_WhenEndExceedsMaxLength_ThrowsArgumentOutOfRangeException
Parse_MissingSectionsLine_ThrowsFormatException
Separate Arrange / Act / Assert with a blank line only — never write // Arrange, // Act, or // Assert comments:
[Test]
public void WhenStartEqualsEndThrows()
{
var act = () => new Section(1000, 1000);
Should.Throw<ArgumentException>(() => act());
}
[Test]
public void ToStringReturnsEndValue()
{
var section = new Section(0, 2500);
var result = section.ToString();
result.ShouldBe("2500");
}
Always scan for duplication before writing a new [Test] method. If two or more tests share identical body structure and differ only in one or more literal values (strings, numbers, enum values), they MUST be collapsed into a single [TestCase]-parameterized method.
// ❌ avoid — identical structure, only the expected string differs
[Test] public void ActiveStatusHasCorrectName() { ... status.Name.ShouldBe("Active"); }
[Test] public void InactiveStatusHasCorrectName() { ... status.Name.ShouldBe("Inactive"); }
// ✅ correct — collapsed into one parameterized test
[TestCase(UserStatusId.Active, "Active")]
[TestCase(UserStatusId.Inactive, "Inactive")]
public void StatusHasCorrectName(UserStatusId id, string expected)
{
var status = UserStatus.FromValue(id.Value);
status.Name.ShouldBe(expected);
}
Use [TestCase] whenever the same assertion logic applies to multiple input values:
[TestCase("")]
[TestCase(" ")]
[TestCase(null)]
public void CreateUserWithEmptyNameThrows(string? name)
{
var act = () => new UserBuilder().WithFullName(name!).Build();
Should.Throw<ArgumentException>(() => act());
}
Use [TestCaseSource] when test data is more complex or reused across multiple tests:
private static readonly object[][] InvalidEmails =
[
["not-an-email"],
["missing@domain"],
["@nodomain.com"],
];
[TestCaseSource(nameof(InvalidEmails))]
public void CreateUserWithInvalidEmailThrows(string email)
{
var act = () => new UserBuilder().WithEmailAddress(email).Build();
Should.Throw<ArgumentException>(() => act());
}
Always use Should.Throw<T>() with a lambda — never Assert.Throws:
Should.Throw<ArgumentException>(() => new Section(500, 100));
When validating the exception message or properties, assert on the caught exception:
var ex = Should.Throw<ArgumentException>(() => new Section(500, 100));
ex.Message.ShouldContain("start");
This repository tests Angular code generation by comparing rendered output against reference .txt files in Angular/FilesToBeGenerated/. Comparison is whitespace-agnostic — all whitespace is stripped before comparing.
When changing Razor templates, update the corresponding .txt snapshot files. To verify output, run the test and inspect the assertion failure message which shows actual vs. expected content.
[TestFixture] to classes whose names end with Fixture.// Arrange, // Act, // Assert comments.Assert.That — use Shouldly only.[Test] methods for cases that differ only in input values — use [TestCase] or [TestCaseSource] instead. Always check for this before writing any new [Test] method.