《构建之法》第十四章 质量保证

来源:互联网 发布:手机理财软件安全吗 编辑:程序博客网 时间:2024/05/30 23:10

摘至 邹欣《构建之法》一书,以作学习之用

软件的质量

从浪漫的角度看软件开发,人们不禁想象软件团队一开始就理解了用户的需求,完美的分析文档如高屋建瓴般流出,软件工程师在此基础上开发了各种完美的功能,按时交付给用户;用户一用就觉得特别符合自己的需求,皆大欢喜!然而所有的软件都没有这么浪漫。读者可以问一下周围的亲朋好友,大家使用的软件质量如何?相信回答绝不是“浪漫”。

什么是软件的质量(Software Quality)?这个词应用非常广泛,在不同的语境中有不同的定义。下面是国际标准组织最近的定义:

Capability of software product to satisfystated and implied needs under specifiedconditions

这个定义都强调了软件要符合用户以及利益相关者的需求。有多种方式可以用来剖析软件的质量,关于这方面的学术论文也不少。

我们知道:

软件 = 程序 + 软件工程

那么我们可以套用这个公式,看看“程序的质量”和“软件工程的质量”如何影响软件的质量。就像下面这个公式:

软件质量 = 程序质量 + 软件工程质量


程序的质量

程序的质量体现在软件外在功能的质量。衡量软件的功能,基本的判断可以用“是|否”来判定,例如,一个字处理软件能否通过拷贝/粘贴与其他软件传递信息。进一步,可以用复杂的多维度特性的综合指标来衡量,例如,衡量一个搜索引擎的质量,业界通常用准确度(Precision)和覆盖率(Recall)的综合指标来表示。各种功能还有很多特性需要衡量,例如,网站显示查询结果的速度;订票网站能并发处理业务的吞吐量;支持同时在线用户的数量。程序的质量还有其他方面,例如用户体验的质量、国际化的质量和安全性的质量。


软件工程的质量

软件的开发过程有三个主要的特性:“好”、“快”、“便宜”。通俗的理解是“软件在功能、成本、时间三方面满足利益相关者的需求”。前面提到功能方面的质量与具体的程序相关,那么软件工程方面的质量就与“快”、“便宜”比较相关。一个团队也许可以靠一些特殊的办法来提高程序的质量(例如在交付之前通宵加班,或者在软件发布后,长期加班修复用户提出的问题),但是软件工程的质量需要长期的过程来提高。软件工程的质量体现在以下方面。

  • 软件开发过程的可见性(Visibility)
    我们看这个项目开发过程中的场景,下面的对话不能说明软件的功能如何(也许最后发现功能非常惊艳),项目的可见性是非常差的。不但是小规模、业余项目会出现这样的情况,大规模的专业团队也是如此。曾经有一个专业项目,每次领导问:还有多久就能发布?回答都是:只差三个月!但是在连续两年的时间里,回答都还是“只差三个月”

    领导:进度如何?

    答:可能快了。

    问:能看看演示么?

    答:嗯,不知道。可能到了项目的最后一天才能看……

  • 软件开发过程的风险控制(Risk Manage-ment)
    软件开发过程中有种种依赖关系,有些项目的进展经常被这些因素打断,例如:
    ① 有个模块由其他公司提供,但是没有交付,我们也无能为力;
    ② 哦,这个平台的开发难度远超预期,我们也没有办法,只有延长开发时间;
    ③ 程序重新选择架构之后,突然出现了许多问题,我们只好延长开发时间;
    ④ 项目组有个成员离职了,他负责的模块别人都不懂,只好重新招人培养,并推迟交付日期;
    ⑤ 服务器突发故障,所有源代码都丢失了,也找不到完整的备份,只好大大推迟交付日期。

  • 软件内部模块,项目中间阶段的交付质量,项目管理工具的因素
    软件团队开发的内部模块都不会交付给用户,但也要注意这些因素对最终软件质量的影响,例如:
    ① 内部模块经常崩溃,延误开发;
    ② 项目内部的里程碑实现质量太差,导致最终产品未能达到预期质量标准;
    ③ 项目管理工具太难用,太繁琐,速度慢;
    ④ 工具体现的软件工程流程与团队实际运作不符合;
    ⑤ 并不是所有人都使用项目管理工具(例如很多人不想用规定的工具来跟踪Bug)。

  • 软件开发成本的控制(Cost Control)
    成本包括时间和金钱等,例如团队眼看完不成预定任务,只好花钱请第三方帮助完成工作,从而付出巨大成本。

  • 内部质量指标的完成情况(Internal Bench-marks)
    团队会在项目启动时制定一些内部质量指标,例如测试用例的数量、测试自动化的程度、每日构建的速度、自动部署系统的效率、代码覆盖率、文档的质量,等等。事情一多起来,很多都顾不上了。低劣的内部质量,会对产品的外部质量产生深远的负面影响。


软件工程的质量

如何衡量既然软件工程的质量对最终软件的质量有举足轻重的意义,人们当然希望衡量一下各个机构的软件工程质量究竟如何,其中一套比较成熟的理论是CMMI(全称Capacity Maturity Model Inte-grated,能力成熟度模型集成)。资料显示,运用CMMI模型管理项目,不仅降低了项目的成本,而且提高了项目的质量和按期完成率。因此,美国在国防工程项目中全面地推广CMMI,规定在国防工程项目的招标中,达到CMMI一定等级的公司才有资格参加竞标。CMMI虽然源于美国,但在世界各地都得到了推广,并被广泛采纳。一些以外包为主要业务的公司非常重视CMMI的考核工作。CMMI目前已成为许多大型软件业者用于改善组织内部软件工程所采行的软件评估标准。

实施CMMI的意义
CMMI的实施能够提高企业的管理水平,降低企业的成本。经验表明,企业实施CMMI的投入都会得到丰厚的回报。CMMI有以下几个等级。

  • CMMI一级,初始级
    在这一水平上,企业项目的目标得以实现。但是由于任务的完成带有很大的偶然性,企业无法保证在实施同类项目时仍能完成任务。企业在这一级上的项目实施对实施人员有很大的依赖性。

  • CMMI二级,管理级
    在管理级水平上,企业在项目实施上能够遵守既定的计划和流程,有资源准备,权责到人,对相关的项目实施人员有相应的培训,对整个流程有监测与控制,并联合上级单位对项目与流程进行审查。企业在二级水平上体现了对项目的一系列管理程序。这一系列的管理手段排除了完成任务质量的随机性,保证了企业的所有项目实施都会得到成功。

  • CMMI三级,明确(定义)级
    在定义级水平上,企业不仅能够对项目的实施有一整套的管理措施,并保障项目的完成,还能根据自身的特殊情况以及标准流程,将这套管理体系与流程予以制度化。这样,企业不仅能够在同类的项目上成功地实施CMMI,在不同类的项目上一样能够成功地实施

  • CMMI四级,量化管理级
    在量化管理级水平上,企业的项目管理不仅形成了一种制度,而且要实现数字化的管理。通过量化技术来实现流程的稳定性,实现管理的精度,降低项目实施在质量上的波动

  • CMMI五级,优化级
    在优化级水平上,企业的项目管理达到了最高的境界。企业不仅能够通过信息化和数字化来实现对项目的管理,而且能够充分利用信息资料,对项目实施过程中可能出现的次品加以预防。企业能够主动改善流程,运用新技术,实现流程的优化。由上述5个级别我们可以看出,每一个级别都是更高一级的基石,要上高层台阶必须先踏上较低一层台阶。

CMMI有两种不同的实施方法,其级别表示不同的内容。

  • 连续式:主要是衡量一个企业在某一项目中的管理能力。它仅仅表示企业在该项目或类似项目的管理能力达到了某一级别。
  • 阶段式:主要是衡量一个企业的成熟度。就是说处于某一阶段的企业,实施大部分项目都要达到某一要求。一般地讲,一个企业要想在阶段性评估中得到三级,其内部的大部分项目都要达到三级,小部分项目可以在二级,但绝不能只有一级。

CMMI在传统软件企业中取得了不少成效,但是在以互联网业务为主的中小企业里,它的效果还有待观察。


质量的成本

要达到一定的软件质量,是要付出成本的。戴明环(Plan-Do-Check-Act/Adjust)也有一个专门的Adjust部分。这些成本有被动响应的(例如应付各种故障),也有主动行动的(例如投资于学习或预防)。SWEBOK特别定义了软件质量成本(Cost of Software Quality,CoSQ)的组成部分,其中包括预防、评审、内部故障、外部故障这四个方面,还要加上流程分析改进、投资改进等各种成本。

  • 预防(Prevention)
    为了防止事故的发生,软件团队要在改进软件流程、质量检测的基本建设和工具(例如投入人力物力设计和实现测试框架、测试用例、测试工具等等)进行投资,为了预防团队因人员变动而导致无人能理解老的程序和模块,软件团队要在培训、审核等活动上投入一定的时间。

  • 评审(Appraisal)
    为了评价质量的高低,团队要投入人力物力做复审(需求文档复审、代码复审、测试用例复审),以及软件测试工作,有些时候还要评价外部公司提交的软件模块的质量。

  • 内部故障(Internal Failure)
    在评审过程中发现的所有问题,都需要处理,这些处理的过程(改进文档、改进代码、改进测试用例等)都需要时间。

  • 外部故障(External Failure)
    软件发布到用户手里,或多或少会出现各种问题,处理这些问题的流程也需要成本。

  • 流程分析改进(Process Enhancement)
    一个项目里程碑结束后,团队成员要分析过去各个阶段的优缺点,并提出改进意见。团队经过讨论后决定实施合适的改进意见。

  • 提高职业技能(Enhance ProfessionalSkills)
    见“软件工程师的职业技能”一节,这些技能有别于“专业技能”。

  • 投资软件工具(Invest in Software Tools)
    开发、购买、定制、完善用于软件开发和软件工程管理的工具,并学习这些工具,争取发挥工具最大的效能。

举一个例子,某公司的软件工程师果冻说他只有20%的时间用来写新功能的代码,其他时间都花在了上述的软件质量成本:

  • 预防:参加培训,学习和应用新的测试框架

  • 评审:给同事做需求文档复审、Spec复审、代码复审,检查外包公司提交的软件模块的质量

  • 内部故障:忙着修复测试人员发现的代码错误

  • 外部故障:忙着调查和修复用户报告的错误

  • 流程分析改进:分析众多Bug产生的原因,忙着和队友讨论如何改进流程

  • 提高职业技能:参加一些学习班和讨论,琢磨如何提高自我管理能力

  • 学习新的工具:学习新的开发工具

磨刀不误砍柴工,每个软件团队都希望看到在“磨刀”上的投资能在“砍柴”上尽快得到回报。每一个工程师都愿意写新的功能,但也必须投入时间和精力去修复软件已有功能的质量问题。那么怎样才能提高程序的质量呢?这当然要设计师、项目经理、工程师以及测试人员一起努力才能做到。


软件的质量保障工作

从上面的叙述中我们不难看出,软件的质量保障(QA)和软件测试(Testing)是有很大区别的。然而,当前IT业界经常混用QA和Testing这两个名词,很多团队的QA/Testing工作是在较低水平上重复。这引发了一些相关的讨论。

  • 测试的角色(Test)要独立出来么?

  • 独立出来的测试角色怎么才能发挥作用?

  • 有些成功人士或公司认为独立的测试角色不应该存在,你怎么看?

首先,要明确两个概念

  • 软件测试(Test)
    运用一定的流程和工具,验证软件能实现预先设计的功能和特性,工作的流程和结果通常是可量化的。例如,测试用例、Bug、代码覆盖率、MTTF、软件效能的参数等等。正因为流程和结果是明确定义的、可量化的,很多测试工作可以自动化。

  • 软件质量保障工作(Quality Assurance)
    软件团队为了让软件达到事先定义的质量标准而进行的所有活动,包括测试工作。


测试的角色(Test)要独立出来么

首先,有分工是好事,软件团队中应该有独立的测试(Testing)角色。所有人都可以参与QA的工作(报告Bug什么的),但是最后要有一个角色对QA这件事负责。不但角色要独立,而且在最后软件发布时,必须得到此角色的签字保证(SignOff)。分工是社会和行业进化的结果,开发和测试其实是软件工程的两个分支,对于不同的软件/服务,测试的方式和程度都有所区别。独立的测试角色从用户的角度出发验证产品质量。独立专业的测试等同于代表客户对产品进行认证

我们经常使用的电子产品,从大彩电到电源插座,都经历了很多团队内部的和外部的测试。随手拿来一个电器,你会在背面看到密密麻麻的小字,其中肯定有下列标记之一:

这里写图片描述

没有这些标记的电子产品,市面上很少看到。我们也看到过新闻报道,说某消费者买了路边无质量认证的充电器给手机充电,结果发生爆炸的事情。

在软件和互联网产业,目前没有这些认证,相反的,倒是有“人肉认证”。你想申请某个著名专业网站的账户或者邮箱,但是又担心这个网站对用户信息的保护程度不够。有人说,没关系的,这个网站的创始人也在用,CTO、总监什么的还经常发安全相关的微博,账户一定是非常安全的!这里不存在独立的质量认证,只能通过人肉(创始人/CTO/总监)来认证产品的质量。

其实这种种“人肉认证”和幻想未必安全。从2011到2014年,我们就看到下列这些报道。

  • 2011年12月,CSDN等国内知名技术网站上百万名用户的登录名、密码及邮箱泄露,原因之一是使用明文密码。

  • 搜狐邮箱用户存在密码被重置的危险,原因之一是设计缺陷,申诉页面的源代码里存储了提示问题和问题答案。

登录一个网站时,如果网站有第三方的认证“此网站对用户信息的保护程度是X级,我们认证它不会用明文存储用户密码……”,我就放心了。在第三方认证出现之前,我希望团队内部至少有独立的QA角色,来确保软件的质量。否则我是不乐意使用这些软件或服务的。互联网服务的各种认证也在发展。


和测试角色相关的问题

有了独立的测试角色之后,是不是就万事大吉了?未必,分工意味着一件事要分给别人去工作。让别人做事,并且依赖别人做出的结果,这会出现一些问题。

问题1 既然有专人负责,那我就不用负责了!

生活中有一个常见的歪理:既然有清洁工,那我乱扔点儿垃圾算什么,这才是他们的工作啊!尽管有专人负责测试工作,但是保证质量仍然是所有成员的职责。软件团队中的一些人往往在有意无意中忘记这一点。最常见的现象是开发人员写好一个功能之后,迫不及待地宣布成功,然后希望测试人员去发现所有问题。如果问题在发布后才被发现,开发人员会说——测试人员怎么搞的,这种Bug都没找出来!?

一个开发人员应该负责下面“开发功能右边的几个圆圈呢?

这里写图片描述

问题2 盲目信任“专业人士”扮演的角色

每个角色的水平不一样,水平最差的角色往往对软件质量的影响最大。某团队要为自己开发的软件写一段英语介绍。团队成员都是通过四六级英语考试的牛人,可他们都很谦虚,非要请一个专业人士来写不可。于是找了一个专业人士,求了好几次(专业人士很忙的),在软件上市之前才拿到专业的文案,于是,几个人把文稿复制/粘贴几次之后,软件就向全世界发布了。这个文案第一句就是热情洋溢的设问句:“Haveyou ever think about …”随后还有几处非常明显的语法错误。这个软件吸引了不少评论文章,有旁观者说,从介绍文字的几处典型中国式语法错误(Have … think)来看,这个软件是在中国搞出来的……回头来看,我们可以问两个问题:

  • 这件事真的要专业人士来做么?

  • 专业人士做完之后,谁来负责测试?即使有专业人士扮演各种角色,还得有专人独立地检查验证质量。

问题3 为了自己的角色而做绩效优化

分工之后,每个角色为了自己的绩效而优化,会出现局部最优而全局未必最优的情况。我们团队的另一个Windows Phone的应用也要发布,这次专业人士又出手了,写了175个英语单词的介绍,极尽溢美之词,而且找不到明显的语法问题!这的确是一种局部最优了。但是专业人士完全没考虑到用户在小小的手机屏幕上有多少耐心读完那么多形容词和状语从句。经过简化,我们把它减少到78个词,勉强能放进手机的两个屏幕。
回头来看,不妨问问:

  • 这些事真的要让与项目无关的专业人士来做?
  • 向专业人士描述需求时,是否花了足够的时间让对方理解我们要的是什么?
  • 专业人士做完之后,我们要做什么样的QA?

问题4 画地为牢的分工
在一个长期而复杂的项目中,要求所有新来的成员,包括外包公司的新成员,在加入团队时,找到系统当前100个数据方面的问题,并用内部工具修复。我认为这能有效地让新人了解系统的复杂性、弱点和维护的流程。外包公司的员工很爽快地答应了,但是一些专家反而有不同意见。专家认为,外包公司的人是来做测试用例的设计,所以不必做其他事情,期望他们一上手就能设计出高质量的测试用例,不应该给他们那些低级的手工操作任务……

理论上这都是非常有道理,但是如果这些人没有亲力亲为地在这个项目中做一些具体的事情,他们怎么能“设计”出高质量、有实际意义的测试用例呢?

有时分工导致链条过长,信息丢失。一个开发者对自己写的程序有什么潜在问题还是很有感觉的,有些问题可以用文字表述出来(如果开发人员有耐心的话),有些问题是一些预感……现在都交给别人测试了,那好,让他们测吧,我也懒得说了。

分工还可能会导致一个软件的灵魂被切碎分给各个“角色”,每个功能都做得很卖力,但是整体就是不太行,明显看出来是费了老大的劲给强行“集成”起来的。

问题5 无明确责任的分工
分工之后,的确会产生很多问题。但是解决的方案是什么呢?是取消分工,让开发人员顺手做测试人员的事情,顺便把项目管理、美工、市场推广、客服都干了?显然不是。请注意我们提到了“角色”,角色是由人来扮演的,如果一人扮演了“开发”的角色,又能扮演“测试”的独立角色,这当然很好。但条件是他要以“独立”的心态测试,而不是想:“这代码就是我写的,哪会有什么错……”便草草了事。那么独立的测试角色怎么才能发挥最大作用?从上面的坏现象中,我们不难总结出来。其实MSF原则都讲到了。

  • 充分授权和信任(Empower team members)

  • 各司其职,对项目共同负责(Establish clear accountability and shared
    responsibility)

有些成功人士和成功的公司号称没必要设置独立的测试角色(Test),你怎么看?我猜想和踢足球类似,还是那几个原因:

  • 人太牛:不世出的天才,例如高德纳写书的时候发现排版软件不好用,就自己写了一个。也没听说他为这个软件项目请了什么独立测试人员。对了,他不读Email已经很多年,有秘书帮他处理这些事——这也是一种分工!

  • 事太小:“我写了个小类库,全部自己测试。”

  • 人不够:那就自己动手多做一些事情,也挺好。就像前面提到的,一个人扮演多个角色,只要能入戏就行。

  • 条件特殊:近年来,软件产业百舸争流,鱼龙混杂,在海里裸泳的弄潮儿也不少。在有些情况下(例如一窝蜂模式,主治医师模式),强力的Dev是可以搞定很多事情。运用之妙,存乎一心。


总结

分工是社会和行业进化的结果。开发和测试其实是软件工程的两个分支。不同的软件和服务需要不同方式和程度的测试。独立专业的测试角色等同于第三方代表对产品质量进行检测和认证。那么,一个团队应该如何培养和安排各个角色呢?

  • 在初始阶段(新项目,团队进入一个新领域,人员刚进入一个项目),每个团队成员都要尽量打通各个环节,多负责,把所有事情都搞懂,培养通才

  • 当项目/产业发展到一定阶段(进入阵地战的时候),要大力提倡分工合作,培养专才

  • 做好自己项目的架构和流程,让所有人都能比较轻松地开展质量保障工作。

  • 培养“大家都要做QA,专人负责量化的测试,有条件多做测试自动化”的文化。

  • 弄清楚自己项目的特点,人员的特点,产业特点。避免简单照搬别人的做法。不要听说某某伟大的系统的开发/测试比例是多少,就哭着喊着也要同样的比例……

0 0
原创粉丝点击