嵌入式单元测试技术

发表于:2009-5-31 14:05

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:未知    来源:网络转载

  对嵌入式系统软件进行测试是一项很有挑战性的工作。因为嵌入式系统的软件开发平台和最终运行平台是完全不一样的两个平台,开发者不可能在其运行平台上像在桌面环境那样执行测试程序。这些差异可以表现在这几个方面。在软件开发的时候目标硬件平台可能还没有准备好,软件工程师在访问硬件时可能会很麻烦,在开发环境下模拟整个系统存在困难性等。

  本文阐述了单元测试在嵌入式系统软件开发过程中的作用以及其如何帮助开发者解决上述问题。简要地讲,它提升了桩函数在宿主环境下或者仿真器中的作用。这使软件工程师在代码编写完毕之后就可以立即对其进行验证,即使此时目标硬件系统还没有准备好或暂时不能进行测试。这样,绝大部分的潜藏在程序中的逻辑问题都能够在早期被发现,软件工程师就可以迅捷地修复这些问题,而目标平台上的测试就可以注重于检测软硬件接口方面的问题。

  为何要对嵌入式系统软件进行单元测试?

  单元测试是检查嵌入式系统软件缺陷的最有效的一种方法,更确切而言也即在宿主机环境下或在仿真器上进行的API测试。这能使测试尽早开始并且最大程度地降低了测试工作对目标硬件平台的依赖性。嵌入式系统软件的单元测试的一个前提是能够让软件独立于硬件进行测试,这是由桩函数对目标硬件平台的模拟而实现的。在这种情况下,代码的绝大多数功能性测试都能够独立于目标硬件系统进行测试。这对嵌入式系统开发者而言有以下主要好处。

  1. 单元测试能让开发者在目标硬件平台准备好之前就开始测试周期,开发者可以直接在宿主开发环境下开始初始测试(而不需要目标硬件平台)。早期测试能够为开发团队发现并修复缺陷提供尽可能充足的时间。此外,早期测试还能将测试工作较平均地分配于产品开发的各个阶段中,从而避免将所有的测试工作留到产品发布之前才进行,为开发团队争取了充足的时间。

  2. 单元测试采取一种“各个击破”的策略,允许用户将复杂的系统分为相对较简单的准独立系统进行测试。测试工具能够管理模块之间的关联性并使用桩函数来模拟这些模块的行为。

  图1:使用桩函数,开发者可以模拟真实环境和程序之间的相互影响对程序的某个模块进行测试,而不需要目标硬件平台以及暂时还未完成的其它代码模块。在测试环境中,桩函数充当了为待测模块提供外部关联性桥梁的作用。

  在代码修改过程中保护代码完整性

  复杂系统的开发者最大的烦恼就是不能确定对代码的修改是否改变或破坏了程序的既有功能性。为了打消这些顾虑,用户可以创建一个基准单元测试套件来捕捉代码的既有功能性。如果用户希望检查相对于基准单元测试套件的改变,只需要对修改过的代码定期地运行该测试套件即可。因为单元测试能够独立地测试系统的某些代码,所以这样一组回归测试套件可以持续地执行而无论目标硬件平台准备好与否。这种测试并不排斥对整个程序进行测试的分离回归测试套件。

  这样的测试套件作为变更检测完全能够让用户确保如果无意间破坏了既有功能性能够被立即告知。当目标硬件平台准备好后,用户可以直接用宿主环境下的测试来验证代码是否会在实际的目标硬件平台上正确地运行。虽然代码在宿主环境下进行了回归测试,但是在目标硬件平台上还是需要进行一定的自动系统测试

  验证错误处理

  由于消费类产品的错误处理可靠性需求的不同,所以系统测试情景变得更加复杂了。因为不能精确地预测其使用情况,所以系统的设计和测试都不能基于某个特定的情况。相反这些系统必须经过广泛地错误以及未预期输入的验证,以保证这些输入能够被正确地处理。

  使用含有桩函数的单元测试同样能够大大地简化错误测试过程。总的而言,在应用程序这一层级来测试错误条件是一件相当耗时的事,因为将程序置于“正确的错误状态”需要准备相对复杂的输入数据并且同时要求程序在其大量的可能状态中处于相应的状态。与之形成鲜明对比的是,使用“错误模拟”方法来对某些函数进行错误处理测试则要简单得多。

  例如,测试一个含有输入数据错误处理机制的测试是相当简单的:

  float signalToNoiseRatio (float signal,float noise,MODE mode)

  {

  if (MODE_MEASUREMENT == mode)

  {

  …

  if (signal < 0 || noise < 0)

  {

  handle_bad_data();

  }

  }

  }

  在这种情况下,在测试程序中对handle_bad_data()函数的调用是很简单的,因为测试该语句是否受程序输入数据控制是很简单的。

  尽管如此,很多情况下控制语句并不直接受控于函数接口,而是取决于系统处于的特定状态,如下例所示。将系统置于该错误状态可能会相当复杂,甚至可能牵扯到让设备接口处于某些特定状态,所以测试用例中的这个条件就需要通过模拟来实现。

  float shutDown ()

  {

  if (uploadingData())

  {

  userMessage (“Cannot execute shutdown while uploading data”);

  recoverShutDown();

  }

  else

  {

  // shut down indeed

  }

  }

  使用支持“智能桩函数”(smart stubs)的高级测试工具,对于复杂错误条件的测试比其它方法就简单了很多。“智能桩函数”允许通过原始函数的桩函数以及通过实现某些必要的特定功能的方法来执行代码。实际而言,当被测程序明显没有处于错误状态时,其相应待测函数将被调用以模拟错误实际发生的情况,这就是“错误模拟”的意义。在上述例子中,对错误处理函数uploadingData()的测试需要其桩函数以保证至少让其返回一次“真”。

21/212>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号