敏捷开发及测试方法在安全级软件研制过程中的适用性研究
2018-10-27韩文兴瞿铭君余波蒋维
韩文兴 瞿铭君 余波 蒋维
【摘 要】安全级软件研制过程通常采用发展成熟的瀑布模式作为一种典型的生命周期模型,随着行业发展,软件规模不断扩大,复杂度不断加深,瀑布式开发方法的内在风险越来越明显地影响安全级软件研制的成本、进度和质量。在互联网行业兴起的敏捷开发模式,其新颖的思想维度、快速交付带来的价值、显著的效率提升,越来越广泛地被软件从业者接受和推崇。文中从根源上研究敏捷方法的思想,并与安全级软件领域的核心思想进行对比,探索二者的差异性和共同点,讨论敏捷开发及测试方式在安全级软件研制过程中的适用性。
【关键词】敏捷;安全级;瀑布模型;开发;测试
中图分类号:TK08 文献标识码: A 文章编号: 2095-2457(2018)16-0053-003
DOI:10.19694/j.cnki.issn2095-2457.2018.16.023
【Abstract】In safety software development, its usually fallowing waterfall method as there software life cycle model. With the development of the industry, software becomes lager and more complexity, and make the method of Waterfall Model display its short face clearly, such as more cost, slowly progress and inferior quality. In Internet field, there is a new development method called Agile that accepted by software engineers because its has special point of view and highly valuable of quickly ready to use and efficiently work. This paper briefly introduces the different between this two kinds of development model, and discuss applicability of Agile in safety software developmet.
【Key words】Agile;Safety;Waterfall Model;Development&Test;
0 引言
1970年,温斯顿.罗伊斯(Winston Royes)在他的论文《管理大型软件系统的开发》中描述了瀑布式方法论的阶段划分方法,从此“瀑布模型”因其被人们最容易掌握并熟练应用的线性方法成为一种被广泛采用的软件开发模型,其固定的阶段划分、严格的过程控制、详尽的文档和记录在安全級软件领域发挥着巨大的作用。但这种方法由于其本身的局限性,在大规模安全软件项目中暴露出估算困难、文档工作繁重、变更成本高昂、项目成功率不理想等问题。即使后续基于瀑布模型的线性方法变体模型:增量迭代模型(分段线性)和螺旋模型(弯曲线性),也不能充分解决问题。于是在2001年由17名追求卓越的软件开发人员共同与会并定义了“敏捷”术语,发布了敏捷宣言,创建了敏捷联盟,并从工作思想层面、项目管理层面、团队协作层面等全方位改进以瀑布模型为代表的传统开发模式。由此衍生出的极限编程、看板、Scrum等一列敏捷流派都在互联网行业引起一阵革命浪潮,其他软件行业领域纷纷效仿。与此同时,对于敏捷方法的普适意义、方法理念的合理性、工作有效性也一直存在相互对立观点的争论。
软件开发模型决定着软件研发过程的各项活动在什么样时机、以何种形式开展,必然影响最终的产出成果。由于安全级软件应用场景对于人身安全的重要性,将未经论证、存在不可控因素或者有风险开发模型贸然引入,即使存在较小的可能性会造成严重的后果和无法挽回的损失,也是难以让人接受的。那么,客观分析来看,敏捷方法究竟是否适用于安全级软件呢?如果适用,该如何引入?如果不适用,是什么原因导致不适用的?
1 根源上的差异
根据一些非正式的统计数据表明,绝大多的安全级软件均是按照瀑布模型开发,由于众所周知的原因,瀑布模型在开发过程中体现出良好的可控性、可预见性为软件开发管理者提供长效监督作用。在敏捷方法体系中,有的专注于实践,如敏捷建模、极限编程等,有的专注于工作流程如Scrum、看板等,有的支援需求规范和开发,例如自适应软件开发(ASD)、测试驱动开发(TDD)等,在核心内容上均源自于敏捷宣言及原则,其相关内容任何人都能够轻易获得。此处不再赘述,仅通过针对瀑布方法和敏捷方法在思想上的研究,客观分析其根源上存在的不同及各自的优缺点。
1.1 技术上的区别
瀑布要求自顶向下的设计方法,概要设计时充分考虑所有需求在后续工作中如何实现,选择较为稳妥和中庸的设计方案,这项任务对设计工作提出了比较高的要求,否则下一个和一些阶段会难以开展或无法开展。这种方法的好处是,在技术稳定和成熟的团队,前期优良的设计对顺利执行后续各个过程提供了极大地便利。同样问题也在于,对于技术上不够成熟的成长型组织,容错的空间较小,一旦出现难以逾越的障碍将会导致整个软件重构。
敏捷方法要求采用极低耦合度、高扩展性的设计方法,当前版本迭代周期(敏捷术语称之为一个sprint)内只设计一个或少数几个需求。剩下的在未来的sprint去设计和实现,努力做到各个功能和需求间相互不影响或尽可能少的影响。以期望实现sprint间的故障隔离,在某些方法论(如TDD)中,甚至采用至下而上的开发思路。好处是显而易见的,每个sprint仅有少量的设计工作,并不需要充分完全地、充分地考虑未来有哪些需要实现的需求,因为未来的需求可能是会变化的。每次迭代都能提供一个已经实现的功能集合,各个sprint之间可以清晰隔离故障原因。但在经过了长期迭代之后,可能会发现,高扩展性可能只是表现在形式上,实际上也许已经变成了一个软件群的组合。
1.2 对待变更的态度
瀑布模型的本质是一种可预见性的工作方法,而变更是不可预见的,都会发生在已制定的计划之外,因此是比较抗拒变更的,尤其是在软件项目后期阶段。一旦发生变更,就必须经过一系列的工序获得准许,并申请额外的资源、修订原项目计划来实现变更。罗伊斯博士在他的论文中早已经意识到,对于需求经常变化的软件项目来说,瀑布模型是不适用的。
敏捷方法本质的拥抱变更的,将变更项列在待办池中,安排在下一个或更加以后的sprint中实施,并通过短路径的反馈回路和适应周期,迅速修正负面反馈信息,在应对较为频繁变更的软件项目上,敏捷方法在效率上和用户满意度上体现出了其他方法无法比拟的优势。
1.3 对待流程的态度
瀑布模型强调流程规范的重要性,职责分工细致明确,有专职人员如QA来监督流程与实际执行的一致性,通过定义标准的输入输出接口、严格的流程执行力度,来降低因为个体犯错而导致某个环节活动失败的概率。强调以流程为核心的工作理念,因此意味着在一个软件项目尚未启动时,就需要预先将一系列的工作活动流程约定成章,工作效率及工作成果的质量高度依赖于流程制度的合理程度。
敏捷方法更加重视团队成员个体间的交流和互动。并把活动过程比作一场Scrum(并列争球)游戏,所有人以一种自组织的方式围绕同一目标努力,认为大部分流程和工具上的一切问题都可以通过面对面的、非正式的交流来达成一致,强调以人为核心的工作理念。但这种做法的问题在于,一方面要维持每个体间相互沟通的成本会随着个体数量增加而大幅增加,计算方式是N*(N-1)/2,曾获得计算机图灵奖的Brooks教授在他的著作《人月神话》一书中有详细的论述,尤其是对于分布式工作环境而言,要向每一个团队成员更新最新的信息也需要占用很大一部分工作量。另一方面工作成果的质量过于依赖于个体,会导致人为因素的错误可能会在软件研制过程中被不断地放大。因此,在成功实施敏捷方法的组织中,要求每一名团队成员都是经过训练的,具有相当丰富的工作经验。
1.4 对待文档的态度
瀑布模型相当依赖于详尽的文档,对于文档的规范要求、编写时机、内容细致程度、评审等方面都有严格的要求,并作为下一阶段工作开展的输入。文档一方面用于技术细节交流,一方面形成软件项目的过程记录,对于安全级软件而言,监管机构不能时刻监视软件开发过程,文档审查便作为监管的重要手段和内容。毫无疑问,详尽的文档工作必然大幅度降低开发人员的代码生产率。
敏捷方法看重的是交付可工作的软件,弱化文档的功能,以减少用于消耗在文档工作上的精力,集中并快速实现一个sprint周期的成果。工作效率显著提高,但问题在于,软件虽然是可用的,却难以提供证据向团队外部人员或组织证明软件是可靠的,尤其是在经过了多次迭代周期以后。
1.5 对测试的要求
瀑布模型中按照V字模型对开发工作的成果开展测试活动,各个阶段测试的對象、粒度、覆盖率均有规范的要求。对于安全级软件,执行测试的机构还有独立性要求,每个工作阶段达不到相应的质量要求变不允许进入下一个工作阶段。测试工作易于按部就班开展,对是否要求实现自动化并不在意。
敏捷方法采用一次次的sprint不停地发布可用版本,对于每一个版本都全量或增量的测试,因此要求实现持续集成和测试自动化,否则对于版本发布及测试工作而言就是地狱般的存在,值得庆幸的是,由于敏捷方法的推动,对持续集成方法和自动化测试技术的发展都有强烈的促进作用,但问题是,对于安全级的嵌入式软件而言,实现持续集成和自动化远没有其他领域那么容易。
2 一些优秀的敏捷实践
基于敏捷思想的方法和技术由于敏捷流派不同倾向,呈现出遍地开花的姿态,如水晶方法、动态系统开发方法、精益软件开发、测试驱动开发、探索性测试等、模型驱动的敏捷开发、敏捷建模、自适应软件开发、极限编程、Scrum等等,各自都声称自己是相关领域的优秀实践。此处无法一一列举,仅简单分析几个常见的方法,分析其核心思想,并探讨合理性及必要性。
2.1 以讲故事方式描述需求
把每一个需求以用户故事或场景的方式,简明扼要地以3行文字(As… I want… So that…)写到卡片上,这种实例化需求的方法虽然很好的表达了需要什么,但极易隐藏细节,例如:“作为一个核电厂业主,我需要一个仪控系统,来控制我的反应堆!”隐藏了细节的需求必然会导致向团队某个或多个成员解释真正的需求所隐含的真正内容。于是又回到了N*(N-1)/2条沟通路径的问题上。
在把需求经过拆分、变成了既有独立的,非常小的,具有外部价值的,可测试的用户故事之后,实际上已经完成了传统的运用格式化的和层级化的需求规格书所表达的内容。
2.2 结对编程
根据一些可靠的调查和研究表明,结对编程的实际效率虽然比两个人并行编程工作仅低了35%,但完成了非正式的代码评审工作,提升了质量的同时也加强了结对成员的交流,但一些观点认为,当在享受更多的不被打扰的自由空间和隐私空间时,人们才有最好的创意,另外,在安全级软件领域,即便代码通过了非正式的代码评审和单元测试,依然需要开展同行评审进行复审,因为结对编程虽然解决了两个人的共同问题,但并不能包含代码评审需要关注的所有问题。
2.3 测试驱动开发
将单元测试框架及测试代码、测试用例优先于软件代码完成,开发工作完成以单元测试通过为标准,严格来说这更像一种技术而不是方法,不仅要求开发和测试人员具有逆向思维的意思形态,掌握测试和重构,也还要懂得设计方面的知识。这也是所有敏捷实践中TDD最难实施的原因。根据一些针对TDD的代表性实践的研究发现,TDD确实能够降低代码缺陷密度,并提高测试的质量,但TDD并不能一直提高设计质量,虽然可以使类级和函数方法级的复杂度降低,但它给耦合内聚带来了负面影响,直接体现就是包级和项目级为之变得更加复杂,以至于无法有效地处理系统级的可靠性和安全性之类的问题,因为这些问题通常需要更加完善的模型。
更加重要的是,一组很好的测试用例不断更新并经常执行,这个与它在代码前写好还是代码后写好,本质上没有关系。
3 安全级软件的特点
以核电厂安全软件为代表,安全级软件具有以下特点:
a)标准符合性。软件研发过程需要符合IEC 60880以及IEC 61508等安全相关标准,必要时还需要响监管机构出具标准符合性分析报告。而标准文件中的虽然没有明确规定需要使用哪一种生命周期模型,但是对于研发过程,实际上是参照了瀑布模型的线性思维,对各阶段及活动的每一个环节提出具体要求。因此,如果严格按照标准要求执行,最好的思路仍然是采用线性的瀑布模型。
b)软件研发过程需要出具详尽的文档。对每一个研发活动环节,都需要向第三方独立验证与确认团队、监管机构证明软件是可信的。然而除了测试和鉴定以外,只有提供文档这一种手段。因此即使会很快过期的文档,作为一个过程的记录,对于安全级软件开发过程来说,也是不可缺少的。可以预见的是,如果将敏捷思想运用于安全级软件的研制过程中,文档工作量仍然不会明显地减少,届时,敏捷将失去其快速的意义。
c)具有严格要求的配置管理和质量保证活动,以监督软件研发过程完全受到控制。尤其是质量保证,由于敏捷方法讲究的自组织团队面对面沟通、弱化文档,使得软件工程中QA的评审、检查、追溯、证明等基于文档见证件的工作异常困难,几乎陷于无处入手的境地,即使敏捷方法的原始倡导者,也要求软件QA需要转变职能及工作方法,至于如何转变,也不能提出更好的方法。根据一部分调查报告显示,部分实践敏捷项目管理的组织将QA转变为Scrum Master,让QA抛弃警察角色而作为教练角色,但如此一来质量保证的工作性质是否还有拥有其原本存在的意义,可能也值得怀疑。
d)严格的变更控制。对软件的任何修改其本质是引入新的缺陷的过程,因此安全级软件出于对质量控制的原则出发,对变更的控制非常严格,对每一项变更不仅需要完成申请工序,还需要详细地分析变更产生的影响。由于敏捷方法运用持续集成和自动化测试,通过执行全量测试的方法确保没有引入新的缺陷,有效地隔离了每个sprint的故障源。所以并不在乎如何变更。在这方面,敏捷方法是可行的,前提是每个版本的全量测试能够切实执行。
e)明确的需求。大部分安全级软件(如核电厂DCS)的需求实际上是非常明确的,会产生变更的内容相对较少。因此,敏捷方法讲究快速响应变化的特点似乎并不能充分的发挥作用,反而在设计阶段考虑了所有需求如何实现的瀑布模型的开发方法更能体现有优势。
f)软件升级部署会受到非常严格的监控,更加注重安全性。一般而言,对于未完成的软件,是不允许部署在应用场景中,对于已经部署的软件,非必要的情况,也不允许任意升级。因此,快速交付可工作的软件只可能用于向用户演示功能及宣传用,在真实使用环境上只能部署经过完整验证的最终版本软件,因此敏捷方法中快速试错并纠正的理念,并不一定能在安全级软件中得到最终用户的认同。
g)软件的规模大。安全级软件的规模基本都在千万级金额以上,涉及上百人跨多个职能部门的团队分布式进行研发,更加注重有依据的技术信息传递,而技术文档就是一种技术信息的可靠载体。敏捷倡导的面对面的沟通确实能在小范围中发挥重要的作用,但对于大规模的团队沟通而言,流程和文档才是不容忽视的力量。
h)软件需要经过技术和管理完全独立的第三方团队严格的测试,并提供需求、设计、实现等工作的完整的追踪链和较高的可测试性,以保证测试的完整性和充分性。敏捷方法中运用大量的非正式化的交流,难以保存完整的跟踪证据链,使得第三方团队工作无法充分发挥作用。
i)服役时间长。一般而言,安全级软件的服役时间非常长,核电厂安全级DCS系统软件服役时间都是以10年计,这对软件的稳定性、可靠性和可维护性要求非常高,而完全用敏捷思想开发的软件由于其专注于软件“刚好够”的可用性及快速意义,便难以同时兼顾软件的其他特性。
4 开发模型的本质
对于敏捷从业者而言,敏捷方法不是一种方法或流程,而是一种思维模式。这是有原因的,大多数试图用流程的方式向敏捷方法转型的努力基本上都以失败而告终,要么回到了传统的瀑布模型,要么回到了无序不受控的工作状态。开发模型或者生命周期模型的作用,是为了使规模大、结构复杂和管理复杂的软件开发变得容易控制。瀑布模型将软件工程作为一个整体,横向切分层级;敏捷模型将软件工程纵向割裂成一次次的小型化的增量迭代,二者拥有各自适用的场景和条件,在各自的领域均能发挥重要的作用。瀑布模型让大型软件工程项目流程清晰过程可控,易于监管;敏捷方法让中小型软件快速升级迭代,不断试错,乐于变更。彼此思想上虽然存在较多的对立面,同时也是互补点。
5 结束语
软件的开发和测试工作是抽象和逻辑的艺术,正如Brooks教授所言,这个世界上没有银弹,敏捷方法也不是,完全套用在安全级软件的研发过程中,显然是不合适的。但这并不妨碍研究融合其中一部分思想和原则,降低一部分瀑布模式的不利因素,例如:在编码实现阶段用迭代方法分批次实现需求,迭代版本不用提交给用户,但可以提交给测试;测试虽然不用驱动开发工作但提前介入的思路却可以提高测试的充分性与完整性,不仅仅是对单元测试;利用看板展示进度和计划,既方便团队成员了解整体进展,有利于识别并合理安排闲置资源;利用燃尽图评估剩余工作量;以人为本的理念重视个体的创造性等;也许未来会存在一种经两者融合的新型的生命周期模型,即解决了瀑布模式面临的问题,也满足于安全级软件的生产需求。
【參考文献】
[1]Rober C.Martin.敏捷软件开发:原则模式与实践[M].北京:清华大学出版社,2003.9.
[2]IEC 61508-2.Functional safety of electrical/electronic/progr-ammable electronic safety-related systems [S].2010.
[3]Freder P.Brooks Jr.人月神话[M].北京:清华大学出版社,2015.4.
[4]Mark C.Layton.敏捷项目管理[M].北京:人民邮电出版社,2015.12.
[5]曲长利.测试驱动开发的应用研究[J].复旦大学.2010.
[6]Paul C.Jorgensen. 软件测试:一个软件工艺师的方法[M].北京:机械工业出版社,2017.11.