假设我有一个TCL API,如下所示:
namespaceXY::apiXY <value> -opt1 <value1> -opt2 <value2> -opt3 <value3>
此API在测试套件(即数千个测试)中使用(也可能不使用)。
如何检查我的API是否已被调用+测试(所有选项都已被调用/测试)。
非常感谢
发布于 2020-10-18 21:13:22
您可以在命令上设置执行跟踪。这样,命令的签名就不会改变。因此,如果有任何代码执行info args namespaceXY::apiXY
,您仍然会得到相同的结果。此外,错误消息也不受影响。
proc cmdtracer {cmd op} {
global cmdtracer
dict incr cmdtracer $cmd
}
trace add execution namespaceXY::apiXY enter cmdtracer
最后,您将得到一个cmdtracer
字典,其中包含命令被调用的每种方式的计数。您必须弄清楚如何检查是否所有选项都经过了测试。你的问题中没有足够的信息来为这一部分提供建议。
发布于 2020-10-19 15:56:57
请参阅@SchelteBron对覆盖命令的回答。
详尽地测试所有选项将是棘手的,因为它们可能都以复杂的方式进行交互,其中一些可能是互斥的(例如,想想标准的Tcl lsearch
命令)。但是,审计是否至少在您自己的命令中调用了所有选项,可以通过附加的仅审计探测来完成。检查它们的所有合理组合是一项手动任务;为此,您可能需要一个覆盖工具。
C命令中的审计选项
假设您正在处理一个使用Tcl_GetIndexFromObj()
解析选项名称的C命令(这是常见的,也是推荐的),并且您不介意存在线程风险(也很常见),那么这个想法很简单。在C代码中创建一个整数变量(可能具有文件作用域),使用Tcl_LinkVar()
将其绑定到Tcl变量,然后使用(成功的) Tcl_GetIndexFromObj()
调用得到的索引在该整数变量中设置一个位,表明该选项已被解析。
#ifdef AUDIT_OPTIONS
static int foobar_optionTracker;
#endif
// in the implementation function, called FoobarImpl here for sake of argument
int index;
if (Tcl_GetIndexFromObj(interp, objPtr, optionNameTable, "option", 0, &index) != TCL_OK) {
return TCL_ERROR;
}
#ifdef AUDIT_OPTIONS
foobar_optionTracker |= 1 << index;
// Theoretically should call Tcl_UpdateLinkedVar() here, but for audit-only its not important
#endif
switch (index) {
// ...
}
// In your command registration function
Tcl_CreateObjCommand(interp, "foobar", FoobarImpl, NULL, NULL);
#ifdef AUDIT_OPTIONS
Tcl_LinkVar(interp, "optionTracker(foobar)", (void*) &foobar_optionTracker, TCL_LINK_INT);
#endif
准备就绪后,您可以从Tcl测试控制代码中读取数组元素optionTracker(foobar)
,以查看自上次重置掩码以来,在foobar
命令中解析了哪些选项(假设您对位掩码满意)。只需将0
写入掩码,即可重置掩码。
请注意,在C中也有Tcl_GetIndexFromObjStruct()
,但是审计的覆盖率与上面的没有显著不同。
Tcl命令中的审计选项
在纯Tcl代码中,Tcl_GetIndexFromObj()
的等价物是tcl::prefix match
,但它不返回索引。相反,它返回可与switch
一起使用的完整选项名。使用完整数组最容易完成的审计。(这在道德上与C代码版本的功能相同,但适用于特定语言中的最佳工具。)
proc foobar {mandatoryArgument1 mandatoryArgument2 args} {
# Parse other things here, set up the TABLE of option descriptors, etc.
foreach option $args {
set option [tcl::prefix match $TABLE $option]
if {$::DoAudit} {
set ::foobarAudit($option) 1
}
switch -- $option {
# etc...
}
}
您可以使用array size foobarAudit
来计算实际使用的选项的数量,或者使用parray foobarAudit
来打印出实际使用的选项。
https://stackoverflow.com/questions/64412423
复制相似问题