该页面可以包含自动翻译的文本。
C# 单元测试。为何要费心?
在 Docotic.Pdf 的开发过程中,我们使用了大量单元测试。目前,我们有 14,631 个单元测试。这些测试帮助我们确信,即使在修改软件时,我们的软件也能按预期工作。

有时,我们现有的或潜在的客户会要求我们添加新功能或修复缺陷。如果改动不涉及大量编码,我们可以实现该改动,并在几小时内发布库的更新版本。并且我们非常确信,新版本不会引入回归,因为我们会在发布前运行测试。这使得我们的预发布构建可以安全地用于生产环境。
我们的 C# 单元测试帮了我们很大忙。我们认为,单元测试是软件开发中的关键实践。这就是为什么我想进一步讨论单元测试的重要性及其收益。
C# 单元测试能带来什么好处
单元测试执行速度很快,只需按一下按钮即可运行。它们不需要对整个系统有深入了解,因此在验证改动时非常高效。如果没有单元测试,你就需要通过手动步骤来验证预期行为,这既耗时又容易出错。
代码变更可能引入意外问题,这类问题称为回归缺陷。使用单元测试时,你可以在每次构建或代码变更后重新运行整个测试套件。这有助于及早发现缺陷,从而降低后续修复成本。编写良好的单元测试在代码变更或重构期间充当安全网。
耦合紧密的代码很难进行单元测试。因此,编写单元测试会自然地解耦代码,使其更模块化、更易维护。
单元测试可以作为代码文档。它们可以说明方法在特定输入(例如空字符串或 null 值)下的行为,并解释预期输出。
共享测试套件提供了对代码的共同理解。由于期望明确,团队成员之间的协作也会得到改善。
C# 单元测试工具
要开发测试,你需要一个测试框架。用于单元测试的三大 C# 测试框架是 MSTest、NUnit 和 xUnit。选择哪一个取决于你的需求和偏好。
MSTest 是 Microsoft Visual Studio 提供的默认测试框架。你无需安装其他任何东西即可开发和运行测试。MSTest 与 Visual Studio 集成紧密。
xUnit 是一个现代、可扩展的测试框架,以简单和易用著称。有人认为它有助于编写更整洁的测试。xUnit 还提供了最佳的测试隔离性。一些流行的大型项目使用 xUnit 进行自动化测试。ASP.NET Core 就是其中之一。
NUnit 是一个成熟的测试框架,具有丰富的功能集和广泛的插件生态系统。它可能比另外两个框架更慢,而且你需要使用 NUnit 3 Test Adapter 才能在 Visual Studio 中或命令行下运行 NUnit 3 测试。
我们在 Docotic.Pdf 测试中使用 NUnit。主要原因之一是,很多年前我们开始为我们的 C# PDF 库开发测试时,其他替代方案要么更差,要么还不存在。如果今天才开始,我们也许会阅读那篇出色的 NUnit vs. XUnit vs. MSTest 文章,并做出不同的选择。
什么样的 C# 单元测试才算好
测试应当运行迅速。速度很重要,因为在成熟项目中,单元测试数量会达到数千个。尽可能加快每个测试的速度,可以减少运行所有测试所需的总时间。这有助于保持开发效率。
每个单元测试都应聚焦于某一具体功能点。聚焦的测试不仅更短,也更容易理解和维护。开发者能更快把握聚焦测试的目的。为了让它更方便,别忘了为测试提供名称,名称应简短,但能提供关于测试目的的基本信息。测试应包含清晰的断言。
单元测试应当在任何环境下都产生一致的结果。无论何时、何地运行测试,它都应始终给出相同结果。为了避免测试中的非确定性行为,最好不要依赖外部数据或时间。例如,最好不要让测试依赖从某个 URL 下载的数据。
使用 mock 和/或 stub 将被测单元与外部依赖隔离开来。Mocks and stubs 是 C Sharp 单元测试以及其他语言中都在使用的工具。mock 是方法或对象的伪实现,用于在测试中模拟该方法或对象的行为。stub 是方法或对象的占位实现,用作测试中的占位符。
结论
对 C# 代码进行单元测试不仅是最佳实践,更是必要手段。通过投入时间编写稳健的单元测试并创建全面的测试套件,开发者可以防止回归、提升代码质量,并确保长期可维护性。所以,让我们拥抱单元测试,构建更可靠的软件。
如果你对 C Sharp 或 VB.NET 中的单元测试有疑问,欢迎联系我们。有关 C# 回归测试的问题也同样欢迎。
祝测试愉快!🧪🔍