当开发人员和工程师测量嵌入式系统中的代码覆盖率时,他们可以提高设备的安全性和性能。嵌入式系统是无数日常设备中的基础性角色。未经检查的代码错误可能对业务不利,并具有潜在的危险。
开发人员和工程师应该了解代码覆盖率的重要性,以及他们可以采取哪些措施来提高测试过程中的代码覆盖率。
高代码覆盖率表明系统的大部分代码在经受测试。开发人员可能会发现他们的代码似乎没有错误且运行良好。但是,如果仅运行一小部分代码,则可能存在测试结果中没有显示出的隐藏错误或bug。因此,代码和测试的有效性都依赖于代码覆盖率,越高越好。
虽然并不可能总是达到100%的代码覆盖率,但出于多种原因,优先考虑更高的代码覆盖率是很重要的。
提高代码覆盖率最明显的好处就是能得到更高质量的代码和产品。较高的代码覆盖率意味着大部分代码都经过了测试。因此,产品发布时的bug将更少,从而带来更好的终端用户体验和更高的整体产品性能。
调查显示,89%的开发人员认为“未被发现的错误”会对业务造成负面影响。当代码覆盖率较低时,很可能有一些情况没有机会在测试用例中运行。其中包括可能导致程序运行失败或行为异常的不稳定的情况。
(来源:Shutterstock)
在某些行业中,测量嵌入式系统上的代码覆盖率是一个关系到用户安全的重大问题。在医疗、汽车和航空航天等领域尤其如此。在工业领域和具有较高风险的产品(如汽车或飞机)中,软件正变得越来越重要。如今,即使像物联网设备这样看似无害的设备也变得具有着高风险。
此类设备中的bug或故障可能会威胁到用户的生命安全,因此实现高代码覆盖率对于确保设备符合安全标准至关重要。从网络安全的角度来看,这一点尤其重要。例如,梅赛德斯-奔驰在2020年的头条新闻,当时黑客在一次安全大会上披露了许多的安全漏洞,这些漏洞使他们能够远程控制梅赛德斯-奔驰汽车。
幸运的是,这些黑客是安全研究人员,而不是恶意黑客。不管怎样,这是一个完美的例子,说明了实现高代码覆盖率在车辆等高风险设备中的重要性。对于应用程序或电子游戏之类的东西,开发人员可以等到用户报告bug后再修复它们。不过,这种方法并不适用于高风险设备。在这些情况下,等待用户遇到bug可能会严重危及其人身安全。
事实上,许多行业都有安全法规,要求开发人员满足某些测试标准,例如汽车行业的ISO 26262。高代码覆盖率是满足这些安全标准的一部分,表明系统的错误经过了彻底的测试。
更高的代码覆盖率可以带来更高效、更有效的代码测试过程。纠正bug对于开发人员来说可能很乏味,而反复返回以纠正遗漏的错误则更加乏味。高代码覆盖率可以最大限度地减少代码测试阶段漏掉bug或错误的可能性。
开发人员可以使用不同类型的覆盖率指标来确定测试时正在运行的是代码的哪些部分。例如,指令覆盖率指标将告诉开发人员其代码中的语句在测试中至少运行过一次的百分比。通过使用各种覆盖率指标,开发人员可以更加谨慎地为其代码选择测试,从而节省时间。
例如,程序可能具有较高的函式覆盖率和条件覆盖率,但分支覆盖率较低。这就提示了开发人员,他们需要运行更多的测试来跑代码中的if/else语句。
提高代码覆盖率说起来容易做起来难。开发人员和工程师可以使用一些关键策略来提高嵌入式系统的代码覆盖率。
节省内存空间是提高代码覆盖率的简单方法。运行代码覆盖率测试需要一些最低限度的软件和硬件资源,特别是内存。许多测量工具必须添加一些代码才能运行,例如计数器,这就需要使用一些内存空间。如果没有足够的可用内存,就不可能有效地测试代码覆盖率。
如果内存或其他计算资源有限,开发人员可以尝试使用占用资源较少的测量方法。有时,由于内存或其他技术限制,使用完整的32位代码覆盖率工具根本不可行。
在这些情况下,使用替代的测量工具可能更合适。例如,部分检测代码覆盖率的分析器可以小至16或8位。一些计数器可能具有更高的处理器需求,但所需的内存则较少。
开发人员可能会受益于边界扫描或片上调试的方法。这种方法无需添加任何新代码即可测试代码覆盖率。这意味着它不像其他分析方法那样需要多余的内存空间。
代码覆盖率可以指整个程序的一般覆盖率,也可以指程序中特定类型代码的覆盖率。使用特定类型的代码来度量是测试嵌入式系统代码覆盖率的一个好方法,因为它使开发人员能够查看他们的测试缺少哪些类型的代码。
代码覆盖率的主要层级是指令、函式、分支、循环和条件。一些标准只使用这些层级中的部分。例如,ISO 26262主要使用指令、分支和条件层级。在更复杂的代码层级中实现高代码覆盖率自然也会覆盖前面的层级。例如,在ISO 26262使用的层级中,条件层级的高代码覆盖率也将确认分支和指令层级的高覆盖率。记住这一点将会很有帮助,因为它可以简化测试的过程。
如果开发人员需要某一层代码具有较高的代码覆盖率,他们可以优先考虑对该层及其之上的所有代码进行测试。跟踪不同类型代码的代码覆盖率还可以发现代码的哪些区域没有得到测试,从而使开发人员能相应地调整他们的测试方法。
最后,考虑测试用例本身的质量也很重要。如果在程序上运行的测试无效,则代码覆盖率就没有意义。开发人员需要将高质量的测试与高代码覆盖率相结合。
事实上,Google的最佳实践强调了分析测试用例质量的重要性。具体来说,Google专家的指南指出,在代码覆盖率高的同时,测试覆盖率也可能很低。这意味着开发人员可能会被高代码覆盖率误导,而实际上他们的测试并未涵盖所有可能的情况。
代码覆盖率本身并不能告诉开发人员他们的程序是否运行良好,只能告诉开发人员有多少代码在测试中运行了。因此,要提高代码覆盖率,使其真正反映测试过程的彻底性,就必须确保使用高质量的测试用例。
花时间测试嵌入式系统上的代码覆盖率并使其尽可能接近100%,这将带来更安全、更高质量的系统。许多嵌入式设备在汽车、飞机和医疗设备等终端产品中发挥着至关重要的作用,在这些产品中,一个遗漏的错误就可能会危及到生命。对于确保嵌入式系统能满足OEM和终端用户所需的质量、性能和安全标准来说,努力实现高代码覆盖率至关重要。
(原文刊登于EDN姊妹网站Electronic Products,参考链接:Why code coverage matters,由Ricardo Xie编译。)