编写测试有两个原因:
- 声明预期行为
- 防止行为回归
承担(1)声明预期行为:
在断言预期的行为时,您要确保代码按预期的方式工作。这实际上是一种自动化的方式,可以执行例行验证,任何开发人员在实施任何类型的代码时都会执行以下操作:
- 我刚刚写的作品行得通吗?
- 这个循环真的结束了吗?
- 它按我认为的顺序循环吗?
- 这对空输入有效吗?
这些都是我们所有人都会想到的问题,通常,我们也会尝试在脑海中执行代码,确保它看起来确实有效。对于这些情况,让计算机以确定的方式回答这些问题通常很有用。因此,我们编写了一个断言确实有效的单元测试。这使我们对代码充满信心,可以帮助我们及早发现缺陷,甚至可以帮助实际实施代码。
在需要的地方进行此操作是个好主意。任何难以理解的代码,或非琐碎的代码。即使是平凡的代码也可以从中受益。这完全取决于您自己的信心。多久做一次和走多远取决于您自己的满意程度。当您可以自信地回答“是”时,请停下来:您确定这样做有效吗?
对于这种测试,您不需要关心可见性,界面或其他任何方面,而只关心拥有有效的代码。因此,是的,如果您认为需要对它们进行测试以回答问题的“是”,则可以测试私有和受保护的方法。
承担(2)防止行为回归:
一旦获得了有效的代码,就需要有一种机制来保护该代码免受将来的损害。如果没有人再次接触您的源和配置,则不需要此操作,但是在大多数情况下,您或其他人将接触您的源和软件的配置。这种内部麻烦很可能破坏您的工作代码。
大多数语言中已经存在机制来防止这种损坏。可见性功能是一种机制。私有方法被隔离并隐藏。封装是另一种机制,您可以对事物进行分隔,因此更改其他分隔不会影响其他分隔。
通用的机制称为:边界编码。通过在代码各部分之间创建边界,可以保护边界内的所有内容免受其外部内容的影响。边界成为相互作用的点,以及事物相互作用的契约。
这意味着对边界的更改(通过破坏其接口或破坏其预期的行为)将损坏并可能破坏依赖于该边界的其他边界。这就是为什么有一个单元测试的好主意,它针对这些边界并断言它们在语义和行为上都没有改变。
这是您的典型单元测试,是大家在提及TDD或BDD时谈论的话题。重点是加强边界并保护它们不受更改。您不想为此测试私有方法,因为私有方法不是边界。受保护的方法是受限制的边界,我会保护它们。它们没有暴露于世界,但是仍然暴露于其他隔间或“单位”。
该怎么做?
正如我们所看到的,有充分的理由对公共方法和受保护方法进行单元测试,以断言我们的接口没有改变。而且有充分的理由测试私有方法,以断言我们的实现工作。那么我们应该对它们全部进行单元测试吗?
是和否
首先:测试所有您认为需要确定性证明的方法,以便能在大多数情况下确保您的代码有效,无论可见性如何。然后,禁用这些测试。他们已经完成了工作。
最后:为您的边界编写测试。对将由系统其他单元使用的每个点进行单元测试。确保此测试声明语义约定,方法名称,参数数量等。还确保测试声明单元的可用行为。您的测试应演示如何使用该设备以及该设备可以做什么。使这些测试保持启用状态,以便它们在每次代码推送时都运行。
注意:禁用第一组测试的原因是为了允许进行重构工作。主动测试是代码耦合。它可以防止将来修改正在测试的代码。您只需要为您的界面和交互合同使用。