【发布时间】:2012-03-02 06:11:00
【问题描述】:
我正在尝试自动化应用程序的测试,但我遇到了一个我正在努力解决的问题。
该应用程序具有标准的 Windows 按钮,我尝试使用 AutoIT 和 User32 dll 来单击其中一些按钮。有时按钮被正确点击(耶!),有时它们失败(嘘!) - 但更糟糕的是,AutoIT 确信它点击了按钮(双重嘘!)然后产生误报(三声嘘!)。当我看到它被说服时,我的意思是它返回点击成功而不是成功。
我在 Win Server 2K8 上运行该应用程序,该应用程序除了使用 MDI 窗口之外没有什么特别之处,并且一些按钮包含在 MDI 窗口中。但有些不在 MDI 窗口中(例如,在创建父窗口之前的登录窗口)。
这是我的命令顺序:
在窗口中找到按钮(总是成功) 将窗口置于前台(成功) 激活窗口(成功) 激活按钮(成功) 聚焦按钮(成功) 如果按钮已获得焦点,并且该按钮已启用,则单击它。 (成功/失败,不可预知的行为。我无法缩小它为什么有时会成功,以及为什么有时会失败......)
其他细节:
有时订单会点击按钮,这应该会打开另一个窗口。该窗口关闭,然后再次单击该按钮 - 这一次,没有任何反应。其他时候它按预期工作。
我以管理员身份运行,UAC 已完全禁用。
据我所知,这不是时间问题,因为我确实确保按钮已获得焦点,并在尝试单击它之前启用,并且我看到按钮确实在其周围获得了焦点突出显示。
正如我所提到的,我也一直在尝试通过简单的 User32/SendMessage 调用来实现这一点,但这也失败了。
最后但同样重要的是,当我手动与应用程序交互时不会发生这种情况。我一直有实际的按钮点击工作。
有什么想法吗?
更新
这是我应该提到的等式的另一个变量 - 这发生在 VM 上(因为这是我需要运行它的地方)。我可以在我自己的机器上做一些有限的测试,但要获得一些真正的测试,它需要在 VM 上。点击我自己的开发框似乎是可靠的,这让这更加令人费解。
我一直在另一个 VM 上尝试这个,它似乎也在那里工作。就这两个虚拟机而言,它们运行的是相同版本的 Windows、相同版本的我的应用程序、相同版本的 AutoIT,等等。
我已将其简化为一个细节 - 幸运的是,我无法自行配置,必须提交一张票才能更改任何配置。配置的区别是这样的:
在不工作的 VM 上,设备管理器显示一个鼠标,它是 vmware 鼠标。在 工作的 VM 上,设备管理器显示一个 PS/2 鼠标。显然两者都是软件鼠标,但我现在想知道 VMWare 鼠标的行为是否会有所不同,并导致按钮点击并不总是有效。我不确定这作为解决方案的可能性有多大,因为根据我对它的理解,使用 User32 SendMessage 调用实际上并不使用鼠标,而是发送鼠标会发送的相同消息,但值得一试...
【问题讨论】:
-
有多个子窗体,但每个窗体一次只有一个实例 - 我可以确认包含按钮 的窗口位于顶部,并且是没有被最上面的窗户挡住
-
我正在使用以下命令:ControlClick("My Sub Window Title", "", "CLASS:ThunderRT6CommandButton; INSTANCE:1]", "left");我不设置坐标,因为我总是提供控件 ID(谢天谢地,这是静态的)
-
我很确定当 AutoIt 确信它找到了按钮时,它也点击了它。换句话说:它只会在找不到控件时返回错误。这只是一个正在发送的 Windows 消息,当其他应用程序不处理它时,AutoIt 无法知道。
-
尝试使用来自@M.Babcock 的提示并正确定位鼠标并单击。有一个功能
_WinAPI_ClientToScreen可以帮助您获得点击的确切屏幕位置。使用来自ControlGetPos的坐标输入它。或者您应该在再次单击该按钮之前的某个时间点Sleep(333),或者使用Send("{Space}")模拟单击,因为您已经将焦点放在了它上面。 -
我确实在我的 User32 调用中使用睡眠来发送点击。我已经设置了我的代码来尝试 AutoIT,然后如果失败则回退到 User32 - 但误报是问题所在。这可能是一个显而易见的问题,但如果我遗漏了什么 - 是否有任何潜在的消息可以挂钩以验证按钮是否已被按下?显然,我可以一起破解一些东西,但是我可以绑定任何底层的 Windows 消息来验证按钮是否接收到某种“点击”状态 - 也许如果它的类从未点击的按钮类更改为点击的,或者类似的东西?
标签: c# windows automation autoit user32