开发者测试 (DT, Developer Testing)
开发者所做的测试。
可控制性,可观测性,可定位性。
可定位性:不管故障被自愈,容错,还是最终失败,异常都需要输出,不能被内部逻辑完全消化。
日志要分层(INFO/WARN/ERROR),日志量与可定位性要权衡,太少不足以定位问题,太多影响性能,浪费磁盘空间。
有时过程中的交互消息/事件、状态、性能、资源等过程信息输出对问题定位也有非常关键的作用。
测试分层:UT:IT:ST = 7:2:1
单元测试(UT, Unit Test)
单元:最小粒度的功能单元/工作单元。
单元测试:一段自动化的代码。
单元测试(Unit Testing)是用来对一个模块、一个函数或者一个类来进行正确性检验的测试工作。
一个单元测试是一段自动化的代码,这段代码调用被测试的工作单元,之后对这个单元的单个最终结果的某些假设进行校验。单元测试几乎都是用单元测试框架编写的;只要产品代码不发生变化,单元测试的结果是稳定的。
CUnit
测试框架gtest/gmock
https://github.com/google/googletest/tree/main/googletest/samples
https://github.com/google/googletest/tree/main/googlemock/test
DECLARE_FUNCTION_MOCK
IMPLEMENT_FUNCTION_MOCK
EXPECT_FUNCTION_CALL
(WillOnce,WillRepeatedly,Invoke)
https://www.cnblogs.com/welkinwalker/archive/2011/11/29/2267225.html
https://www.cnblogs.com/coderzh/archive/2009/04/06/1426755.html
gtest的官方网站是: http://code.google.com/p/googletest/
测试框架关键字简介:
1.TEST_F宏:每个宏定义一个测试用例,宏的两个参数分别代表测试套名和测试用例名
2.SetUp和TearDown: 在每个测试用例调用前和调用后执行
3.SetUpTestCase和TearDownTestCase:在测试套调用前和调用后执行,必须为static void类型
4.EXPECT_EQ:预期结果检查
5.MOCK_METHOD1,EXPECT_CALL:对一个类的接口进行打桩/模拟
单元测试原则FIRST:
F-FAST(快速原则)
I-Independent(独立原则)
R-Repeatable(可重复原则)
S-Self Validating(自我验证原则)
T-Timely(及时原则)
单元测试用例需要符合BCDE原则:
B:Border 边界值测试
C:Correct 正确的输入
D:Design 与设计文档相结合
E:Error 强制的错误输入
单元测试的作用: 1.单元测试描述了代码的预期行为,可以最有效地保证代码正确运行 2.由于单元规模较小,当因为代码变更出现问题的时候,可以帮助我们快速定位问题 3.有单元测试覆盖的代码,让我们更有信心,敢于放心做代码重构
集成测试(IT, Integration Test)
集成测试也叫组装测试或联合测试,按照设计要求将各个单元,组件或子系统集成到一起测试是否能正确运行。
系统测试(ST, System Test)
系统测试是对整个系统的测试,将硬件,软件,操作人员看作一个整体,检验它是否有不符合系统说明书的地方。
测试驱动开发(TDD, Test Driven Development)
TDD = TFD + Refactoring 即测试先行加上重构。
测试驱动开发是一种由一系列短小迭代组成的软件开发技术。
UT中的替身对象
测试对象概述
- Dummy: 不被使用的占位
- Stub: 提供假的数据
- Mock:提供期望的行为
- Spy:能够存储数据
- Fake:简化版的实现
自测
(单选题)1.软件测试是软件质量保证的重要手段,( )是软件测试中的最基础环节
- 功能测试
- 单元测试
- 结构测试
- 验收测试
2.关于软件测试,以下说法错误的是( )
- 测试是为了发现程序中的错误而执行程序的过程
- 好的测试方案是尽可能发现迄今为止尚未发现的错误的测试方案
- 成功的测试是发现了至今为止尚未发现的错误的测试
- 软件测试的目的是使程序符合结构化原则
(多选题)1.关于可测试性,以下描述正确的是:( )
- 可隔离性指软件元素(功能单元、模块/组件等)被分解/隔离的能力,也有称可分解性。
- 可控制性指对广义输入的控制能力,广义输入包括:被测对象的初始状态构造,被测对象的输入,注入到被测对象内部的异常。
- 可观测性指对广义输出的观察能力;广义输出包括:被测对象的内部状态或事件(过程),被测对象实际的输出(结果)。
- 可定位性指输出信息支撑问题分析的能力。
2.关于单元测试,以下说法正确的是:( )
- 单元测试主要针对对外暴露的小粒度功能接口的测试,未对外暴露的内部函数不需要测试
- 面向对象语言,单元测试主要测试类对外暴露的公共接口;对于面向过程的语言(C语言等),单元测试主要测试头文件中对外暴露的接口。
- UT测试也需要做测试设计,且要从黑盒(功能)角度设计,从输入(I)、处理(B)、预期输出(O)的角度进行用例分析设计
- UT测试需要将功能单元隔离开测试,一方面需要代码具有较好的可隔离性,另一方面,为了做UT,需要做适当的代码重构提升代码可隔离性,也就是说,做UT可以提升内部质量(代码架构质量)。
3.关于测试分层,以下说法正确的是:( )
- 耦合/依赖大的功能单元或者组件不要强行隔离测试,建议要么通过架构优化,解耦开,要么直接集成测试
- 虽然耦合/依赖大的功能单元/组件拆分测试的成本较大,但是为了追求金字塔测试分层,还是要将功能单元/组件强行拆分隔离开测试
- 通过持续重构保持单元/模块/组件边界清晰,提升代码的可隔离性,降低功能单元/模块/组件分解的成本,从而逐步的朝着金字塔分层的方向优化
- 所有的产品测试分层都是分UT、IT、ST三层
测试框架
• C/C++单元测试框架gtest
• Java单元测试框架JUnit
• Python单元测试框架PyUnit
• go单元测试框架可以用go自带的gotest包
相关书籍
• 《软件测试基础教程(第2版)》
• 《有效的单元测试》
• 《JUnit Recipes-程序员使用测试技巧》(JAVA)
• 《软件测试》
• 《Clean Code》
• 《重构—改善既有代码的设计》
• 《xUnit测试模式–测试码重构 》
• 《单元测试之道》
• 《实战Infusion 代码坏味道浅析》(JAVA)
相关链接
• 白盒测试覆盖技术:https://blog.csdn.net/virus2014/article/details/51217026
• JUnit4(JAVA):https://github.com/junit-team/junit4/wiki
• Mockito(JAVA):http://static.javadoc.io/org.mockito/mockito-core/2.25.1/org/mockito/Mockito.html
• 《Debugging with GDB》:https://www.gnu.org/software/gdb/documentation/