《Google软件测试之道》
Google软件测试之道
Google对质量的理解
- 质量不等于测试,即质量不是被测出来的
- 开发和测试应该并肩齐驱,测试就是开发过程中不可缺少的一部分
- 质量是一种预防行为而不是检测
Google对软件测试的划分
抛却复杂的专业术语,简单按照测试范围去划分:
- 小型测试:对一个代码单元的测试,通常就是单元测试
- 中型测试:对两个或多个模块之间交互的测试,通常类比于“集成测试”
- 大型测试:对一个应用系统及其子系统整体的测试,通常类比于“端到端测试”
这样划分的好处有:
- 容易定位问题:测试范围从小到大,各自负责不同的功能,某个测试一旦失败容易让开发找到问题所在
- 产生较高的测试回报率:测试的回报率等于测试所产生的业务价值与测试执行成本之比。范围小的测试越容易被自动化,但因为覆盖业务范围小所产生的业务价值也就越小,范围大的测试则反之。根据团队和产品具体情况,通过制定合理的测试策略和划分测试范围,决定自动化测试的比例,可以产生较高的测试回报率
Google对软件测试角色的划分
- SWE(软件开发工程师):主要职责是实现用户功能,除编码外也具有编写和组织测试的能力,日常活动是代码设计、代码实现与编写测试
- SET(软件测试开发工程师):主要职责是让SWE更容易地去写测试,工作重心在可测试性和通用测试基础框架上,是SWE的紧密合作伙伴,关注质量提升,具备观察代码质量、编写测试框架等能力,日常活动是参与设计评审、代码重构、编写测试框架等
- TE(测试工程师):主要职责是专注于用户角度的测试,关注集成后的系统是否可以满足最终用户的需求,是真正的产品专家、质量顾问和风险分析师,具备全局审视与分析思考的能力,日常活动是模拟用户使用场景,对SWE和SET编写的测试进行分类组织,分析、解释和测试运行结果,特别是在项目最后阶段推进产品发布
与传统软件测试中的角色不同,Google将编写测试的工作大部分转交给SWE进行,因为测试本来就应该是开发工作的一部分,由开发去完成再合理不过。考虑到SWE在测试编写方面需要统一的支撑,SET作为SWE的紧密合作伙伴介入进来,予以框架工具和技术方面的支持,并帮助观察代码质量。而TE的作用向后推移,更关注系统集成为一个整体后,从用户角度是如何使用的,能否满足用户需求,因为毕竟质量的定义就是“满足用户需求”。TE看起来更像一个具备很强验收能力的产品经理,并且被验收的不仅仅是用户需求,还会用放大镜仔细看SWE和SET所做的测试工作细节。
Google的“工程生产力团队”
测试是独立存在并与业务领域部门平行的部门,横跨于各个业务领域,被称为“工程生产力团队”。测试人员以租借的方式进入产品团队帮助做提高质量相关的事情,寻找测试方面的可改进之处。测试人员并不直接向产品团队汇报。这种借调模式,一是可以帮助测试人员保持新鲜感,二是可以让一个好的测试实践迅速在公司内的不同团队间蔓延。
测试左移(前移)与测试右移(后移)
相对于传统的认为测试工作主要是测试人员的事的看法,Google提倡测试左移与测试右移:
- 测试左移:开发阶段就应该完成大部分测试工作,尽量将测试放在早期进行,有助于尽早发现问题和质量内建
- 测试右移:既然TE的主要工作是从用户角度审视产品是否满足用户需求,那为什么不直接找真实用户来进行测试呢?内测用户、众包测试都是测试右移的手段,直接、快速地收集来自真实用户的反馈,能得到更有用户价值的测试结果
但是,个人认为测试左移是测试右移的前提条件,即团队尚不能完全保障产品的功能完整与稳定性之前,不要仓促开放给哪怕只是部分用户。团队应该先着力于发展自己内建质量的能力,即让人人都来关注质量,以及提前预防问题的发生。
《Google软件测试之道》的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- Redis第二讲【Redis基本命令和五大数据结构】
[二.Redis基本命令和五大数据结构] redis的基础知识和命令 redis 是一个单进程(包装epoll函数来对读写事件进行相应) 默认有16个数据库,初始使用的数据库为0号库 默认端口为637 ...
- java概述和java环境按照,java开发体验
java概述: Java的发展可以归纳如下的几个阶段. (1)第一阶段(完善期):JDK 1.0 ( 1995年推出)一JDK 1.2 (1998年推出,Java更名为Java 2): (2)第二阶段 ...
- Win32_DiskDrive 硬盘 参数说明
Availability --设备的状态. BytesPerSector --在每个扇区的物理磁盘驱动器的字节数. Capabilities --媒体访问设备的能力阵列. CapabilityD ...
- 《吊打面试官》系列-ConcurrentHashMap & HashTable
你知道的越多,你不知道的越多 点赞再看,养成习惯 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试点思维导图,也整理了很多我的文档,欢迎Star和 ...
- Go 面试每天一篇(第 65 天)
Go 面试每天一篇(第 65 天) 1.下面列举的是 recover() 的几种调用方式,哪些是正确的? A. 1func main() { 2 recover() 3 panic(1) 4} B. ...
- 【每天一题】LeetCode 0107. 自底向上层遍历二叉树
开源地址:点击该链接 题目描述 * 给定一个二叉树,返回其节点值自底向上的层次遍历. * 即按从叶子节点所在层到根节点所在的层,逐层从左向右遍历 * * 例如: * 给定二叉树 [3,9,20,nul ...
- 终极CURD-4-java8新特性
目录 1 概述 2 lambda表达式 2.1 lambda重要知识点总结 2.2 java内置函数接口 2.3 方法引用 2.4 构造器引用 2.5 数组引用 2.6 lambda表达式的陷阱 3 ...
- SpringCloud -创建统一的依赖管理
场景 Spring Cloud 为开发者提供了在分布式系统(配置管理,服务发现,熔断,路由,微代理,控制总线,一次性 Token,全居琐,Leader 选举,分布式 Session,集群状态)中快速构 ...
- SAP 基础知识
SAP R/3系统的应用层由应用服务器及消息服务器(Message Server)组成. 应用服务器组件如下: 工作进程(Work Process) 调度机(Dispatcher) 网关服务器(Gat ...
- 位域-isa指针
一.isa指针结构 union isa_t { isa_t() { } isa_t(uintptr_t value) : bits(value) { } Class cls; uintptr_t bi ...