与测试是什么相对,要测试什么对于所有团队来说都是一个重要的问题。测试是达到目的的一种手段,选择如何优先测试代码库的不同部分可能很困难。
最佳的优先级排序方式是基于你的代码库和团队的目标。但重要的是要记住,虽然编写大量小型测试(例如位于测试金字塔底部的单元测试)并获得大量代码覆盖率只需花费少量时间和带宽,但它们不一定能降低项目的整体风险。

你可以通过考虑你的应用程序、网站或库的主要用例来选择首先测试的内容。这可以通过对站点的关键部分(构成用户体验的核心组件)编写组件测试来实现。例如,允许用户上传和管理时间序列数据的站点的开发人员应该想象并测试用户可能执行这些任务的不同方式。
另一种优先级排序方法涉及获取最多的信息。如果你有一个“危险的”、遗留的或编写糟糕的、承载负载的代码库部分,你的团队中没有人喜欢处理它,那么围绕它构建测试以使其行为更加一致会很有用,然后再进一步忽略它,或者重构它以修复它。将其想象成一个已被谴责但仍容纳你的数据中心的建筑物的脚手架。
维度
我们介绍了测试金字塔或另一种测试形状的概念,但这些概念往往只呈现测试的单个维度:一条从范围小、简单的单元测试到复杂、范围广泛的测试的线——单元测试与集成测试与端到端测试。
但是,一些可能的测试类型长列表并不代表复杂程度,而是代表测试目标或技术。例如,冒烟测试是一种不同的测试类别,它们本身可以是单元测试、端到端测试或其他测试,但旨在让测试人员对被测项目处于有效状态充满信心。视觉测试也可以应用于小型组件或整个站点,这可能很有用。
你的代码库将有独特的要求。例如,在你的代码库中,就单个功能达成一致可能更为重要,编写不同类型的测试以确保其正常工作。需要测试的新功能很少是单个组件、函数或方法,并且其对项目的影响可能分布广泛且规模不同。
你的测试优先级也可能取决于你的业务需求。高度技术性的系统可能需要复杂的单元测试来确认独特的算法是否正确执行,而高度交互式的工具可能更侧重于视觉测试或端到端测试,以确认复杂的触摸输入是否能引起正确的响应。
你的测试方法
尝试专注于测试代码库的用例,无论其规模如何。想象用户可能如何使用你的项目的任何部分——这可能代表单个组件、较低级别的函数或高级别的端到端用例。(如果你发现你的测试无法与被测代码整洁地交互,这也可能揭示你的任何规模的抽象的缺陷。)
重要的是,每个测试用例都有明确定义的目标。大型“包罗万象”的测试可能会变得笨拙,就像在你的非测试代码中一样。
关于测试驱动开发的题外话
测试驱动开发 (TDD) 是一种独特的测试方法——与规模或类型无关——因为它涉及编写旨在失败的测试,至少最初是这样。这可以应用于手动测试和自动化测试:你描述你想要实现的目标,找出当前解决方案或代码中缺少什么,并使用失败的测试作为指导来找到解决方案。
当然,即使在你开始构建假设的应用程序或组件之前,测试每种可能的场景也是没有用的。TDD 有其用武之地,并且当你的代码库变得更加复杂时,它可能会有所帮助。
TDD 也是修复错误时的良好实践。如果你可以编纂错误的重现案例,则可以将其放入最初会失败的自动化测试中。当你修复错误后,测试通过,让你无需手动确认即可确定修复是否成功。

不透明与透明
这是指你测试系统任何部分的方式。如果它是不透明的,你就无法看到内部,例如,当使用类的公共接口而不是检查其内部结构时。
除非你有不这样做的特定理由,否则最好从不透明盒测试开始,这样你就可以根据组件的使用方式来设计测试,而不会被其内部如何运作分心。如果你只依赖代码路径的“公共”接口(不一定是你的用户的公共接口,但可能是代码其他部分的公共接口),你可以自由地重构和改进该代码,因为你知道你的测试会检测到任何更改。
将你的“透明盒”代码转换为更不透明的一种方法是引入可配置的元素,例如代码依赖项的抽象,或用于观察状态的回调,而不是该状态与其他系统紧密耦合。这使你的代码更加解耦,并允许你提供“测试”版本。或者,你可以模拟代码与其他系统交互的位置。