上一篇文章提到自定义静态扫描,这次我们来看看如何利用ANTLR在没有反射(reflection)特性的语言,比如C/C++,实现类似NUnit的C/C++ Unit。
2. 单元测试工具
反射能做很多事情,有些是依赖动态特性的,比如获得一个对象的类型信息;有些其实是静态特性,比如一个类型的成员、函数、属性,以及其参数返回值类型什么的。如果比较有反射的语言的单元测试工具,它们利用的其实是反射的静态特性部分,比如attribute的名字和参数,函数的参数返回值类型等等。这里就可以取巧了:ANTLR能得到的就是静态信息。
以C++的ANTLR语法文件为例,通过语法树遍历或者Listener可以找到functionDefinition语法对象,如果我们规定测试函数的返回值为void,无参数,那么所有具备这种特征的函数就可以加入测试函数的列表里面。这可以通过declSpecifier找到typeSpecifier、再找到trailingTypeSpecifier、再找到simpleTypeSpecifier、再找到Void从而确定这属于Void返回值的情况;无参数则通过declarator找到noPointerDeclarator分支、找到parametersAndQualifiers、通过空的parameterDeclarationClause从而确定这属于无参数的情况。
显然这个列表包含了更多不是测试函数的情况,所以就如同java或C#里面的测试函数需要添加[TestMethod]的attribute一样,我们也需要添加自定义的attribute。只是这里可要