- 易迪拓培训,专注于微波、射频、天线设计工程师的培养
嵌入式软件测试基础知识
何时停止测试?
最通用的停止标准(按可靠性排序)如下:
1.老板命令停止测试
2.新的测试周期找到的新缺陷少于X个
3.在没有发现任何新缺陷的情况下已经满足了某个覆盖阀限
无论你多么彻底地测试了程序,都无法保证找出所有缺陷。这引发了另一个有趣的问题:你可容忍多少缺陷?假设在极端软件压力测试过程中,你发现系统每进行大约20小时的测试就会锁定。你仔细地检查程序,但是仍无法找出这个错误的根源。这个时候你应该交付产品吗?
多少测试才“足够好”?这个我说不好。但遵循一些久经时间考验的规则总是好的:“如果方法Z预估Y行代码中的缺陷少于X个,那么就可放心地发布程序了。”也许有一天会出现这种标准。编程行业仍然相对年轻,还达不到类似建筑业那样的成熟度。
许多厚厚的建筑手册和大本规范是多年经验的结晶,它们可为建筑师、土木工程师和结构工程师提供按工期在预算内、建造一栋安全建筑所需的全部信息。偶尔虽仍会有建筑倒塌,但毕竟很少见。在编程行业制定出类似标准前,“多少测试才足够?”就是个主观判断问题。
选择测试案例
在理想情况下,你可能想要测试程序中每一个可能的行为。这意味着每一种可能的输入组合或者每一种可能的判定路径至少测试一次。
这是个崇高但完全不切实际的目标。比如,Glen Ford Myers在其《软件测试的艺术》一书中就描述了一个只用五个判定条件就可有1014个不同执行路径的小程序。他指出,如果你能够每五分钟就能编写、执行并验证一个测试例程的话,那么全面彻底地测试完这个小程序需要10亿年时间。
显然,理想的状况是无法实现的,因此你必须采用接近这种理想状况的标准。如你所见,功能测试与覆盖测试相结合可以提供合理的次优选择方案。基本方法是选择最有可能发现错误的测试(一部分功能测试,一部分覆盖测试)。
1.功能测试
功能测试一般称为黑匣子测试,因为在编写功能测试的测试例程时并没有涉及实际的代码。换句话说,没有触及到“匣子内”。嵌入式系统有输入和输出,并在输入和输出之间执行某些算法。黑匣子测试是根据对哪些输入应该是可接受的以及这些输入应与输出有何种关系的了解来进行的。黑匣子测试完全不了解输入与输出之间的算法是如何实现的。黑匣子测试的示例包括:
压力测试:有意使输入通道、内存缓冲器、磁盘控制器、存储器管理系统等过载的测试
边界值测试:表示特定范围内的“边界”的输入(例如,对于整数输入而言,是最大和最小整数以及-1、0、+1);以及应使输出在输出范围的类似边界出现跨变的输入值。
异常测试:能触发故障模式或异常模式的测试。
错误推测:根据以前的软件测试经验或者从测试类似程序获得的经验进行的测试。
随机测试:通常,这是效率最低的一种测试方法,但却仍然广泛用于评估用户界面代码的鲁棒性。
性能测试:由于性能预期是产品要求的一部分,因此性能分析属于功能测试的范畴。
由于黑匣子测试仅取决于程序要求及其I/O行为,因此一旦完成功能要求的编写,即可开发这类测试。这使得黑匣子测试例程的开发可以与余下的系统设计同步进行。
与所有测试一样,功能测试应被设计得具有破坏性,也即,要试图证明程序无法工作。这包括使输入通道过载、随意地敲打键盘,以及故意地做程序员认为会破坏其程序的所有事情。
作为研发产品经理,这是我的主要测试方法之一。如果产品在经过40个小时的极限测试(abuse testing)后,并没发现任何严重或者致命的缺陷,那么就可以发布这个产品了。如果找到了一个重大的缺陷,那么修正这个缺陷后,还必须重复前面的测试步骤。
2.覆盖测试
功能测试的缺点是其很少执行全部代码。覆盖测试则试图规避这个缺点,它采用的方法是(理想地)确保每一条代码语句、判定点或者判定路径都至少被测试一次。覆盖测试还可以显示已经访问的数据空间大小。
覆盖测试也称为白匣子测试或玻璃匣子测试,这类测试的设计需要全面了解软件的实现方式,也就是说,它要“看到匣子里面”。白匣子测试利用了源代码所能提供的方便。
白匣子测试充分借力了程序员对程序API、内部控制结构的知识,分享了程序员的异常处理能力。由于白匣子测试取决于具体的实现决策,因此要到应用代码完成后,才能动手设计这类测试。
从嵌入式系统的角度来看,覆盖测试是最重要的测试,这是因为只要你把握已在多大程度上对代码进行了测试,你就可很好地预警出现未发现缺陷的风险。白匣子测试的示例包括:
语句覆盖:选择的测试案例可以至少将程序中的每一条语句执行一次。
判定或分支覆盖:选择的测试例程可以使每一个分支(条件为真和假的路径)至少执行一次。
条件覆盖:选择的测试例程可以强制判定中的每一个条件(项)都包含所有可能的逻辑值。
理论上,白匣子测试可以利用或控制所需的任何对象来执行其测试。因此,白匣子测试可能使用JTAG接口强制设定特定的存储器值作为测试的一部分。实践上,白匣子测试可以分析逻辑分析仪报告的执行路径。
3.灰匣子测试
由于白匣子测试可以深入代码内部,因此与黑匣子测试相比,这类测试的维护成本更高。只要要求和I/O关系保持稳定,黑匣子测试就会一直有效;但每次修改代码后,可能都需要重新进行白匣子测试。因此成本效益最高的白匣子测试一般是那些在不深入编程细节的情况下利用实现知识进行的测试。
较少涉及代码细节的测试有时也称为灰匣子测试。当与“错误推测”配合使用时,灰匣子测试非常有效。如果你知道(或者至少猜到)代码中的弱点在哪里,那么你就可以设计出对这些弱点“施压”的测试案例。
因为这些测试覆盖了代码的特定部分,因此这些测试是灰匣子测试;因为这些测试是根据可能会出现哪些错误的猜测而选择的,因此这些测试是错误推测测试。
在整合新功能与稳定的旧代码库时,这种测试策略非常有用。由于代码库已经过全面的测试,因此将测试重点集中在新、旧代码交集处可以起到事半功倍的效果。
上一篇:利用SPICE仿真TEC温度环路PID控制
下一篇:测试平台上的阻抗测试方案