我看到很多问题都在问“如何”用一种特定的语言进行单元测试,但没有人问“什么”、“为什么”和“什么时候”。

是什么? 它对我有什么用? 我为什么要用它? 什么时候用(什么时候不用)? 有哪些常见的陷阱和误解


当前回答

单元测试是在不需要该代码单元所依赖的基础设施的情况下对代码单元(例如单个函数)进行测试。即在隔离环境中进行测试。

例如,如果您正在测试的函数连接到数据库并执行更新,那么在单元测试中您可能不想执行该更新。如果这是一个积分测试,你会这样做,但在这个例子中,它不是。

因此,单元测试将测试您正在测试的“函数”中所包含的功能,而不会产生数据库更新的副作用。

假设函数从数据库中检索了一些数字,然后执行标准偏差计算。你想测试什么?标准偏差计算正确,还是数据从数据库返回?

在单元测试中,您只想测试标准偏差的计算是否正确。在集成测试中,您希望测试标准偏差计算和数据库检索。

其他回答

单元测试是在不需要该代码单元所依赖的基础设施的情况下对代码单元(例如单个函数)进行测试。即在隔离环境中进行测试。

例如,如果您正在测试的函数连接到数据库并执行更新,那么在单元测试中您可能不想执行该更新。如果这是一个积分测试,你会这样做,但在这个例子中,它不是。

因此,单元测试将测试您正在测试的“函数”中所包含的功能,而不会产生数据库更新的副作用。

假设函数从数据库中检索了一些数字,然后执行标准偏差计算。你想测试什么?标准偏差计算正确,还是数据从数据库返回?

在单元测试中,您只想测试标准偏差的计算是否正确。在集成测试中,您希望测试标准偏差计算和数据库检索。

单元测试,粗略地说,就是在与测试代码隔离的情况下测试代码。我想到的直接优势是:

测试的运行变得自动化和可重复 您可以在更细粒度的级别上进行测试,而不是通过GUI进行点击测试

请注意,如果您的测试代码写入文件、打开数据库连接或在网络上执行某些操作,则更适合将其归类为集成测试。集成测试是一件好事,但不应将其与单元测试混淆。单元测试代码应该简短、简单且易于执行。

另一种看待单元测试的方法是先编写测试。这被称为测试驱动开发(简称TDD)。TDD带来了额外的优势:

您不需要编写推测性的“我将来可能需要这个”代码——只要能够通过测试即可 您编写的代码总是会被测试覆盖 通过先编写测试,您不得不考虑如何调用代码,从长远来看,这通常会改善代码的设计。

如果你现在还没有做单元测试,我建议你现在就开始做。找一本好书,实际上任何xUnit-book都可以,因为它们之间的概念可以很好地转换。

有时编写单元测试会很痛苦。当出现这种情况时,试着找个人来帮助你,并抵制住“只写该死的代码”的诱惑。单元测试很像洗碗。这并不总是令人愉快的,但它让你的比喻厨房保持干净,而你真的希望它干净。:)


编辑:我想到了一个误解,虽然我不确定它是否普遍。我曾听一个项目经理说过,单元测试让团队把所有的代码都写了两次。如果它看起来和感觉是那样的,那么,你做错了。编写测试通常不仅可以加快开发速度,而且还为您提供了一个方便的“现在我完成了”指示器,否则您就不会有这个指示器。

首先,无论是谈论单元测试还是其他类型的自动化测试(集成、加载、UI测试等),与您所建议的关键区别在于它是自动化的、可重复的,并且不需要消耗任何人力资源(=没有人需要执行测试,它们通常按下按钮就可以运行)。

我使用单元测试来节省时间。

在构建业务逻辑(或数据访问)时,测试功能通常涉及在许多屏幕上输入内容,这些内容可能尚未完成,也可能尚未完成。自动化这些测试可以节省时间。

对我来说,单元测试是一种模块化的测试工具。每个公共函数通常至少有一个测试。我编写额外的测试来覆盖各种行为。

您在开发代码时想到的所有特殊情况都可以记录在单元测试的代码中。单元测试还成为如何使用代码的示例的来源。

对我来说,在单元测试中发现我的新代码破坏了某些东西比检入代码并让前端开发人员发现问题要快得多。

对于数据访问测试,我尝试编写没有更改或自行清理的测试。

单元测试不能解决所有的测试需求。他们将能够节省开发时间并测试应用程序的核心部分。

使用Testivus。你需要知道的都在那里:)