unity 单元测试框架的工作原理,及隐含问题

unity 单元测试框架的工作原理,及隐含问题

unity 是 github 上的一个开源测试框架,能够很方便的移植到各种不同的嵌入式平台中。unity 的主要实现依赖 setjmp 与 longjmp 及 printf 函数。unity 的实现中将不同的测试情况封装为不同的宏,通过调用相应的宏就能够对输入条件进行测试。

在测试开始时,unity 会调用 setjmp 保存当前栈帧,然后执行初始化任务(如果 setUp 函数被重写),完成后执行测试函数主体。在测试函数中可能有数量不等的宏的使用。当一个测试条件失败后,unity 生成错误信息,调用 longjmp,以不同的返回值跳转到 setjmp 预先设定的位置,然后打印信息,继续执行其它的测试 demo。这也就是说当一个条件不满足后,该条件后边的代码将不会再执行,这符合测试的基础逻辑,但是在某种情况下可能会造成极其严重的问题。

首先 setjmp 与 longjmp 栈跳转函数本身就有潜在的问题。setjmp 保存的上下文信息中所有存储在内存中的变量都与 longjmp 调用后的值相同。在 cpu 或浮点寄存器中保存的变量将会恢复到 setjmp 调用时的值。如果你忽略了这点,而且你的程序恰好依赖这些存储在 cpu 或浮点寄存器中的变量,那么程序的执行将产生异常。

setjmp 与 longjmp 自身的问题被 unity 的测试代码继承,因此这也是 unity 中潜在的问题。不过除了这个问题之外,还存在着一种更为致命的问题,不过这个问题是完全可以避免的。

假设我们有一个测试主任务,我们在测试主任务的执行函数中依次调用测试函数来进行测试。当某个需要在子任务中执行的测试条件失败时,unity 将会调用 longjmp 栈跳转到 setjmp 的位置,而 setjmp 在测试主任务中执行,也就是说我们现在从一个任务直接跳转到了另外一个任务。这里存在的问题是子任务并没有被杀死,它只是暂时退出了 cpu ,不久之后它还能够再次执行,但该子任务后面的执行代码依赖前面条件的正确达成,因此就会造成各种异常的结果。

避免这种方式的方案也很简单——不要在任务之间执行栈跳转。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值