【发布时间】:2010-09-19 03:54:06
【问题描述】:
我最近一直在尝试为一些遗留代码创建单元测试。
我一直在采取使用链接器的方法来向我展示哪些函数会导致链接错误,查找源代码以找到定义并从中创建存根。
有没有更简单的方法? 是否有某种 C++ 解析器可以以某种易于使用的形式为我提供类定义,我可以从中生成存根?
【问题讨论】:
标签: c++ unit-testing parsing stub
我最近一直在尝试为一些遗留代码创建单元测试。
我一直在采取使用链接器的方法来向我展示哪些函数会导致链接错误,查找源代码以找到定义并从中创建存根。
有没有更简单的方法? 是否有某种 C++ 解析器可以以某种易于使用的形式为我提供类定义,我可以从中生成存根?
【问题讨论】:
标签: c++ unit-testing parsing stub
您可能想调查http://os.inf.tu-dresden.de/vfiasco/related.html#parsing。但是 C++ 解析很难。
另一方面,也许 ctags 或类似的东西可以提取类定义...
您也可以尝试编写自己的简单 (?) 解析器来从头文件生成类存根...
我试图给你一些指示。如您所见,问题并不容易。但希望您至少可以自动化其中的一部分。
【讨论】:
Gcc XML在一些项目中使用,如automatic FFI for Common Lisp. 它与 G++ 编译器相关联以生成表示源的 XML。从那里开始,任何 XML 处理工具都可以帮助您实现目标。
【讨论】:
abi-compliance-checker 工具可用作 C/C++ 头文件的解析器:
abi-compliance-checker -lib NAME -dump VER.xml -headers-only -xml -stdout > api.xml
VER.xml输入文件如下:
<version>
1.0
</version>
<headers>
/path1/to/header(s)/
/path2/to/header(s)/
...
</headers>
输出的api.xml文件包含结构化形式的头文件中的函数签名和其他信息:
...
<symbol>
<id>37348</id>
<mangled>_ZN7MWidget11qt_metacallEN11QMetaObject4CallEiPPv</mangled>
<short>qt_metacall</short>
<class>13749</class>
<header>mwidget.h</header>
<line>45</line>
<return>44</return>
<spec>virtual</spec>
<parameters>
<param>
<name>p1</name>
<type>4078</type>
<algn>4</algn>
<pos>0</pos>
</param>
<param>
<name>p2</name>
<type>44</type>
<algn>4</algn>
<pos>1</pos>
</param>
<param>
<name>p3</name>
<type>3905</type>
<algn>8</algn>
<pos>2</pos>
</param>
</parameters>
</symbol>
...
另请参阅有关api-sanity-checker 工具的信息,该工具可以通过分析头文件中的声明为 API 中的每个函数生成基本的单元测试用例。
【讨论】:
http://clang.llvm.org/ 看起来很有希望,但并不完整。
http://www.boost.org/doc/libs/1_36_0/libs/python/pyste/index.html 使用 GCCXML 为 C++ 代码生成包装器以连接 python。这证明GCCXML已经被用于类似的概念。
【讨论】:
如果您在使用 DWARF 调试格式(主要是 UNIX)的平台上,您可以使用 libdwarf 解析调试信息并提取有关所有内容(函数原型、类定义等)的信息。比 C++ 更结构化且更易于解析。
【讨论】:
doxygen 通常可以解析足够多的 C++ 来为代码创建文档。它还有一个 XML 输出选项。
【讨论】:
Eclipse CDT 项目提供了一个高级 C++ 解析器。界面非常简单。 下面的代码 sn -p 可以给出足够的提示。
ITranslationUnit tu = CoreModelUtil.findTranslationUnit(file);
ICElement[] 元素 = tu.getChildren();
IStructure 结构 = (IStructure) 元素;
IMethodDeclaration[] 方法 = structure.getMethods();
IField[] 字段 = 结构.getFields();
【讨论】:
如果您使用的是 Windows 平台,您可能想查看Microsoft Phoenix project。它是一个新的编译器框架,可让您连接到编译过程的任何阶段。
【讨论】: