Unit Testing
What is Unit Testing?
UNIT Testing 测试软件中独立的 units 或者 components。目的是使软件代码的每个单元都如预期执行。单元测试在开发过程中应用的编码阶段由开发者完成。单元测试分割代码段并测试它们的正确性,一个单元可能是单独的函数,方法,过程,模块或者对象。
The Benefits of Unit Tests
- 单元测试帮助你更在的找到和修复 bugs。
- 你的单元测试组件是开发者的安全网。
- 单元测试贡献更高的代码质量。
- 单元测试可能贡献更好的应用架构。
- 单元测试能够作为文档。
- 检测代码库的质量。 如果不能轻松的向代码库某部分添加单元测试,说明该部分的代码并不是很好–比如,函数太复杂了
How to Achieve Testable Code
拒绝边际效应和不确定性,采用纯净函数。反对过多依赖,使用 dependency injection。偏爱更小更专注的模块,而非巨大复杂的模块。避免 cyclomatic complexity。
9 Essential Unit Test Best Practices
1. Tests Should Be Fast
足够快的单元测试才能经常进行测试,足够经常进行的单元测试才能起到保护网的作用。
- 使单元测试尽可能简单
- 不要让它们依赖于其他测试
- 模拟额外依赖
2. Tests Should Be Simple
简单的代码有助于提高单元测试的正确性。
- 保持你的测试具有低 cyclomatic complexity。cyclomatic complexity 是一种代码度量,表示所给方法可能的执行路径的数量。
3. Test Should’t Duplicate Implementation Logic
避免在单元测试中使用实现的逻辑来验证实现,如果实现本身有问题,那么单元测试也具有相同的问题,且无法反映实现的问题,反而会使测试通过。
避免使你的测试变得花哨,保证它们绝对简单。
4. Tests Should Be Readable
测试用例也是某种形式的文档。它们可以执行且不会丢失同步。
- 使用 Arrage, Act, Assert 模式,来清晰地定义你的测试用例中的阶段。
- 可选的,采用 BDD-style 测试用例(Given/When/Then pattern)
- 每个方法一个逻辑断言
- 不要使用在测试用例中使用魔术字或者字符串。使用变量或者常量来表示你正在使用的值。
5. Tests Should Be Deterministic
无论进行多少次测试,相同的测试输入应当具有完全相同的输出。
为了让你的测试具有确定性,它必须被完全隔离,不能有任何外部依赖:
- 其他测试用例
- 环境变量,比如当前时间,或者计算机的当前语言设置
- 额外的依赖,比如文件系统,网络, APIs 等
测试用例从通过到失败或者从失败到通过的原因仅能是被测试的代码实现的改动。
6. Make Sure They’re Part of the Build Process
单元测试应当与工程一起被构建测试。
7. Distinguish Between The Many Types of Test Doubles and Use Them Appropriately
test double 在测试过程中取代依赖,与被测试代码交互。Test double 有不同的类型,比如,stubs,spies,mocks。依据你的需求选择合适类型的 test double。
8. Adopt a Sound Naming Convention for Your Tests
测试名应当能反映它们测试的情境。
9. Don‘t Couple Your Tests With Implementation Details
避免单元测试与被测试的代码太过耦合,这样当开发者改变内部实现或者进行重构时,单元测试依然能提供有价值的反馈和安全网,而不是也要随之改变。
原文链接: https://www.testim.io/blog/unit-testing-best-practices/