一、工作职责
- 单元测试方面给予开发人员支持
- 为开发人员提供测试框架
二、统一代码库
- 开发人员的交付物就是即将发布的代码,代码的组织形式、开发过程、维护是日常工作重点。
- 统一的代码库模式,可以使得开发人员快速从容的在不同项目之间转换而不需要过多的学习成本
三、版本构建流程
- 使用统一的平台和相同的代码库,持续不断的在构建系统中打包。
- 构建系统要求使用统一的打包规范,大家必须使用同样的“构建文件”来打包生成文件或程序包。
- 一个版本在构建的时候需要指定构建目标,这个目标由许多源文件编译链接产生。(公共库、测试套件等)
- 产出将是两个配套的构建目标:库构建目标和测试构建目标。库的构建目标是需要新发布的公共库,测试构建目标用以验证新发布的公共库是否满足需求。
3.1 主要流程
- 针对某个功能或服务,在一个或多个源文件中编写一类或一系列功能函数,并保证所有代码编译通过
- 把构建新的目标设定为公共库
- 通过调用这个库的方式编写一套单元测试用例,把外部重要依赖通过mock来模拟实现。对于需要关注的代码路径,使用最常见的输入参数来验证。
- 为单元测试创建一个测试构建的目标
- 构建并运行测试目标,做适当的修改调整,知道所有测试都运行成功
- 按要求运行静态代码分析工具,确保遵守统一的代码风格,且通过一系列常见问题的静态扫描检测
- 提交代码申请代码审核,根据反馈再做适当的修改,然后运行所有的单元测试并保证顺利通过
测试驱动开发模式,可以将步骤3提至步骤1之前。
3.2 复杂服务构建
对于规模更大的服务,通过链接编译持续新增的代码,构建目标也会逐渐变大,直到整个服务都构建完成,形成一个产品。它必须由三个部分构成:一个经过良好测试的独立库,一个在可读性与可复用性都不错的公共服务库、一套覆盖所有重要构建目标的单元测试套件
四、设计评审关注点
设计评审时,需要有一定的目的性去阅读文档,需要完成以下特定的目标:
1、 完整性: 文档残缺不全、特殊背景所需知识点
2、 正确性:是否语法、拼写、标点符号等方面错误
3、 一致性: 确保配图和文字描述一致、确保上下文中没有出现逻辑矛盾、确保与相关文档一致的主张和观点
4、 设计: 设计必须要经过深思熟虑、考虑可用性、考虑目标能否顺利达成、用了什么基础技术框架、框架选型的原因分析、设计是否太过复杂、有能简化的方法么、是否还需增加内容
5、 接口及协议: 对所用协议的描述有清晰的定义、是否完整描述产品对外接口协议、接口协议的实现是否与期望功能一致、是否满足公司统一的标准、是否有对自定义格式做解释
6、 测试: 考虑文档中描述的系统可测试性、是否需要增加测试所需钩子、系统设计是否考虑到易测性、预估测试人员需要提前做哪些准备
六、测试大小定义
小型测试是为了验证一个代码单元的功能,中型测试验证两个或多个模块应用之间的交互,大型测试为了验证整个系统作为一个整体是如何工作的。
1. 小型测试
- 为了验证一个代码单元,一般与运行环境隔离,例如针对一个独立的类或一组相关函数的测试。小型测试的运行不需要外部依赖。一般公司统称为单元测试
- 一般集中精力在函数级别的独立操作与调用上,限定了范畴的测试可以提供更加全面的底层代码覆盖率上
- 外部服务(文件系统、网络、数据库)必须通过mook或fake来实现。为了减少依赖,适当的时候也可以模拟实现被测类所在的模块的内部服务
2. 中型测试
- 为了验证两个或多个模块应用之间的交互,中型测试主要目的时验证模块之间的交互,一般公司统称为集成测试
- 中型测试运行时间更久,需要测试执行工具在执行频率上加以控制,不能像小型测试那样频繁地运行。一般由SET来组织进行中型测试
- 鼓励使用mock来解决外部服务依赖问题
3. 大型测试
- 为了验证系统作为一个整体是如何工作的,这涉及到应用系统的一个或多个子系统,从前端界面到后端数据存储。 一般公司称为 端到端测试 或 系统测试
- 依赖外部资源,如数据库、文件系统、网络服务等
七、 测试规模在共享测试平台中的使用
使用统一的运行方式来执行不同的自动化测试是有一定难度的。这个平台必须支持运行各种各样的测试任务。
1. google测试执行平台运行的通用任务如下:
- 开发编译和运行小型测试,希望立刻就能知道运行结果
- 开发人员希望运行一个项目的所有小型测试,并能快速知道运行结果
- 开发人员只有在变更代码出现时,才希望去编译运行相关的项目测试,并即刻得到运行结果
- 工程师希望能够知道一个项目的测试覆盖率并查看结果
- 对项目的每次代码变更(CL),都能够运行这个项目的小型测试,并将运行结果发送给团队成员以辅助进行代码审查
- 在代码变更(CL)提交到版本控制系统之后,自动运行所有项目的所有测试
- 团队希望每周都能够得到代码覆盖率,并实时跟踪覆盖率的变化
2. 运行状态如下:
- 上面所提及的任务,有可能同时并发提交到共享测试平台执行
- 其中一些测试,会极度消耗资源,使得公共测试机处于不可用的状态
- 其中一些测试,可能只需要几毫秒,而且可以和几百个任务同时在一台机器上并发执行
- 当每一个测试都标记为小型、中型、大型时,调度运行这些测试任务会变得相对简单,可以优化任务队列,达到合理利用的目的
测试执行系统利用测试规模的定义,把运行较快的任务从较慢的任务中挑选出来。不同测试规模在测试运行时间上规定了一个运行时间的最大值,同时测试规模在测试运行消耗的资源上也做了要求。当执行任务不满足要求时,会把测试任务取消并报告这个错误。这会迫使工程师提供合适的测试规模标签,精准的测试规模,可以使执行系统在调度时做出明智选择
八、测试规模的优缺点
小型测试带来优秀额代码质量、良好的异常处理、优雅的错误报告;大中型测试带来整体产品质量和数据验证。单一的测试类型不能解决所有项目需求。总体上google公司对于一个项目的测试规模占比,有一个经验法则:70%小型;20%中型;10%大型。
1. 大型测试
- 测试最根本最重要的:在考虑外部系统的情况下应用系统时如何工作的
- 由于对外部系统有依赖,因此它们时非确定性的
- 很宽的测试范畴意味着如果测试运行失败,寻找精准失败根源就会比较困难
- 测试数据的准备工作会很耗时
- 大型测试是较高层次的操作,如果想要走到特定的代码路径区域是不切实际的,而这一部分 却是小型测试的专长
2. 中型测试
- 不需要使用mock技术,且不受运行时刻的限制,因此该测试是从大型测试到小型测试之间的一个过度
- 因为它们运行速度相对较快,可以频繁的运行,但没有小型测试快
- 它们依赖外部系统
- 由于对外部系统有依赖,因此它们本身就有不确定性
3. 小型测试
- 更容易被测试,代码应清晰干净、函数规模较小且重点集中。为了方便模拟,系统之间的接口需要有良好的定义
- 由于能够快速执行,所以代码发生变更时即可运行,能较早的发现缺陷并提供及时的反馈
- 在所有环境下他们都可以可靠的运行
- 较小的测试范围,这样可以很容易做边界场景与错误条件的测试
- 它们有特定范畴,可以很容易的隔离错误
- 对子系统的模拟是有难度的
九、测试运行要求
由于测试执行在公用环境中,因此就要要求测试用例满足下面几个条件:
1. 每个测试用例和其他测试之间独立的,使它们能够以任意顺序执行
2. 测试不做任何数据持久化。测试用例离开测试环境时,保证测试环境的状态与用例执行前的状态一致。
tips: 任意顺序意味着可以并发执行。
- 对于占用系统资源的用例需要重点关注设计:
- 两个测试需要同一个端口,来接收网络数据
- 两个测试需要在同一路径下创建相同的文件
- 一个创建使用数据库表,一个删除这个数据库表
- 解决方式:
- 在测试执行系统中,让每个测试用例获取一个未被使用的端口,并让被测系统动态绑定到这个端口
- 在测试执行之前,为每一个测试用例在临时目录下创建文件和目录,并使用独一无二的目录名
- 每个测试运行在自己的数据库实例之上,使用与测试环境隔离的目录和端口
五、测试执行系统
- 必须考虑如何编译测试程序、执行、分析、存储和报告所有测试运行结果,这些都是自动化测试会遇到的挑战。
- 一个可以做代码编译、测试执行、结果分析、数据存储、报表展示的通用框架。
- 只有能加快开发过程的自动化测试才有意义,所以自动化必须与开发过程真正集成起来。
- 新增测试程序后,需要对测试创建一个构建说明文档,里面包括测试名称、源码文件、依赖库、还要指明其规模大小。
- 测试执行系统工作步骤
- 得到最新代码
- 运行所有测试
- 报告运行结果
- 重复上面的3个步骤
tips:
- 文档要求详尽,要求解释说明:角色、测试用例职责、测试执行者、集群系统、运行时刻的libc、依赖文件系统等
- 可以提供具体哪次代码变更导致失败
- 可以利用依赖分析技术寻找可能受影响的模块,并触发对应模块用例