SWTBot工作机制:
让我们看看new SWTBot()的初始化过程,SWTUtils.primaryThreadGroup()静态方法首先从JVM内获取当前Thread的ThreadGroup的父ThreadGroup即JVM顶级ThreadGroup,然后SWTUtils.allThreads()从这个顶级ThreadGroup获取全部Thread,最后SWTUtils.display()静态方法利用org.eclipse.swt.widgets.Display.findDisplay(thread)遍历这些Thread来捕获当前display,只要这个display不Disposed,那么SWTBotFactory将新建ControlFinder和MenuFinder组成Finder,这个Finder利用org.eclipse.swt.widgets.Display.getShells()/getActiveShell()获取它的全部shell或当前活动shell来区配测试swt widget或menu。如何区配呢?
打开org.eclipse.swtbot.swt.finder..jar包,我们至少可以看到如下包层次:
org.eclipse.swtbot.swt.finder
org.eclipse.swtbot.swt.finder.finders
org.eclipse.swtbot.swt.finder.matchers
org.eclipse.swtbot.swt.finder.resolvers
org.eclipse.swtbot.swt.finder.utils
org.eclipse.swtbot.swt.finder.waits
org.eclipse.swtbot.swt.finder.widgets
在org.eclipse.swtbot.swt.finder.widgets包中提供swtbot widgets API,它对应包装swt widget并提供对这个widget的相应访问方法,如 本例中的SWTBotText 就是对应包装好了swt text widget并提供对这个text widget的访问方法setText,typeText等。在org.eclipse.swtbot.swt.finder.matchers包中提供12类mather API,可为查找swt widget提供相应的mather 方法或方法集:
1,WithText可以matcher有getText方法的swt widget。
2,WithLabel用来matcher特定的Label和CLabel widget。
3,WithId用来matcher控件的属性和值对。
4,WithMnemonic用来matcher有getText方法且会有助记符&的widget。
5,WidgetOfType用来matcher控件的类名。
6, WithToolTip可以matcher有getToolTipText方法的swt widget。
7,WithItem可以matcher有getItems方法的swt widget。
8,WithStyle可以matcher有特定样式的swt widget,如withStyle(SWT.PUSH,”SWT.PUSH”)。
9,WithRegex扩展withText用来matcher文本正则表示的widget。
10,InGroup可以在一个group内matcher swt widget。
11,InUIThread在一个UIThread内matcher另一个matcher。
12, AllOf用来定义matcher方法集来区配swt widget。
在org.eclipse.swtbot.swt.finder.waits包中提供widget wait API,waitForWidget利用SWTBotFactory构造的Finder在当前活动线程中macher控件。waitForMenu利用Finder在给定的线程中macher菜单。WaitForShell利用Finder在所有线程中macher指定线程。
这样我们只要先构造合适的macther,然后利用对应的wait方法且在一个合适的timeout及delay interal范围内来区配并等待测试成功,然后从这个macher的结果集中按照给定的index获取对应的widget,最后将这个widget构造为对应的SWTbot widget返回,利用这个SWTbot widget即可驱动swt widget来完成相应的GUI测试。SWTBotFactory提供了现存的timeout和相应的public方法waitUntil(ICondition condition),waitUntil(ICondition condition, long timeout)和waitUntilWidgetAppears(ICondition condition)。另外,SWTBotFactory和SWTBot中也提供一些指定的macther并包装为对应的SWTbot widget的公共方法,我们只须从SWTBot中调用这些现存的方法就可方便的找到对应的widget来测试,如本例中的SWTBotText t = bot.text("Hello World SWT", 0)即使用了下面text()方法:
public SWTBotText text(String text, int index) {
Matcher matcher = allof(widgetOfType(Text.class),withText(text));
return new SWTBotText((Text) widget(matcher, index), matcher);
}
此方法引用了SWTBotFactory.widget(matcher, index),一个通用的waitForWidget及timeout的wrapper。如果现存的方法不能满足我们的要求,那么可以订制自己合适的macther并类似下面新建一个SWTbot widget即可:
Matcher matcher = allof(widgetOfType(Text.class), withText(“Hello World SWT”), withStyle(SWT.MULT, ”SWT.MULT”));
SWTBotText t = new SWTBotText((Text) bot.widget(matcher, 0), matcher);
如果现存的timeout不能满足我们的要求,那么也可以订制自己合适的timeout或自己认为合适的timeout及delay interal的wait测试方法,如text()方法改写为:
public SWTBotText text(String text, int index) {
Matcher matcher = allof(widgetOfType(Text.class), withText(text), withStyle(SWT.MULT, ”SWT.MULT”));
WaitForWidget<Widget> waitForWidge = waitForWidget(matcher);
bot.waitUntil(waitForWidget,8000);//CustomWaitUntil(condition, timeout, interal)
return new SWTBotText((Text) waitForWidget.get(index), matcher);
}
对org.eclipse.swtbot.eclipse.finder..jar包,它们具有以上同样的机制,只不过支持的测试对象扩展为 eclipse 控件,最新的SWTBot 2.0.0.433版本还提供了对widget keyboard支持org.eclipse.swtbot.swt.finder.keyboard 。