Testing Tcl/Tk-自动化GUI测试

Testing Tcl/Tk-自动化GUI测试,testing,automated-tests,tcl,tk,gui-testing,Testing,Automated Tests,Tcl,Tk,Gui Testing,我想自动测试我的GUI。我已经完成了以下内容,但是如果有人能为下面的示例发布一个测试代码示例,我会更容易理解 下面是我的简单helloworld代码 名称空间评估Gui{ } procGUI::hello{}{ 顶层,你好 wm标题。你好“你好” wm可调整大小。您好0;#不可调整大小 #创建一个框架来保存检查小部件 设置f[frame.hello.boolean-borderwidth 10] 套装$f-侧边上衣 #确定和取消按钮 button.hello.ok-文本“ok”-命令[列表Gui

我想自动测试我的GUI。我已经完成了以下内容,但是如果有人能为下面的示例发布一个测试代码示例,我会更容易理解

下面是我的简单helloworld代码

名称空间评估Gui{
}
procGUI::hello{}{
顶层,你好
wm标题。你好“你好”
wm可调整大小。您好0;#不可调整大小
#创建一个框架来保存检查小部件
设置f[frame.hello.boolean-borderwidth 10]
套装$f-侧边上衣
#确定和取消按钮
button.hello.ok-文本“ok”-命令[列表Gui::ok.hello]
button.hello.cancel-文本“cancel”-命令[列表Gui::cancel.hello]
打包。你好。取消。你好。好-右侧
bind.hello{Gui::Ok.hello;break}
bind.hello{Gui::cancel.hello;break}
}
procGUI::Ok{arg}{
集合x[列出“你好,世界!”]
估价$x
销毁$arg
}
进程Gui::取消{arg}{
销毁$arg
}
#-------------------------------------------------------------------
#Gui主窗口
#-------------------------------------------------------------------
proc Gui::初始化{}{
#构建包含菜单选项的框架
机架.mbar-卸压升高-bd 2
框架尺寸-宽度200-高度240
包装.mbar.mdummy-侧面顶部-填充x
#菜单选项
menubutton.mbar.command-文本命令-下划线0-menu.mbar.command.menu
包.mbar.命令-左侧
#命令选项下的菜单
menu.mbar.command.menu-tearof0
.mbar.command.menu添加命令-标签“Hello…”-命令[列表Gui::Hello]
}
#-------------------------------------------------------------------
#主代码
#-------------------------------------------------------------------
Gui::初始化

我想测试
Command->Hello…->好
并查看是否输出
Hello world。如果有人能发布一个模拟这些点击并自动测试的示例代码,那就太好了。

使按钮表现为被点击的行为的最简单方法是使用其方法:

当然,您还必须捕获调用的结果;当涉及到测试时,向stdout编写代码并不是世界上最有用的事情(除非您在另一个过程中包装了一个测试工具,并且……好吧,让我们把它当作更多的工作)。重新构造代码,以便在测试GUI部分时可以使用不同的后端,这将对您有很大帮助

也有可能在方法调用级别以下,直到开始伪造事件。这需要做更多的工作,因为你不能仅仅产生鼠标点击和按键;您还必须合成
事件,以便Tk的小部件能够正确地武装自己。下面是一个示例(
-当tail
将事件放在事件队列的末尾时):

事件生成.hello.ok-当
事件生成.hello.ok-当尾部
事件生成.hello.ok-当尾部
您甚至可以生成相对于顶层或整个根窗口定位的事件(尽管Tk只在内部传递;它不会将事件发送到其他应用程序,因为这样做相当粗鲁),但我建议如果您不需要这些位置,请将其删除,因为它们会使您的代码非常脆弱(通常不重要)比如详细的字体更改

祝您在测试GUI时好运。很难做好。通过在适当的地方传递脚本以配置为参数(在Tcl中做起来非常简单,相当于在其他语言中做的“模拟”之类的事情),使您的代码与后端分离,这将大大有助于您停止同时测试所有内容。这将有助于保持你的理智

namespace eval Gui {
}

proc Gui::hello {} {
  toplevel .hello
  wm title .hello "Hello" 
  wm resizable .hello 0 0 ;# not resizable

  # create a frame to hold the check widgets 
  set f [frame .hello.boolean -borderwidth 10] 
  pack $f -side top

  # OK and Cancel buttons 
  button .hello.ok -text "OK" -command [list Gui::Ok .hello ]
  button .hello.cancel -text "Cancel" -command [list Gui::cancel .hello ]
  pack   .hello.cancel .hello.ok -side right

  bind .hello <Return> {Gui::Ok .hello ; break}
  bind .hello <Escape> {Gui::cancel .hello ; break}
}

proc Gui::Ok { arg } { 
  set x [list puts "Hello world!"]
  eval $x 
  destroy $arg
}

proc Gui::cancel { arg } { 
  destroy $arg
}

#-------------------------------------------------------------------
# Gui main window  
#-------------------------------------------------------------------
proc Gui::initialize { } {
  # build the frame which contains menu options 
  frame .mbar -relief raised -bd 2
  frame .mdummy -width 200 -height 240
  pack .mbar .mdummy -side top -fill x 

  # menu options 
  menubutton .mbar.command -text Command -underline 0 -menu .mbar.command.menu
  pack .mbar.command -side left

  # menu under command options 
  menu .mbar.command.menu -tearoff 0
  .mbar.command.menu add command -label "Hello..." -command [list Gui::hello]
}

#-------------------------------------------------------------------
# main code
#-------------------------------------------------------------------
Gui::initialize
.hello.ok invoke
event generate .hello.ok <Enter> -when tail
event generate .hello.ok <ButtonPress-1> -when tail
event generate .hello.ok <ButtonRelease-1> -when tail