关于 nunit-skill
nunit-skill 是面向 C# 开发者的 NUnit 3 测试参考技能,涵盖测试结构、断言和生命周期,并指向进阶实践指南。
主要功能
- 01NUnit 3 测试夹具与生命周期模式
- 02约束模型断言
- 03参数化测试
- 04Moq 模拟示例
- 05分类、忽略和超时属性
- 06安装与运行测试命令
适用场景
- 01使用 NUnit 约束模型编写断言
- 02组织参数化测试
- 03管理单项测试和夹具的初始化
- 04按类别筛选测试运行
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ lambdatest/ agent-skills --skill nunit-skill安装后在 Claude Code 中输入/nunit-skill确认已加载。
附带文件reference/advanced-patterns.mdreference/playbook.md
详细介绍
NUnit 3 测试技能
核心模式
基本测试
using NUnit.Framework;
[TestFixture]
public class CalculatorTests
{
private Calculator _calculator;
[SetUp]
public void SetUp() => _calculator = new Calculator();
[Test]
public void Add_TwoPositiveNumbers_ReturnsSum()
{
Assert.That(_calculator.Add(2, 3), Is.EqualTo(5));
}
[Test]
public void Divide_ByZero_ThrowsException()
{
Assert.Throws<DivideByZeroException>(() => _calculator.Divide(10, 0));
}
[TearDown]
public void TearDown() { /* cleanup */ }
}
约束模型(Assert.That)
Assert.That(actual, Is.EqualTo(expected));
Assert.That(actual, Is.Not.EqualTo(unexpected));
Assert.That(value, Is.GreaterThan(5));
Assert.That(value, Is.InRange(1, 10));
Assert.That(str, Does.Contain("hello"));
Assert.That(str, Does.StartWith("He").IgnoreCase);
Assert.That(collection, Has.Count.EqualTo(3));
Assert.That(collection, Has.Member("item"));
Assert.That(collection, Is.All.GreaterThan(0));
Assert.That(obj, Is.Null);
Assert.That(obj, Is.Not.Null);
Assert.That(obj, Is.InstanceOf<MyClass>());
Assert.That(actual, Is.EqualTo(3.14).Within(0.01));
Assert.That(() => Method(), Throws.TypeOf<ArgumentException>()
.With.Message.Contains("invalid"));
参数化测试
[TestCase(2, 3, 5)]
[TestCase(-1, 1, 0)]
[TestCase(0, 0, 0)]
public void Add_ReturnsCorrectSum(int a, int b, int expected)
{
Assert.That(_calculator.Add(a, b), Is.EqualTo(expected));
}
[TestCaseSource(nameof(DivisionCases))]
public void Divide_ReturnsCorrectQuotient(int a, int b, double expected)
{
Assert.That(_calculator.Divide(a, b), Is.EqualTo(expected).Within(0.01));
}
private static IEnumerable<TestCaseData> DivisionCases()
{
yield return new TestCaseData(10, 2, 5.0).SetName("10/2=5");
yield return new TestCaseData(7, 3, 2.33).SetName("7/3=2.33");
}
使用 Moq 进行模拟
using Moq;
[TestFixture]
public class UserServiceTests
{
private Mock<IUserRepository> _mockRepo;
private Mock<IEmailService> _mockEmail;
private UserService _service;
[SetUp]
public void SetUp()
{
_mockRepo = new Mock<IUserRepository>();
_mockEmail = new Mock<IEmailService>();
_service = new UserService(_mockRepo.Object, _mockEmail.Object);
}
[Test]
public void CreateUser_SavesAndSendsEmail()
{
_mockRepo.Setup(r => r.Save(It.IsAny<User>())).Returns(new User { Id = 1 });
var result = _service.CreateUser("[email protected]", "Alice");
Assert.That(result.Id, Is.EqualTo(1));
_mockRepo.Verify(r => r.Save(It.IsAny<User>()), Times.Once);
_mockEmail.Verify(e => e.SendWelcome("[email protected]"), Times.Once);
}
}
生命周期
[OneTimeSetUp] → Before all tests in fixture
[SetUp] → Before each test
[Test] → Test method
[TearDown] → After each test
[OneTimeTearDown] → After all tests in fixture
类别和特性
[Test, Category("Smoke")]
public void QuickTest() { }
[Test, Ignore("Bug #123")]
public void SkippedTest() { }
[Test, Timeout(5000)]
public void TimeLimitedTest() { }
[Test, Retry(3)]
public void FlakyTest() { }
反模式
| 错误做法 | 正确做法 | 原因 |
|---|---|---|
Assert.AreEqual(a, b)(经典模式) | Assert.That(a, Is.EqualTo(b)) | 约束模型更丰富 |
没有 [SetUp] | 正确管理生命周期 | 资源管理 |
| 测试私有方法 | 测试公共 API | 封装 |
| 没有类别 | [Category("Smoke")] | 按子集运行 |
设置:dotnet add package NUnit NUnit3TestAdapter Microsoft.NET.Test.Sdk
运行:dotnet test 或 dotnet test --filter TestCategory=Smoke
深入模式
有关高级模式、调试指南、CI/CD 集成和最佳实践,
请参阅 reference/playbook.md。
评论
支持 Markdown