前言
最近有粉丝在后台提问,咨询使用Testbed(TBrun)进行单元动态测试时报错的问题。这个问题比较常见,于是想着写下本篇文章,希望对遇到类似问题的朋友有所帮助。
问题描述
事情的经过大概是这样子的:
由于当时在工作比较忙,只简单分析了一下,给出了一个排查问题的建议,就没有下文了。今天相对空闲一点,就全面的排查分析一下,写下这篇文章,也是为其他朋友提供一个参考。
原因分析:
上面的图片是Testbed(TBrun)编译时打印的错误信息,报了非常多个error,初学者可能会被直接吓懵。观察一下会发现均为非常类似的错误,都是int8、int16、int32、uint8、uint32等等数据类型引起的。这种情况一般是编译器不认识自定义的int8、int16、int32、uint8、uint32等数据类型造成的,C语言当然没有这些数据类型,一般都是我们在编写代码时自定义的,比如"typedef unsigned char uint8;"、"typedef unsigned long uint32;"之类的,这是一个很好的编码习惯,可以明确数据类型的位宽,提高可维护性和可移植性。
那么这里为什么报这么多自定义类型的错误呢?推测一下,这些自定义类型一般都是在头文件中定义的,方便其他程序文件使用时,可以直接包含引用。这里不认识自定义类型,很可能是没有包含定义的头文件。那么问题来了,被测的软件工程一般都会在开发环境下编译通过后,才会拿来做单元测试,为什么开发环境下能编译通过,testbed编译却会失败呢?
可能存在以下几种原因:
1、实际的开发工程有配置预编译宏定义,而testbed未参照进行预编译配置,编译时宏展开与期望不一致,导致自定义类型的代码未被正确包含;
2、testbed中对头文件的包含路径未正确配置,导致头文件未被正确包含;
3、现在的编译器优化功能越来越强大,完整工程在开发环境下编译时,就算有些程序文件漏包含了头文件,编译器也能通过头文件的多重包含和优化,编译通过;而使用testbed进行单元测试时,一般只会选择被测的1个或多个.c文件,不会把整个工程的源文件选完,所以不一定能进行完全的头文件包含优化,造成编译失败。
4、这些自定义的类型在系统头文件中,而用"<>"括起来的系统头文件,testbed默认是不会展开的(默认设置如下图),造成编译失败。
解决方案:
首先模拟复现一下问题:
针对上面原因分析中的4种可能,逐一排查如下:
1、首先对照实际的开发工程中配置的预编译宏定义,排查一下testbed的预编译宏定义是否配置正确(参照下图打开sysppvar.dat文件添加预编译宏定义):
2、然后对照实际的开发工程中配置的头文件包含路径,排查一下testbed的头文件包含路径是否配置正确(特别确认一下有前面报错的自定义类型的头文件所在路径是否被正确配置)(参照下图打开sysearch.dat文件添加头文件的包含路径):
3&4、完成前面两步后,再重新编译试一次,如果还是编译失败,报同样的错误,那大概率是原因3或4造成的。这种情况可以采取直接手动添加代码的方式解决。
在TBrun的被测源文件视图下,选中被测源文件,在右键菜单中选择"View \ Edit Pre-Include Code",在弹出的代码框中直接添加代码,包含缺少的头文件,或者直接添加报错的自定义类型代码:
完成上述排查和处理后,问题解决,重新生成测试驱动、编译、执行即可:
总结
以上便是"使用LDRA Testbed(TBrun)进行单元测试编译时报自定义的数据类型错误"的排查过程和解决方法,不限于这个问题,其他类似问题也可以参考此排查步骤和解决方法,希望能帮助到遇到类似问题的朋友。也欢迎有其他问题的朋友继续与我交流,共同进步。