前言

对于软件企业来讲,通过不断创新提升企业价值,创造企业核心竞争力是永恒的话题。这个过程中,企业的效率是至关重要的一个环节,特别是在当下的大环境中,如何能够通过合理的人员,流程,技术规划实现降本增效,如何能够通过对团队,对个人的持续培养让每个人更专注,更有效率,等等诸如此类,是这篇博客希望能够讲述的一个话题。这篇博客大部分的内容是来自于茹炳晟的《软件研发效能提升实践》这本书。通过对重点章节的思考整理,形成这篇文章。其中的内容来自于对书中的要点摘录,同时加入一定个人的思考和实践。

声明

这篇文章不会用于任何商业用途,如果大家对于原书希望有更多的了解,请购买正版 《软件研发效能提升实践》 软件研发效能提升实践

Outlines

研发效能简述

“反内卷” 的潮流已经悄然而至

“内卷” 表现为公司或部门的内部竞争越来越激烈,但业务和业绩却没有什么突破。 软件为主的企业需要通过提高效能,减少一味的通过堆砌劳动时间来获得巩固走成果,转 “加班” 为 “奋斗”,让企业和团队成为一个技术密集型的企业,而不是劳动密集型。

想法效能成为科技企业的核心竞争力

很多公司通常回将 KPI 或 OKR 作为团队和员工的绩效衡量指标,如果目标没有发生变化,那么工作量也不可能大幅的减少,这就意味着,原本要依赖加班才勉强完成的工作,现在需要在正常的工作时间内完成。这种情况下,提升研发效能注定是我们要走的必经之路。那效能究竟是什么?可以总结为以下几点:

  • 更高效
  • 更高质量
  • 更可靠
  • 可持续
  • 更优的业务价值
  • 强调功劳而不是苦劳
  • 强调更聪明的工作
  • 强调个人能力的成长

产品是由组织开发的,组织是由个人组成的,只有个人的效率提升了,能力增强了,同时产出更有价值的内容,让产品和团队真正看见了,整个企业的研发效能才会更好。

研发效能要解决的实际问题

  • 效能中的重复造轮子 对于统一的效能指标,效能研发可以依靠效能中台,做统一规划,指标统一采集,避免每天产品线都在做研发效能所必须的 “从0到1的” 的重复事情。

  • 特殊时期需要将本增效 身处红或者资本困难的大时代背景,同时研发的规模也非常大的时候,需要 “勒紧裤腰带过日子” 了,当开源节流的开源遇到瓶颈,节流就应该发挥作用了。这里的节流就是研发效能的提升,即投入同样的资源和时间,获得更多的产出。

  • 减少 “筒仓困局” 现象 在研发的各个环节内部可能已经做了优化,但是跨环节的协作可能会产生大量的流转与成本,从而影响全局的效率。基于流程优化,打破各个环节看不见的 “墙”、去除不必要的等待,提升价值流动速度正式研发效能在流程优化层面试图解决的一类问题。

研发效能与期望之间的鸿沟

随着软件越做越多,越做越复杂,研发效能的绝对值会随着以下因素的变化变得越来越小,研发效能的鸿沟会越来越大

  • 软件架构的复杂度提升(微服务,服务网格等)
  • 软件规模不断扩大(集群规模,数据规模等)
  • 研发团队的规模不断扩大 软件研发效能提升实践

研发效能双流模型

腾讯一些研发团队所采用的 研发效能双流模型 从软件研发的各个阶段提出了研发效能提升的工程实践,并且倡导需求价值流和研发工程流的自动联动。需求价值流和研发工程流的自动联动是指需要状态不需要通过手工的方式来完成流转,而是会随着代码的实际完成情况自动流转。 软件研发效能提升实践

研发效能的罗生门

在研发效能落地过程中,也存在一些需要思考的问题

  • 迷信单点能力,忽略全局优化和拉通的重要性
  • 具有普适性的通用研发工具其实没有专属工具好用
  • 忽略研发效能工具体系的长尾效应。我们很难打造一套统一的研发效能解决方案
  • 用 “伪” 工程实践和 “面子工程” 来滥竽充数
  • 盲目跟风,引入不必要的流程和体系
  • 研发效能度量不是银弹,也没有完美的效能度量,不懂数字的人是糟糕的,但是更糟糕的是只看数字的人

研发效能的黄金三角

软件研发效能提升实践

效能实践

产品导向+工程卓越

  • 产品向导:对于产品以及产品经理来说,需要明白区别于项目导向的交付模式,我们更倾向于以产品导向的交付模式组织相关效能实践。产品导向可以让我们面向长期的业务价值,组织长期稳定的敏捷团队,持续迭代和优化产品。我们承认需求的不确定性,要持续改进产品,而不是简单的遵从既定的计划,我们要考虑长期产品和团队能力的建设,而不是把短期项目做完了了事,我们要考虑持续为客户创造价值,而不是看项目有没有超过预算,我们要面向工作结果进行响应,而不是盯着一些局部的工作产出。
  • 工程卓越:对于技术团队和技术经理来说,需要明白,我们必须持续关注工程和技术的卓越性,而不仅仅是交付了多少需求或特性。比起多完成几个小功能,也许工程和技术上的提升所带来的价值会跟到。我们要追求用工程化的方法持续把确定性,重复性,机械性的任务自动化,从而在提升效率的同时让工程师有更多实践花在有创造性的事情上。

效能平台

自动化+自助化,场景化+生态化

  • 自动化:研究表明高效能的企业在自动化构建,自动化测试,自动化环境创建部署,自动化监控和可观测新等方面远远好于中低效能的企业
  • 自助化:自助化代表上校有角色可以通过平台紧密衔接,在工具平台被使用之后,上下游角色应该都可以按需,自助的使用,降低了对于某个角色或者人的依赖,这样组织协作效率才能提升
  • 场景化:一站式,一体化 不是按功能简单的堆砌,而是按照场景进行组织的,例如按照一个具体的任务进行从前到后的跟踪,按照某一产品为主线贯穿 DevOps 的工作过程
  • 生态化:多部门之间提取共性,在研发效能能做统一考量,减少重复建设和避免内耗。 软件研发效能提升实践

效能度量

数据驱动+实验思维

  • 数据驱动:效能度量的目标是让效能可量化,可分析,可提升,通过数据驱动的方式更加理性的评估和改善效能,而不是凭直觉。
  • 实验思维:效能提升没有 “一招鲜,吃遍天” 的万能公式。而是要基于上下文进行有针对性的试验和探索。我们需要试验思维,找到真正有用的改进活动及其与结果之间的因果关系,有的放矢才会更有效率和效果。

研发度量需要做好以下5项能力

  • 构建自动采集效能数据的能力
  • 涉及效能度量指标体系
  • 奖励效能度量分析模型
  • 涉及和实现效能度量产品
  • 实现有效的效能数据运营体系

研发效能宣言

业务价值高于职能目标(业务视角)
全局流动高于局部优化(流程视角)
工程卓越高于工具平台(技术视角)
数据思维高于经验沉淀(数据视角)
工程师文化高于绩效管理(组织视角)

业务价值高于职能目标(业务视角)

这里更多是对于产品有主导决定权的人而言,例如产品总监,产品经理,一切不宜稻城业务价值为导向的研发效能提升都是耍流氓。可以说效能是方向,效率是速度,如果方向错了,速度再块也没有用,这就是我们经常会通道的 “高效交付无法确保业务成功” 的原因。
瞎忙也是某种形式的懒惰。对于研发团队生产力的提升,思辨首先要找到这正的需求,对于某一个需求,要多花一些时间去研究。因为需求一旦决策形成,其执行成本是数十倍的增加。产品经理的一个决策背后是研发团队,测试团队,运维团队,客服团队,销售团队的大量工作。
从本质商讲,产品经理并不是盲目的追求用户价值最大化,而是选择性的找到性价比高的用户价值。这样研发团队的业务价值输出才会被放大。
当业务价值出于快速上升期的时候,需要的是更块的业务能力交付,用堆人,堆时间的方式可以解决短期效率的不足,同时技术商也可以选择主动的负债,词阶段这种 块、糙、狠 的模式是有效的。 但是用户群体规模大了之后,就不能这么做了,高质量,业务稳定和业务连续性成为了主要矛盾,团队也开始要寻求工程卓越。
当然,特别需要注意的一点,很多时候业务失败不是效能的问题,而是业务本身不行,但往往会让效能变革背锅。

全局流动高于局部优化(流程视角)

流动是精益思想的五大原则之一,是精益思想的关键部分,其目标是让价值不断的立东起来,在研发初期,局部优化,例如编译时间的缩短,自动化执行时长的优化等是有效的,但是一旦涉及到后期多方合作,业务更复杂的深水区,全局流动的优化才更有用。 在软件研发中国,经常使用的度量指标是流动效率,即在软件交付过程中,工作出于活跃状态的时间,与总交付时间的比值。 很多时候研发只是因为交付流被迫中断,不得已切换到其他工作,需求在大部分时间内,是依赖的等待和阻塞等状态,以至于看似团队很忙,但是产出却有限。
另外,有时候,过度优化某个部门的效率,反而会带来交付的阻塞和浪费,使得需求总是等待排期或者优先级被频繁修改。这样对于全局的效率也是会造成浪费。

工程卓越高于工具平台(技术视角)

工具平台应该简单,易用,线下屏蔽复杂的实现过程,向上提供易于使用的能力,在不增加工程师学习成本的前提下,默默的优化研发过程的各个环节,提升整体的工作效率。一块白板加便利贴可以提升效率,同时整套的敏捷流程也可以是披着敏捷外衣的瀑布模型。借鉴其他公司的工具没有问题,但是一味的抄作业只会让效率更低。

数据思维高于经验沉淀(数据视角)

很多行业,例如销售,财务,新媒体已经不依赖个人经验来做决策了,而是更多依赖数据,但是数字化程度最高的软件研发行业却高度依赖人的经验,这点值得反思。经验沉淀固然重要,但是其成功很难被复制。数据思维能够帮助决策者站在更高的位置思考问题,看到更全的格局,从更高的视角解决问题。通过数据思维可以从事后复盘进化为风险管控。 数据思维 加 个人经验 可以发挥更大的作用,

工程师文化高于绩效管理(组织视角)

绩效管理只是一个达成目标的工具,而工程师文化是一个体系,有着更广泛的内涵。 工程师文化提倡用理性思维来创造性的解决问题,要给工程师最大的空间,体长深入研究技术,钻研问题,持续不断的改进产品。另外要尊重客观事实,淡化权威,一切的想法,判断以及思路是以数据和实际的结论为支撑。 一些企业,研发效能只是服务管理者,例如出具各种报表,提供各类汇总。但是,服务管理者之外,也需要服务好工程师,研发效能的提升要拥抱开发者的体验,给工程师提供上下一致对齐的目标,更人性化的管理和工作环境,业务要求范围内最精简的流程。

研发效能的管理实践

研发过程中的管理挑战

我们在研发过程中,经常遇到以下问题:

  • 业务部门常提出一句话需求,需求表述不清晰,沟通成本高,效率低
  • 交付的产品效果与用户需求偏差过大,用户满意度低
  • 业务部门变更频率高,开发阶段的需求变更不可控,开发周期长,成本呢高
  • 业务部门与研发部门存在重要的协作鸿沟,业务部门吐槽研发部门进展缓慢,研发部门吐槽业务部门需求过多,无法形成团队合力
  • 研发资源分布情况出于盲盒状态,利用度不清晰,投入大量成本,却仍然长期出于人力缺乏状态
  • 研发团队加班严重,但需求发布仍然常常延期,产品在发布上线后问题频发
  • 代码库使用与管理混乱,常在产品版本发布时爆发合并冲突
  • 开发质量依赖测试环节,测试资源峰谷波动明显
  • 自动化程度不高,重复性工作的人工操作提高了问题发生的概率
  • 回归测试重复率高,工作量大,效率低,测试覆盖度不清晰,品质不可控
  • 产品发布受环境和人为因素的影响大,发布异常频发,成功率不可控
  • 开发人员疲于应付业务需求,没有经理去精进技术,士气低迷,工作效率低下

绝大部分问题的动因源于业务痝,开发部门和运维部门之间存在严重的协作鸿沟。这些鸿沟导致了目标,资源,时间等诸多信息的不对称,他们相互交叉,重叠干扰,导致互相不能李洁对方的价值和必要性,从而陷入低效的僵局。因此,协作效能是首要要解决的问题。 为此,我们需要以下的一些措施:

  • 从需求提出,评估分析,排期开发,测试验收,上线研发各个环节实现透明化
  • 科学的制定从需求分析到产品发布的相关流程,因地制宜,并结合自身的业务特色落实和实施
  • 设置合理的门禁管理,使代码的测试,入库,发布等核心事件能够得到有效的管控,从而保障研发质量
  • 对高度重复化的事件,建立及其自动化机制,降低人为失误的可能性
  • 形成制度和规范

敏捷和精益协作实践

实现敏捷协作

在研发的开端,提出需求的时候,就需要敏捷模式的介入。

  • 业务部门应使用标准化的引导型需求模板,准确和有重点的提出业务需求,形成需求任务,并使开发人员能够快速,精准的理解。多任务会形成需求池,此时应该对池内的需求进行价值评估或初步清晰,讲无效的需求去除。对保留下来的需求,需要让技术专家从专业维度预估需求的复杂度及完成时间。这些评估信息会反馈给需求提出人,以帮助业务部门了解成本与困难程度,同时也能识别项目团队的工作优先级,拥有的人力资源成本等。 评估的角色一般包含
    • 创建人:需求创建人,和评估人可以是同一人
    • 评估人:业务需求初审人员,可以是产品总监或者产品负责人
    • 提出人:需求真实提出人,对于外部需求,则是靠需求的数据统计,价值和用例阐述来说明
    • 干系人:需求上下游关联人
    • 分析人:研发方的业务专家 需要说明的是,对需求的可行性做初步评估,因业务人员更加熟悉业务真实诉求,能快速,有效地还原业务实际场景,判断需求的可行性,建议评估人按照业务领域统筹规划,解决业务层面不知道找谁评估需求的疑惑。
  • 开发环节,业务部门也可以随时查看需求的整体进展,了解项目的潜在风险
  • 最后的验收与上线环节,平台可以建立规范化的标准集中进行验收。

敏捷流程的专业化与本地化

  • 敏捷需求管理
    • 需求规划方案设计
      确保需求文档的统一性,减少团队不同成员的学习成本,提高阅读效率

    • 需求评审 评审维度要覆盖体验交互,技术可行性,方案容错性等各个方向

    • 需求追踪 通过既定的规则来展示需求完成率,达标率,延期率等基础数据信息,辅助需求管理

    • 需求变更 以平常心对待变更,针对变更主要要注意下面几点

      • 识别变更
      • 评估变更影响
      • 备选方案
      • 紧急程度
      • 变更申请
      • 变更知会
      • 变更审批
      • 变更追踪
  • 版本迭代管理 在项目初期,我们需要对产品整体规划有一个全局的把握,之后,指定分阶段计划,对每个版本迭代定制可交付产品增量,并根据实际情况进行适当的调整。最后,制定实施路线,围绕核心目标层层分解,按照不同的时间颗粒度划分指定完整的产品路线图,从而明确产品的实施路线。按照这个思路,团队就可以形成研发节奏,创建版本迭代计划。 所以大致步骤为:
    • 用户估时地图展示需求的关联关系
    • 产品路线图排布迭代周期计划
    • 快速估算人力消耗
    • 需求看板实时监控研发进度
    • 指定版本发布计划发布生产版本

软件研发效能提升实践

  • 测试管理 在版本迭代启动后,或者在需求清晰之后,测试人员就要建立测试用例,并明确测试用例与需求的关系,版本迭代与测试计划的关系
    • 测试用例 在执行测试用例的过程中,遇到缺陷需要随时上报,并自动关联需求和用例

    • 测试计划 测试计划通常基于版本迭代创建,包括冒烟测试,系统测试,回归测试,UAT测试等等,不同的测试计划类型应该使用对应的用例来验证。同时,针对测试计划,可以设置相应的完整进度比例,同时测试计划也可以通过自动化流程设置,与需求计划和版本计划进行上下游打通,提升研发效率及效能。

    • 测试报告 测试报告应该可以根据报告模板来定义,包括设置不同类型的出口达标标准,报告发布的触发条件等

    • 测试门禁
      针对不同环节则可以设置门禁

      • 版本门禁: 重点检查需求纳入版本的条件,比如在合并之前,需要观察相应的需求是否达到:需求已经评审,需求方案业务已经确定,需求已审批 等环节必须通过,才可以将需求纳入版本
      • 版本发布移交门禁:重点检查版本内所有用例测试已通过,版本内高级别缺陷无遗留,需求代码追述率已达标 等
      • 用例门禁:重点检测测试用例的准入情况,在将测试用例纳入测试计划的时候,需要和相应的团队成员完成用例评审
      • 代码门禁:重点检查代码入库时的过程,例如 自测,MR, CodeReview 等
      • 安全门禁:重点检查安全制度执行情况,例如漏洞扫描,安全制度评审等
      • 运营门禁:重点检查运行制度的执行情况,包括运营资源审核,运营评审、运营验收等。
      • 生产发布门禁:发布之前,将之上的门禁选择性执行,并检查最终状态。
  • 代码管理 代码管理中,包括分支管理,文件管理,代码质量管理,代码规范等等,其中最重要的是代码质量管理
    • 在制度方面,要建立良好的代码规范,它将一道评审时的权威评价体系建立,以提升代码质量与代码互助传承
    • 在风险防控方面,要建立代码扫描机制
    • 在权限管理方面,要控制权限范围,设定核心代码审核人,关键代码负责人等,对不同代码文件的新增,合并进行评审
    • 在代码评审方面,除了要支持基于合并的 MR,还可以将协作平台,流水线带通,支持基于需求视角的代码评审。
  • 持续集成管理
    CI:代码合并,自动化编译打包部署和测试
    CD:在持续集成的基础上,将集成后的代码部署到各类环境,达到交付即部署的效果
    整体流水线步骤如下
    • 触发源
    • 编译
    • 扫描
    • 测试质量
    • 环境部署
    • 生产门禁

数据驱动的组织效能提升实践

数据驱动组织提效的困境和应对的关键

管理实践面临阻碍

  • 重要但不经济的事情得不到资源
    现状:研发效能对许多企业而言仍然是重要但不紧急的事情,当业务压力增加,研发效能建设和数据驱动转型就会被推迟。
    建议:建立数据管理专业组织,建立数据管理框架,发布数据管理策略,统一信息框架和标准,建立数据质量改进机制等。我们面对业务优先级与研发效能的两难选择时,我们也可以主张双驱动,我们的组织应该从上到下指定战略级研发数据规划,尽早设立独立的效能部门或负责人,专门主导研发数据建设工作。

  • 数据标准兼容困难
    现状:现实中经历数字化转型的企业,往往每隔一段时间就会上一套新的系统,即便是同一类的系统,技术架构会出现更迭,因此,多数企业的研发数据和业务数据普遍存在标准不统一的问题。
    建议:为了达到统一的数据治理能力,企业必须引入现金的数据处理技术,才能做好支撑。例如引入数据胡,在实施层面,组织需要首先根据自己的需求制定入湖的标准和流程,保证入湖数据的清洁,完整。其次时数据源的同步策略,以确保数据更新策略满足数据使用的要求。

  • 指标体系设计不科学不可持续
    现状:度量不能以偏概全,不能没有文化引导,不能把数据驱动作为 “唯数字论”,一旦组织文化只关注数字增长,忽略创造用户价值,必将引发管理灾难。 建议:每一个指标定义背后都关联着被度量对象的生产行为。指标体系的设计需要以自上而下,自下而上,横向连接的方式在组织内部形成深层次的共识,这样才能让重要指标有效的落实,浅层共识停留在个体认知层面,对组织结果产生的实际影响有限。我们往往缺少的是一套指标体系,而是对指标体系的深层共识。

同时人们对数字驱动存在误解和认知偏差。认为一是度量可能引发个体造假,致使数据失去观察价值,二是过度关注数据就会陷入指标陷阱,从而忽略组织的真正目标是创造用户价值。以及对于数据驱动,数字化人才和持续的资金投入是必不可少的。

建立正确的数据驱动观

数据驱动的意义不是控制而是赋能。度量的重点是改进,不是监督。通过度量系统的数据反馈,我们能够选择如何调整自己的行为,一步步朝着既定的目标前进。如果指标设计不合理,我们就会对度量的公平性产生怀疑,从而不会依据度量系统的反馈做出调整。如果度量是公平的,度量结果是我们期望改善的,那么我们就会非常积极的希望通过度量系统了解自己的现状。
因此,度量是加强反馈的手段,不是监控行为的工具。度量旨在改进。对崇尚公平性的团队而言,数据驱动下的度量,必须是科学的指标体系。
通过指标体系的制定,积极的在组织内部建设共识。我们应该尝试进行怎么做度量的思考,而不是停留在做不做度量的问题上。
数据驱动可以提高决策质量。数据驱动的目的是实现组织认知的进化。我们可能听说过企业如人的说法。企业认知水平的高低影响了决策的质量,数据驱动的目标就是通过剥离高智能个体的限制,实现高效的认知拷贝,从而规模化的提高认知。

数据驱动组织提效的框架

软件研发效能提升实践 数据驱动的开端是数字化战略。在高层管理者意识到数据价值对组织的重大意义,从人才到资金都给与充分支持之后,数据驱动才能开始落实。在建设初期,组织首先需要就数据价值,数据文化,数据治理方式展开充分的讨论,并评估组织内部的数字化人才是否满足建设数据湖,数据引擎的要求。如果不具备这样的技术实力,或者希望提升建设本身的效能你,组织应该考虑外部采购的形式补充建设能力,将这些数据基础设施搭建起来只是第一步,组织内外部的用户需要通过数据消费,不断从数据中提炼信息,沉淀知识,以此达成认知进化,提升决策力,洞察力,创新力,通过数据反哺业务,提升组织运转效率。

持续交付工程实践

常见问题

  • DevOps 流水线接入率低
    不少开发过程依旧是使用先本地开发,提交编译平台,再手动去平台上线的模式。这种模式下,很多质量保证能力和指标监控手段都无法介入并发挥作用,同时过多的人工操作也存在较大的误操作风险。

  • 维护角色各异,流水线非标准化
    有的团队由QA 来统一提前进行流水线的创建和维护,有的团队由RD随用随建流水线,导致废弃的流水线越来越多,而且大多数只用过一次,维护成本很高,另外,团队不同的研发习惯造成流水线的编排也不同,有的通过增加质量卡点来提高质量,由的通过增加原子并发执行来提高效率,没有统一标准。

  • CI/CD 原子呢两个i复用率低
    各个团队中的 RD 和 QA 通常都会通过开发脚本或接口方式解决遇到的问题。这样,A 团队之前遇到的问题,很可能 B 团队也会遇到,但 B 团队并不知道 A 团队已经开发过解决问题的脚本或接口,而会重复开发,造成人力资源的浪费,并且随着业务的不断再增加和团队的不断扩大,这个问题会越来越严重,导致整体 CI/CD 原子能力复用率很低。

  • 度量指标建设不完善
    如果没有一套指标来度量研发流程各个阶段的效果或问题,也就无法了解接入和不接入流水线究竟有何差异。在不同团队的流水线上,原子能力及编排标准化对效率和质量究竟有怎样的帮助?当前各个团队所处的持续交付阶段及下个阶段的重点事项是什么?另外,没有度量,就没有客观的数据来支撑我们进行下一步的规划。

  • 平台割裂,整体流程不顺畅
    公司往往会有很多平台,如需求管理平台,代码仓库,编译平台,接口自动化平台,安全扫描平台,效能平台,云平台,但各个平台之间是割裂的,导致整个研发活动也是割裂的,即需要特定时间在 A 平台操作,完成后再去 B 平台操作。 这不但影响开发测试效率,而且对新原子能力接入也是一个阻力。

持续交付的前期调研

整体的解决方案从分析线上的问题入手,线上问题 Top 归类如下

  • 接口复用影响
  • 技术方案问题
  • 数据不一致
  • 自测不充分
  • 接口理解不一致
  • 版本错误
  • 环境混乱
  • 问题难定位

所以相应的质量保障能力的 Top 分类如下

  • 接口测试
  • 上线流程规范
  • 单元测试
  • 代码覆盖率
  • 研发流程规范

同时在 RD 侧,Top 的建议

  • 研发流程规范 通过对研发流程进行规范,可以提高 QA 介入的程度,如在上线前,需要 QA 在确认,设计评审,上线发布步骤,自动化测试通过,版本发布控制等环节介入。

  • 线下测试能力补充 单测和接口测试如何保证有效的发现真实问题,核心接口用例,自动查找上下游服务,安全等原子能力的建设

  • 线上监控 QA 牵头梳理现有监控即代码覆盖率的情况,保证监控指标的完整度,能否通过自助/辅助排查工具进行问题定位

将以上问题和建议进行整合,就会得到如下2点重要的事情

  • 研发流程规范
  • 线下 CI 能力建设

持续交付的实施步骤

  • 测试环境建设 在研发流程的构建中,第一步就是构建测试黄健,因为后续各种研发流程和 CI 能力建设,都需要在测试环境中执行才能发挥作用。

  • CI 能力建设 一种是寻找合适的平台,将平台提供的 OpenAPI 以及各类能力进行封装,另一种是自主研发。

  • 流水线标准化 早期,流水线由不同角色维护,这里统一改为由 QA 接口人维护,并将编辑权限进行收敛,同时为了适应多种开发场景,根据实际情况创建多种标准化流水线模板,并在各团队达成共识。

  • 制定流程规范 主要包括需求流程规范,研发流程规范,上线流程规范,规范用于说明在需求阶段,研发阶段,上线阶段分别要做什么事情,准入和准出的标准,以及三者的状态流转机制。

  • 合作机制 同上下游一同参与到持续交付的流程工作中,包括研发,业务 QA,架构,SRE,中台团队等。

  • 度量指标 这部分可见之前度量部分的阐述

综上,整体如下图所示 软件研发效能提升实践

基础构建能力 - 环境治理

在线下主要包括但不限于线下基准环境(develop 分支)以及线下功能环境(feature 分支) 软件研发效能提升实践

环境稳定性

  • 接口自动化测试实例覆盖率提升 因为后台接口的稳定是环境稳定的重要因素,通过对环境中服务的 HTTP, RPC 接口进行自动化测试,来确保整个环境中,服务的稳定。

  • Oncall 机制 环境负责人轮班 Oncall,保证业务和其他团队对于环境稳定性的需求,在遇到问题的时候,能够及时排查和解决。

数据丰富度

  • 核心业务落地 环境中服务错综复杂,如果只推进一个子业务落地测试环境,则这个子业务在测试过程中所依赖的其他服务智能通过 Mock 方式联调。所以,这里必须梳理核心依赖,从底层出发,推进服务整体落地在测试环境。(当然,云原生下,需要所有服务均能落地到所依赖的环境)

  • 数据构造平台 通过构造自动化测试中所需要的数据,例如 100万的粉丝,1000万的图数据数据,因此在某些情况下,测试环境需要能够有大量同步或者制造测试数据的能力。

底层集成能力 - 原子服务市场

  • 环境类
    包括测试环境的初始化,更新,回收,线上环境部署更新

  • 开发类
    包括开发阶段用到的能力,如创建代码仓库,编译库,依赖代码库配置

  • 测试类
    各类测试能力,包括静态扫描,接口测试,安全测试,数据测试,性能测试等

  • 上线类
    如创建工单,审核单,集群选择,单机房升级,全流量升级

  • 工具类
    在环境,开发,测试,上线这四个阶段都会使用的通用能力,如通知 BOT,人工卡单,状态同步,Webhook,拉群周知等

软件研发效能提升实践

中层调度能力 - 标准化流水线

分支主干模式

一般研发模式是双主干研发流程,即 研发主干 + 发布主干,一些公司是 develop 分支 + release 分支,或者 develop 分支 + master 分支 软件研发效能提升实践

流水线总览(环境总览)

软件研发效能提升实践

软件研发效能提升实践

上层通用能力 - 研发流程规范

全流程

  • 需求流程规范
    • RD 在需求平台建立需求工单,填写服务、分支、环境标识等信息。
    • 需求平台自动调用效能平台部署相关流水线,进行自测环境部署并附加
    • 每次代码 push 会触发代码仓库的单元测试和静态代码扫描检测能力
    • 在自测流水线测试完成后, RD 通知 QA 进行测试
    • 在QA测试和 CI自动化测试都通过后,才可以合入代码进入主干部署

软件研发效能提升实践

  • 研发流程规范
    • 执行步骤
      • 在将代码合入 master 后进行触发
      • 编译最新代码,执行测试环境部署
      • 执行CI检测能力(接口测试、安全测试和代码覆盖率)
      • 在基准环境部署成功和 CI 检测通过后才可以进入发布上线环节
    • 准出标准
      • 接口测试通过率 100%
      • 安全测试通过率 100%
      • 代码覆盖率 80%
  • 上线流程规范
    • 执行步骤
      • RD 点击通过人工卡点,以确定本次代码需要部署上线
      • 触发上线部署各个节点:小流量、单机房和人工卡点
    • 准出标准
      • 升级完成后至少观察大盘10分钟
      • 自动化测试通过

度量指标

交付效率

  • 交付效率(需求)
    主要关注需求阶段的需求吞吐效率,包括需求落地平台数、需求交付周期、需求交付吞吐量,以此衡量业务团队在需求维度上的事件处理效率
  • 交付效率(开发)
    主要关注开发阶段的相关指标,对应的角色是 RD,包括代码提交次数、服务接入测试环境概率、每次提交行数等
  • 交付效率(测试)
    主要相关角色是 QA 和 RD,主要关注测试阶段的相关指标,包括测试用例数量、CI测试任务执行时长、漏洞解决时长等
  • 交付效率(上线)
    上线阶段会对每个工单进行审查,查看步骤是否符合规范,包括使用功能环境进行测试比例、使用流水线部署环境比例等

交付质量

  • 交付质量(需求)
    主要关注需求评审阶段的需求通过率和变更率
  • 交付质量(开发)
    主要相关角色是RD, 关注技术方案评审通过率、代码提测成功率、代码提测打回次数分布、自动化任务执行成功率、RD自测时的环境稳定性
  • 交付质量(测试)
    测试阶段的指标分为过程指标和结果指标两种
    • 过程指标
      如接口自动化的覆盖率、单元测试接入率和指标卡点的开启率、静态代码检查接入率和卡点率、安全测试接入率、代码覆盖率等;也可指做事的过程,用来衡量业务各项能力接入的程度
    • 结果指标
      可理解为“功劳”,指接入过程指标中对应的各项能力,能真正保证质量,为业务带来真实收益,如接口自动化测试线下问题拦截率、单测问题拦截率、静态代码检查问题拦截率、安全测试问题拦截率、千行代码漏洞率等,用来衡量 CI/CD 能力接入后带来的实际效果
    • 交付质量
      上线阶段会关注部署次数,线上问题平均解决时长,上线的异常率,单位时间的线上问题数量等

软件测试效能提升实践

要想提升测试效能,首先要提升软件功能测试的效能,因为其是软件测试的核心。功能测试主要分为基于 API接口 的功能测试 以及基于 UI界面 的功能测试。具体实施的时候分为三类情况

  • 靠人工执行的全量功能测试
  • 手工测试+对核心功能以及主要的功能实施的接口和UI自动化测试
  • 测试左移 + TDD + 高覆盖度的接口及UI自动化测试

另外,对于自动化测试,需要先有设计好的测试用例,不用让测试开发者自由发挥,一边想用例,一边写自动化测试代码。因为这样不仅容易出现重复测试,或者测试遗漏,还很难计算测试覆盖率。
其次,如果能在开发之前设计测试用例,就可以使用这些用例实施 TDD 中的 ATDD (验收测试驱动开发),帮助开发人员更加深入的理解验收条件,并驱动开发人员开发出符合验收条件的软件系统。 当然,对于自动化测试,当测试人手不足,后者项目频繁变化,亦或者是项目前期的时候,大多采用全量的手工测试或者少量的自动化测试,当项目周期已经比较长,并且稳定迭代后,在测试人员充足的情况下,则要采用高覆盖度的自动化测试。一般情况下越早实施收益越高,当时收益高的前提一个之前所说项目是否合适,以及测试人员有足够的时间,另外一个则是要有高质量的自动化测试框架,避免因自动化框架导致的技术债,从而导致维护困难,投入产出比失调。
最后,对于 探索测试 则是因为很难被度量,所以它的作用并没有被管理者重视。在敏捷开发周期中,探索性测试是必不可少的组成部分,并且贯穿敏捷软件开发的整个生命周期。如果想有效的提升测试效能,测试左移,测试驱动开发,高效的探索性测试,适合团队的测试用例管理系统,以及全程持续化的测试流程等,也同样重要。

有效的自动化测试策略

首先,对于小规模的自动化测试,测试策略就是全做,而对于大规模的自动化测试,测试策略则极为重要,因为规模较大时,开发和维护的成本就和软件开发一样快速增加。其次,对于规模较大的项目,在大部分情况下测试资源都是不足的,需要对测试工作划分优先级和权重,如经典的测试金字塔模型、钻石模型等。这些模型都是在理想情况下的测试策略模型,而在真正的实践过程中,它们只能作为一个参考。在真实的项目中,我们需要根据不同质量需求的优先级、不同的资源情况、被测系统类型等因素定制自动化测试策略,从而可以更加有效地实施自动化测试。

  • 典型的实践模型
    目前,很多团队的自动化都是按照典型实践模型来实施的,因为资源和时间有限,往往迭代的末期都比较忙,特别是在自动化测试不足的时候,所以在很多情况下,迭代1的探索性测试和自动化测试会放在迭代2的开始阶段补充。这样做的缺点是在迭代结束时可能无法交付迭代产出给用户,从而无法实现每个迭代的持续交付。因此,对于资源充足和技术能力足够的团队,还是建议在当前迭代完成所有的测试工作。 软件研发效能提升实践

  • 最佳的实践模型
    在理想的情况下,自动化开发人员的技能满足自动化测试开发,并且开发资源(包括人力资源和时间资源)能够保证当前迭代中所有故事卡的所有自动化测试开发完成,并且还要保证全量自动化回归测试全部通过。但是在实际情况中,往往会出现开发人员技能差和开发资源不足等情况,因此需要根据实际情况选择并定制典型、适用的实践模型来实施自动化测试。 软件研发效能提升实践

更好的测试实践

在众多测试实践中,最能有效地预防功能性问题,并且能帮助提升功能测试有效性的是测试左移和 TDD。测试左移主要是指将测试工作(如测试分析和测试设计等)在软件开发生命周期中向左移动到开发之前和业务分析工作中去,然后在业务分析和软件设计工作中,通过相关的测试实践去发现软件业务和软件设计中的问题,并修复问题,这样有助于设计出有效性和准确性更高的验收标准和测试用例。这样的验收标准和测试用例还可以用于驱动开发,从而可以有效地提高 TDD 的实施效率。而 TDD本身也是一种很好的测试和开发实践,首先,它有一种正确的软件开发套路,它通过测试先行,尽可能保证需求的正确性,并且在代码编写过程中通过正确的测试用例来确保代码的正确性,从而尽可能确保开发出来的软件能满足正确的需求。其次,它是一种正确的软件可视化设计方法,因为测试用例一定是在设计和编写出来后可以被阅读的,并且在编写代码的过程中执行测试,通过测试结果的红/绿(FailPass)可视化米判断代码是否满足需求。最后,它还是一种提高软件认知能力的方法,通过分析大量的业务知识,设计大量的测试用例,尽可能地深入理解被开发的软件,从而提高对软件的认知能力。
根据业界的定义和经验, TDD可以分为 UTDD 和 ATDD。在实施 TDD 的时候,需要根据项目的实际情况,如质量需求、技术能力及资源情况来选择。无论是选择UTDD 还是 ATDD,核心实践都是测试先行,并用测试驱动软件开发。 软件研发效能提升实践

成功实施 TDD 最为核心的两项能力是自动化测试开发能力和代码重构能力。其中,自动化测试开发能力是指熟练使用各种自动化测试框架,将前面设计出来的测试用例进行自动化。 UTDD 常用的自动化测试框架有 JUnit、Jasmine 等, ATDD常用的自动化测试框架有 Cucumber、Robot Framework 等。只有将测试用例自动化之后,才能快速地进行回归测试,从而进行代码重构。而良好的代码重构能力,是代码质量内建、防止代码腐化,以及保障代码易于维护的关键因素之一。 如果没有能力或者不愿意对代码进行重构,就很难持续实施 TDD。
在实际工作中,要想实践 TDD,首先要转变思维-测试左移,将测试用例分析、设计和实现前移到编写代码之前。这里的测试可以是基于代码单元的单元测试,也可以是基于业务需求的功能测试,还可以是基于特定验收条件的验收测试。其次要帮助开发人员,主要是帮助开发人员理解软件的功能需求和验收条件,帮助其拆分任务、思考和设计代码,从而达到驱动开发的目的。因此, TDD 可以帮助开发人员分析和理解需求,并且有效地减少过度设计,获得大量有效的测试用例(手动/自动),以及快速获得反馈,从而有效减少返工,提高代码的内在质量,最终提升研发效能。

探索性测试

背景

早在1984年, Cem Kaner 就提出了探索式测试(Exploratory Testing), 并首次定义它是 “一种测试风格,主要强调个人的自由与责任,让独立的测试人员可以持续地通过相关学习、测试设计、测试执行等活动来改善测试工作的质量”
到20世纪90年代, Cem Kaner 又在 Testing Computer Software 一书中第一次正式发布了探索式测试方法论,从此探索式测试正式进入测试领域,并且引起了业界的关注,很多测试人员也开始实践这种测试方法。
从 Cem Kaner 给出的定义可以看出,探索式测试的提出主要是为了解决当时测试成本高、效率低、僵化和墨守成规的问题。因此,探索式测试最主要的目的是节约测试成本,以最少的资源投入发现更多的缺陷与问题,从而实现快速测试,并获得较高的测试投资回报比。但是,当时定义的探索式测试最大的问题是难以知道测试过的用例,从而难以度量产出。
后来, James Bach 根据自己的理解重新定义了探索式测试,他将传统的测试行为分为 检验(Verification)和测试(Test)。所谓检验,就是使用确定的测试步骤或者测试脚本来检验系统,而测试则是通过对未知的探索、学习和实验等一系列科学手段,发现并设计出新的测试用例,最后执行这些测试用例来验证系统。因此,他认为真正的测试都需要探索,而探索式测试的核心是测试分析和测试设计,如果要度量探索式测试的产出,则应该和测试工作一样,度量测试分析和测试设计的产出,即测试用例。不过很多测试人员在实施探索式测试时并不会产出测试用例,导致探索式测试很难度量 。良好的、可度量的探索式测试需要产出测试用例或者测试点,其中测试用例也分为多种类型,一般探索式测试产出的用例会使用场景式(Scenario),而不是步骤式(Step),从而可以节约一定的成本。

当前现状

在瀑布式开发流程中,探索式测试一般都是在 功能开发完成之后,甚至在回归测试完成之后,在有额外资源和时间的情况下由测试人员专门安排时间进行的。如果没有足够的资源和时间,一般不会进行探索式测试。除了测试人员专门安排时间进行的探索式测试,还有由非专业测试人员进行的一些测试活动,是一种非专业性的探索式测试,如 Bug Bash、用户测试等。因为由非专业测试人员进行测试产出的测试用例都非常随机,重复度较高,有效性较低,所以很难度量测试的覆盖率和有效性。不过因为 Bug Bash 和用户测试的投入成本相对较低,所以使用也比较广泛。由专业测试人员实施的探索式测试,投入成本相对较高,并且很难度量产出,实施得并不广泛和深入。
在敏捷开发中,敏捷测试的实践核心是快速反馈,这与探索式测试中的快速测试不谋而合,并且敏捷测试中的很多实践和探索式测试相似,如注重测试分析和设计、避免烦琐的测试管理、不需要包含详细操作步骤的测试用例等。在敏捷测试中,非常注重探索式测试,不管是测试前移实践中对业务需求和验收条件的测试分析,还是 Desk Check 和故事验收中的快速测试,或者故事测试和系统测试中的探索式测试,都是探索式测试在敏捷测试中的实践。因此,探索式测试在敏捷开发中是非常重要的一个实践,能有效地发现各种问题。
当前,探索式测试之所以难以实施,是因为有两个最大的难点:第一个是难以度量产出和收益,在大部分项目中,管理层都不愿意对探索式测试投入;第二个是没有明确的实施步骤,测试人员难以系统化地实施,做起来感觉像随机测试,很容易迷失方向,不知道下一步该怎么做。不过,在敏捷开发的敏捷测试中,实施探索式测试有天然的优势,不管是实施步骤,还是度量管理,都十分适合使用探索式测试。
在敏捷开发的敏捷测试中,首先通过对业务需求和验收条件的测试分析,以及和其他角色的合作,设计出覆盖率更高、有效性更好的探索式测试用例;其次根据故事卡生命周期明确给出探索式测试的实施步骤,从而系统化地实施探索式测试;最后通过测试用例度量探索式测试的产出。

探索式测试的测试分析和测试设计

探索式测试最重要的是测试分析与测试设计,但是这两部分也最容易被忽略和误解。没有良好的测试分析和测试设计,不可能做好探索式测试,因此能做好探索式测试的一般都是测试经验和技能丰富的测试人员,因为只有专业的测试人员才能在短时间内很好地完成测试分析和测试设计的工作
除了明确的业务需求和验收条件,所有的测试用例都可以通过探索式测试得到,其中,基础的用例可以使用外延关联法得到,而高级一点的测试用例可以用系统风险法,以及其他测试分析与设计方法得到。但是资源都是有限的,我们不可能在一个项目中针对所有的业务都实施各种类型的探索式测试方法,因此笔者总结了基础的外延关联法和系统风险法,用以指导在常规情况下快速地实施探索式测试。

  • 外延关联法 根据已有的业务需求和验收条件,梳理每个需求验收点,并且通过扩展和打破这些需求验收点来设计测试用例,或者通过关联这些测试用例来进行测试,这部分用例大多数在高频高危探索区。

  • 系统风险法 通过梳理整个系统的所有业务场景和技术架构,找到最为重要且风险最高的场景和技术点,并测试这些场景和技术点是不是符合预期。这部分用例大部分也在高频高危探索区。

探索测试的执行

在传统的“瀑布”模型中,因为测试往往由独立的测试部门的测试人员在专门的测试阶段进行,所以探索式测试一般也在这个专门的测试阶段进行,但是在敏捷开发的敏捷测试中,没有专门的测试部门,专业的 QA 人员参与软件开发的整个生命周期,并在每个阶段都可以进行探索式测试,或者赋能其他角色,如 BA、 Dev 等,让他们自己做探索式测试。因此,在敏捷开发中,探索式测试可以由不同角色的人在软件开发的整个生命周期的每个阶段进行
软件研发效能提升实践

探索测试的产出度量

缺陷其实只是测试的副产物,测试用例才是探索式测试的主要产物。通过探索式测试中的测试分析和测试设计,可以产出相应的探索式用例,而这些性的测试用例就式探索式测试最为重要的产出,也是度量探索式测试的主要依据。

个人能力模型

在数字变革时代,作为一名软件研发工作者,我们应该具备哪些基本能力才能持续精进呢?
考虑到一个研发团队中有各种角色,这里的能力不聚焦在具体的专业技能上,如使用 java 编写代码,设计用户体验较好的软件。这些都式我们通过多年的工作和学习最终练就的技能。 能力不是技能,是能够帮助我们更好的获得技能,更有效的使用技能的东西。 胜任力模型就是围绕问题而设计的个人能力模型。通常研发工作者面对的问题都是复杂问题,针对复杂问题,胜任力模型认为需要三步:第一步是分析问题,寻找解决方案;第二步是对齐目标,获得关键支撑;第三步是实施方案,带领团队搞定。

软件研发效能提升实践

  • 第一步:分析问题寻找方案
    • 技术专长
      有意愿且持续不断的去加强对技术的掌握,努力虚招更好的方法来解决问题,提高效率和降低成本。在平时,要做到以下三点
      • 充分掌握专业领域内技术的最新发展和最佳实践
      • 理解技术和实践对技术专家型和非技术专家型的利益相关者的好处和限制
      • 在解决问题和通过正确的方式完成工作方面显示出强烈的紧迫感,显示出成效
    • 概念性思考
      通过使用一种整体性的,后者抽象的,或者理论性的方法寻找有效的解决方案,落实到行动有以下三点
      • 在不同或者看似不想管的场景中发现相似点,能用一个比喻或者类比来解释一种场景或者现象
      • 在一个复杂的场景中,可以快速的识别核心点,或者看到隐藏在表面现象之后的东西,这个能力就是洞察力
      • 能够用一个理论框架去理解具体的场景
  • 第二部:对齐目标获得关键支撑
    • 自信
      相信自己的能力可以取得成功,在明知存在潜在冲突的情况下,果敢的挑战他人,抛出问题,平时可以注意以下三点
      • 我可以:带着我心的态度,去面对挑战性的任务,这是自信最基本的要求
      • 我反对:当对某个决定或战略不认同时,敢于在对的时刻找到关键的人或者组织表达自己的观点
      • 我反馈:果敢的给出他人基于客观事实的坚定反馈
    • 交付客户成果
      明确向客户交付的最终成果,并对齐保持热忱,要想具备交付客户成果的能力,需要做到以下几点
      • 深刻理解我们的业务目标:让自己的成功与客户的成功保持一致
      • 与客户沟通,找出客户真正的需求和让客户满意的东西
      • 在需要按期或基于可用资源交付最好的成果时,应该给出不同的提案
  • 第三步:实施方案,带领团队搞定
    • 个人责任感
      给出对客户最有利的结果和对未来方向负责,这个能力需要我们做到以下三点
      • 愿意主动承担与客户效果相关的一切后果,并努力寻找方法做出不同的内容
      • 把注意力放在为推动事情发展做点什么上,而不是放在为什么没做到或遇到问题就职责别人上
      • 承认自己的错误和局限性,寻找并接受建设性的批评
    • 建立重点
      通过发展和交流局部目标来支持整体业务和技术目标的能力,与其相关的有以下几点
      • 通过行为把自己和团队的目标与业务的战略方向统一起来
      • 确保团队成员清楚自己的工作目标和业务目标的关系
      • 确保每个人都清楚并支持团队的工作目标:让团队成员支持工作目标,最好的方式是让他们自己去定义和选择团队任务,这样大家就会自然的理解和支持这个任务
    • 发展他人
      愿意委派责任,乐于与他人合作,并指导他人发展的能力,这个主要包括以下三点
      • 给他人提出基于行为的,具体的,有帮助的反馈
      • 给他人不住有效的任务以发展他们的能力
      • 发现并强化他人在个人发展上所作的努力和改进

结尾

提升公司的软件研发效能是一个系统性的命题,茹炳晟的《软件研发效能提升实践》这本书中除了关于研发,持续交付,测试,个人能力的阐述,还有很大篇幅是介绍如何进行度量,以及如何构建效能中台,这两部分在效能提升中也是非常关键的部分。 当前博客从书本的前11章节,针对重点章节进行概念整理。 在效能提升上,不能一味的照搬,需要通过这些概念,看到企业效能潜在的点,以及能够思考如何解决问题,提升效能。

Reference:
https://www.merico.cn/blog/improve-rd-effectiveness
https://portal.netobjectives.com/articles-public/test-driven-development-atdd-and-utdd/