为什么要使用软件验证?

软件开发往往比预期的要昂贵得多。有证据表明,在开发过程中越早发现缺陷,它对时间尺度和成本的影响就越小。在开发周期后期发现的错误会导致成本飙升,并危及系统的完整性和安全性,特别是在软件已经部署的情况下。

作者:Paul Humphreys, LDRA Ltd 二九年二月一日

软件开发往往比预期的要昂贵得多。有证据表明,在开发过程中越早发现缺陷,它对时间尺度和成本的影响就越小。发现较晚的bug

典型的软件开发生命周期遵循熟悉的瀑布过程。

在开发周期中,成本会飙升,系统的完整性和安全性也会受到威胁,尤其是在软件已经部署的情况下。显然,周密的计划、组织和拥有正确技能的团队都会有所帮助。

自20世纪70年代早期开始,顺序瀑布模型就被用作软件开发备选方案的框架。在这个模型中,每个阶段级联到下一个阶段,只有在前一个阶段定义的目标实现时才开始下一个阶段。

在实践中,当开发人员迭代地工作时,当用户测试系统的原型版本时,需求聚集在一起时,通常需要重新访问较早的阶段。由于这种迭代方法,在每个阶段和每个迭代中应用合适的验证和确认(V&V)技术就更加重要了。

需求

瀑布模型的第一步是开发系统需求。这一步涉及最终用户和开发团队之间的密切合作。通过确保需求被充分捕获,被很好地理解,并且被完整而明确地指定,可以获得很多好处。跟踪需求的形式化方法是基于对软件和硬件系统的规格说明、开发和验证的数学方法。

派生类IOFile继承了InputFile和OutputFile的属性,这两个属性都继承自File。

这些形式化的方法可以从使用普遍接受的符号到完全形式化的定理证明或自动演绎-一种通过计算机程序证明数学定理的方法。尽管使用形式化方法的成本通常将它们限制在需要高水平软件完整性的应用程序中,但某种程度的形式化规范为任何软件应用程序提供了好处。

设计

传统上,大型系统的设计遵循自顶向下的功能分解方法。系统被分解成子系统,子系统通过定义的接口传递数据和控制。子系统通常由许多程序模块或单元组成,每个模块都有许多执行不同任务的例程。

随着基于模型的设计策略的出现,许多验证现在可以自动化。单元测试,以前只应用于代码,可以在模拟中进行。给定特定的前提条件和一系列输入,可以检查输出和后置条件。甚至可以对模型进行仪器化,以便还可以检查中间条件,以确保通过设计的不同路径的正确性。很有可能因为错误的原因而通过巧合的正确性得到正确的结果。

实现

源代码通常为应用复杂的工具来验证和测试应用程序提供了第一次机会,而且它也是引入许多缺陷的地方。糟糕的编程实践和非正式的测试导致软件无法正确执行,并且难以理解和维护。虽然许多组织使用风格指南来促进一致性并鼓励更大的关注,但这只是安全关键系统开发人员所追求的遵从性的一小步。

通常,一个编程标准包含大量的规则和指导方针。然而,一个相对较新的编码标准,名为“10的力量:开发安全关键代码的规则”,已经由喷气推进实验室(JPL)设计,并且仅限于10个可验证的编码规则。理论上,一个小的、仔细选择的规则集更有可能被执行,并且仍然可以检测到导致软件缺陷的许多原因。

所分析的软件的感知质量将编程规则/指南分为:

  • 可移植性:这些规则强调了在不同的编译器中不同的编程结构。

  • 可靠性:这些规则暴露了可能影响性能或可靠性的不安全代码。

  • 可测试性:这些规则检测导致测试更困难的特性。

  • 可维护性:这些规则检测难以理解的特性,这些特性会影响更新或修订,比如标识符名称的冗余和重用。

  • 复杂性:这些规则突出了复杂的代码,以便可以对其进行简化,或者在修改时应该更加谨慎。

  • 风格:这些规则确保代码遵循相同的风格,并遵循公认的良好编程实践。

验收测试

在实现阶段的最后,软件单元作为子系统和完整系统的一部分进行集成和测试。一旦集成测试完成,产品准备交付给客户,最后阶段是验收测试。

验收测试是在软件用户的指导下进行的正式测试过程,以确定可操作的软件系统是否满足需求所定义的需求。每个验收测试都试图测试用户所要求的功能。这些测试与单元测试的不同之处在于,单元测试是由每个模块的开发人员建模和编写的,而验收测试是由客户建模甚至可能由客户编写的。

作者信息
Paul Humphreys是LDRA有限公司的软件工程师,负责LDRA静态分析器的持续增强。与他联系:paul.humphreys@ldra.com