自动化中的同步和等待非常重要,在对象还没有准备好的状态下,如果进行下一步操作会导致自动化失败。下面以启动Windows7的计算器来举例说明UI Automation中常用的二种自动化同步和等待方式。
方式一:小时间片的轮询状态检查
class CalcAutomationClient
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); //NLog开源项目,用于记录调试日志
static void Main(string[] args)
{
AutomationElement calcWindow=null;
int timeout = 0;
string appPath = @"c:/windows/system32/calc.exe";
Process.Start(appPath);
AutomationElement aeDesktop = AutomationElement.RootElement;
AndCondition andCondition=new AndCondition(new PropertyCondition(AutomationElement.NameProperty,"Calculator"),
new PropertyCondition(AutomationElement.ControlTypeProperty,ControlType.Window));
while (true)
{
if (timeout == 5) //将超时时间定在5秒
{
logger.Trace("searching the calc window time out");
break;
}
else
{
logger.Trace("this is the "+timeout+"th time searching the calc window");
timeout++;
}
System.Threading.Thread.Sleep(1000);
calcWindow=aeDesktop.FindFirst(TreeScope.Children, andCondition);
if (calcWindow== null)
continue;
else
{
logger.Trace("found the calc window");
break;
}
}
logger.Trace("end");
Console.ReadLine();
}
}
方式二:Event Pattern
class CalcAutomationClient
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger(); //NLog开源项目,用于记录调试日志
private static AutomationElement calcWindow = null;
static void Main(string[] args)
{
//创建新窗口打开事件的回调,只有被测试程序窗口打开后,测试才开始执行
AutomationEventHandler eventHandler = new AutomationEventHandler(OnWindowOpenOrClose);
//注册监听事件
Automation.AddAutomationEventHandler(WindowPattern.WindowOpenedEvent, AutomationElement.RootElement, TreeScope.Children, eventHandler);
string appPath = @"c:/windows/system32/calc.exe";
Process.Start(appPath);
logger.Trace("end");
Console.ReadLine();
}
static void OnWindowOpenOrClose(object src,AutomationEventArgs e)
{
if (e.EventId != WindowPattern.WindowOpenedEvent)
return;
AutomationElement aeSourceElement=null;
try
{
aeSourceElement = src as AutomationElement;
if (aeSourceElement.Current.Name == "Calculator")
calcWindow = aeSourceElement;
}
catch(ElementNotAvailableException ex)
{
logger.Error(ex.Message);
return;
}
//下面可以开始执行真正测试
//ExecuteTest();
}
}
总结:
两种方式相比较,第二种方式的同步性更好,其同步的主动权由系统控制(采用回调函数),而第一种方式加入了人为等待时间把控,这在形如网络访问等类似的操作,等待时间是很不确定的情况下,有很大的弊端。