51Testing软件测试论坛

标题: xuexitcl1 [打印本页]

作者: ameg3    时间: 2009-12-9 16:41
标题: xuexitcl1
问题2: 如何加载测试用例——TCL脚本


问题回答:

方法一:从类似Tclsh的交互界面加载
1.从交互界面逐条输入测试脚本的内容;
2.从交互界面使用source命令来执行一个脚本文件,该命令格式如下:
             source filename
如果我们在c:\tcl下有一个脚本文件example.tcl,我们就可以这样执行这个文件
      %source c:/tcl/example.tcl           //注意这里不是用'\',而是用'/'

方法二:在代码运行中自动加载
1.使用Tcl_Eval函数求脚本script的值并返回执行情况,结果和错误信息保存在interp->result中;
原型: int Tcl_Eval(Tcl_Interp *interp char *script)
示例:
{
    int code;
    ......
    code = Tcl_Eval(interp, "set a 2;puts $a\nset b 3;puts $b");
    if (code != TCL_OK)
    {
        printf("Eval Script Error!");
        return TCL_ERROR;
     }
    ......
}

2.使用Tcl_GlobalEval函数中在全局层次上求脚本script的值并返回执行情况,结果和错误信息保存在interp->result中;
原型:int Tcl_GlobalEval(Tcl_Interp *interp, char *script)
   
3.使用Tcl_EvalFile函数求脚本文件Filename中脚本的值并返回执行情况,结果和错误信息保存在interp->result中;
原型:int Tcl_EvalFile(Tcl_Interp *interp, char *fileName)
实例:
     code = Tcl_EvalFile(interp,"c:/tcl/example.tcl");
作者: ameg3    时间: 2009-12-9 16:42
标题: xuexiticl
问题3: 如何将TCL脚本的执行结果输出到文件或屏幕上?


问题回答:

方法一:在代码中将结果输出至类似Tclsh的交互界面

使用C\C++编写TCL扩展命令过程时,一般可以通过把interp->result指向一个字符串或使用 sprintf  函数来设置命令的执行结果。但是interp->result的缺省大小只有200字节,如果命令结果太长就会出错,因此TCL提供了以下库函数来供用户管理命令结果:
        Tcl_SetResult 函数
        Tcl_AppendResult 函数
        Tcl_ResetResult 函数
其中,使用Tcl_SetResult函数将先清除interp->result中原来的值,故如果你想输出所有的命令结果请使用Tcl_AppendResult函数。



方法二:在脚本中使用puts命令将结果输出至文件

#打开文件,写出到文件的示例
#使用添加的方式打开当前目录下的文件testfile.txt
set     filehandle [open testfile.txt a+]

#写出字符信息到文件
set     info "This is test info..."
puts    $filehandle $info

#将缓冲中的内容写出到文件,如果不使用这条语句,只有关闭文件的时候才会真正的写到文件
flush   $filehandle

#关闭打开的文件
close   $filehandle
作者: ameg3    时间: 2009-12-9 16:43
标题: xuexitcl
问题4: 书写TCL脚本时的注意事项


1. 一个TCL脚本可以包含一个或多个命令,命令之间必须用换行符或分号隔开;TCL的每一个命令包含一个或几个单词,单词之间必须用空格或TAB键隔开。


2. TCL脚本中的注释符是'#',但'#'必须出现在TCL解释器期望命令的第一个字符出现的地方才被当作注释。
%#This is a comment
%set a 100  #  Not  a comment
wrong # args: should be "set varName ?newValue?"
%set b 101 ;  #  this is a comment
101


3.‘{’:在控制流if、while、for、foreach、switch和过程proc中,‘{’一定要写在上一行。 因为如果不这样,TCL 解释器会认为if命令在换行符处已结束,下一行会被当成新的命令,从而导致错误的结果。
    if {$x>0} {
      .....
     } elseif {$x==1} {
      .....
     } else {
      .....
     }


4. 命令置换[]:如果我们希望某个命令的结果作为另一个命令的参数,我们可以把这个命令及其参数用‘[]’括起来,TCL解释器遇到‘[’后就会把随后的单词解释成命令名,并调用相应的命令过程。
    % set c [expr 2+3]
    5


5. 如何正确获取List中元素的个数
    % list 1 3 5 7
    1 3 5 7
    % llength list
    1
    % set a [list 1 3 5 7]
    1 3 5 7
    % llength $a
    4


6. 使用while语句时必须是如下格式:
          while {condition} { body }
如果将红色标注的{}换成" "或是( ),将进入死循环。

不过,在使用" "或( )包围条件参数的情况下,也可以通过在body中加入break或continue等退出循环的条件判断语句来变通
的限定进程在满足某条件时退出while语体;如果不加入类似限定条件,就会陷入死循环。

例如下例在执行时就会陷入死循环,如果在body中加入"if {$x >6}  break"语句则不会如此。特此说明。
    % set x 0
    % while ($x<5) {
      incr x
      puts "x is $x"
      }
修改方案:
    % set x 0                           或      % set x 0
    % while {$x<5} {                            % while ($x<5) {
      incr x                                    incr x
      puts "x is $x"                    puts "x is $x"
      }                                 if {$x>6} break
                                                }


7. 空格问题:在编写TCL脚本的时候,除了要注意语法,格式上也要特别当心。比如很多时候,其实只是空格惹的祸。
  a. 有些空格必不可少,如If {} { ;
  b. 有些空格不能多加,比如在上面的例子中,如果书写如下,
        % set x 0
        % while ( $x<5) {
          incr x
         puts "x is $x"
         if {$x>6} break
        }
     出现如下错误提示:
        wrong # args: should be "while test command"
作者: ameg3    时间: 2009-12-9 16:51
标题: xuexitcl
问题5: TCL扩展函数编写时需注意的一个问题


下面的问题就是在标准TCL中也会遇到,不仅仅是在单板TCL中。实际上属于编程的疏漏之一,但应该引起注意: TCL扩展函数中支持的参数分析函数中,暂无对U8类型变量支持的函数。实际上就是,如果想要将扩展命令的某参数解析为U8类型的,需要先当作int型数据进行接收,然后转换成U8类型即可。

典型案例:

案例来源:中试
一级分类:软件开发案例  
项目组:   8750单板软件测试
标题:    BoardTCL扩展函数编写时要注意的一个问题
关键词 : BoardTCL; BigEndian

案例描述:
    利用编写的TCL扩展函数命令apcinit [devNum]对APC芯片进行初始化,devNum的取值范围为0~3,但是实际的测试结果是输入的devNum值取0、1、2、3,都只能使第一片APC(devNum为0)初始化,即扩展函数接收到的devNum值总是0。

案例分析:
    在对应扩展函数Tcl_ApcInitCmd()中,devNum被声明为U8类型,对应源码如下:
U8 devNum

if (Tcl_GetIntFromObj(interp, /* INTL: Tcl source. */
  objv[1], &devNum) != TCL_OK)
{
Tcl_AppendResult(interp,"Expect devnum is an integer ",NULL);
return TCL_ERROR;
}

而函数Tcl_GetIntFromObj()的原型如下:
Tcl_GetIntFromObj(interp, objPtr, intPtr)
    Tcl_Interp *interp;         /* Used for error reporting if not NULL. */
    register Tcl_Obj *objPtr;   /* The object from which to get a int. */
    register int *intPtr;       /* Place to store resulting int. */

其中,参数intPtr为指向int类型的指针。
pSOS中int类型是32位的,LPUB板的CPU是MPC860,存储字序是BigEndian,即高字节存放在RAM的低地址。当我们在控制台将devNum赋值为2 后,devNum在内存中是这样存放的:
Address : +0 +1 +2 +3
00AA6E24: 00 00 00 02
通过函数Tcl_GetIntFromObj(interp,objv[1], &devNum),U8类型的变量devNum指向同一地址:0x00AA6E24,因此(U8)devNum得到的值为0。

经验或建议:
    当单板的CPU为Motorola系列时,在TCL的扩展函数中要将扩展函数的参数的变量类型要声明为int型。
作者: ameg3    时间: 2009-12-9 16:51
标题: xuexitcl
问题6: 如何用TCL的内嵌脚本命令处理字符串


    Philosophy of TCL:
        Anything is a string.

    TCL只有一个数据类型:串,所有的命令、命令的参数、命令返回的结果以及变量都是ASCII串。在TCL的内嵌脚本命令中,有许多命令都与字符串的处理有关,下面我们将给大家介绍做一下详细的介绍。


1. split命令:  //字符串分割
语法:split string ?splitChars?
把字符串string按分隔符splitChars分成一个个单词,返回由这些单词组成的串。如果splitChars是一个空字符{},string被按字符分开。如果splitChars没有给出,以空格为分隔符。例:
% split "how.are.you" .
how are you
% split "how are you"
how are you
% split "how are you" {}
h o w { } a r e { } y o u


2. scan命令://字符串分析
语法:scan string format varName ?varName ...?
scan命令按format提供的格式分析string字符串,返回匹配的变量个数,然后把结果存到变量varName中,如果变量varName不存在的话,TCL会自动声明该变量。注意,除了空格和TAB键之外,string和format中的字符及'%'必须匹配。
例如:
% scan  "some   26         34"    "some %d %d"  a b
2
% set a
26
% set b
34
% scan  "12.34.56.78"  "%d.%d.%d.%d"  c  d e f
4
% puts  [format  "the  value  of c is %d,d is %d,e is %d ,f is %d" $c $d $e $f]
the  value  of c is 12,d is 34,e is 56 ,f is 78




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2