Skip to content

Latest commit

 

History

History
54 lines (45 loc) · 6.06 KB

File metadata and controls

54 lines (45 loc) · 6.06 KB

单元测试

单元测试作用上应该是保证代码逻辑正常,提升代码质量。在对代码进行修改时能够保障修改的安全性。 从原则上来说提交的代码应该是应测尽测,因此这里仅列出可能不需要单元测试的部分。以及不同部分对覆盖率的一个要求

接口测试

项目应当进行接口测试,接口测试属于相对容易实现的集成测试,而且通过接口测试,能够测试程序整体上的调用链路,可以比较简单的覆盖到单元测试不容易做的部分,属于收益比比较高的一个测试。作为后端接口服务应该天然具备接口测试的能力。在设计,实现,改变项目接口的过程中,应当考虑到这一块的内容。 由于接口测试和代码关系密切,开发有能力也有义务保证接口质量,因此也把接口测试部分包含在单元测试的指导文档当中

哪些情况可以不测

  1. cli形式的项目,不需要进行单元测试。 如果cli项目的逻辑十分复杂, 更应该考虑的是这部分逻辑是否应该移动到代码内部处理。
  2. mock/testhelper形式的代码和结构,并非实际使用的代码,仅仅用于在测试中使用的代码可以不要求单元测试。
  3. 工具自动生成的代码不要求单元测试,但是需要确保工具的可靠性。
  4. 胶水形式的代码,仅仅是包装调用的部分代码且不牵涉到额外逻辑时,不要求进行单元测试。
  5. 紧急情况下(例:线上或者社区运行着发生严重故障),可以先进行修复在后续补充测试。
  6. 快速开发阶段的项目可以不要求测试用例。 项目刚刚开始或者在一段时间内要求快速实现某个功能需求。
  7. 代码比较复杂,但是根据以往经验这块比较安全稳固。 那么在这个模块增加功能时,在目前并没有测试方法的情况下可以要求不增加测试。这里的代码如果产生bug 参考 #哪些情况必须要测试 的bug修复部分。
  8. 难以mock且代码编写者对代码比较有把握的情况不需要增加测试
  9. 依赖注入的构造代码不需要增加测试,如果构造代码中存在复杂逻辑,考虑在另外的位置实现。
  10. 网络升级时,从lotus搬运过来的本身就没有单元测试的代码

哪些情况必须要测试

  1. 工具算法形式的代码 这种形式的代码通常依赖少,代码功能比较集中,使用的人比较多,测试用例容易编写并且收益比较大,因而此类功能要求必须进行测试
  2. bug修复(排除一些显示的修复,程序接口版本等特殊情况)
    • 增加单元测试可以用于验证fix是否生效,发生fix的地方通常容易产生问题,增加单元测试可以预防后来人犯相同的错误。
    • 如果发生bug的代码逻辑及其复杂,而且没有测试手段的情况下,可以考虑进行局部重构进行测试。
  3. 代码重构要求保留单元测试的逻辑,重构之后需要在新的文件中追加或者重写之前的测试逻辑 目的在于方式重构改变了原有的行为,保证重构的行为是安全可靠的。
  4. 数据层接口需要经过测试用例 和工具代码类似,数据层部分代码十分重要,不容易变更(一旦发生变化需要十分小心)而且通常代码逻辑比较简单,结果容易预测,因此在增加或者改变原有接口行为的时候必须增加测试,保证修改是符合预期的。
  5. 新增接口如果存在接口测试框架那么需要增加接口测试
    • 接口是对外提供功能的通道,保证接口质量能够减轻第三方对接接口的工作, 防止发生返工。
    • 接口通常可以覆盖到下面多个层级,可以覆盖到胶水层代码,业务代码。 实现相对容易收效甚大。
    • 防止接口功能损坏
  6. 频繁发生问题的代码或者模块需要增加单元测试保证项目质量。 如果一个模块或者功能,频繁发生问题,可能提示这里的逻辑格外复杂或者实现的质量不高。这种功能情况下有必要对这个模块进行重新的设计并针对各种情况补充单元测试。
  7. 在功能独立或者模块不算复杂的代码中增加feature必须增加单元测试 review代码的人应当可以判断出这个模块的一个状态(如果不能判断,可能需要换个人进行review,不了解这快代码,review的效果也不会很好),进而能够判断出增加单元测试的复杂度。

没有单元测试的代码如何追加单元测试

  1. 尽量有熟悉该代码的人进行单元测试,至少由熟悉该代码的进行主持分配并进行review
  2. 简单的项目可以一次加全测试,对于复杂的项目,可以考虑从底层到上层逐步的进行测试覆盖。
  3. 补充单元测试的过程中如果发生了重构,建议仅进行结构性调整,不进行功能性变化。 否则功能可能会变得复杂,和开始的状态难以预期,然后可能引发新的问题。

一些技巧

  1. 如何测试数据库代码,如果数据库支持内存运行通过内存运行数据库进行测试(参见strikememongo),如果数据库不支持可以进行一些语法层面上的测试(参见sqlmock)。
  2. 如果代码中存在很多的网络调用该怎么办,可以采用一些测试网络库进行打桩(参见httptest), 如果是其他形式,可能需要自己编写桩代码。
  3. 实现中对涉及到存储和网络相关的部分和主体逻辑应当有一定的隔离,这样在单元测试中容易进行模拟。
  4. 对于目前代码复杂,结构不清晰,依赖混乱的代码,建议是先进行逻辑梳理,代码重构在进行代码测试。
  5. 不应当为了测试方便而对代码进行不合理的改造(比如增加新的功能),不应当为了测试而测试,如果发生了这种情况,那么可能是提示你代码或者测试方法存在问题,需要审慎的评估自己的实现。
  6. 合理抽象代码,如果发现测试不容易下手,可能需要在代码结构需要调整,可能存在函数过长,功能划分不合理的情况。