4

我有一个想要自动化测试的 Java 应用程序。不幸的是,应用程序窗口仅注册为 SunAWTFrame,这意味着没有任何控件暴露给典型的窗口分析和自动化工具。

我的搜索引导我使用 C# 并在 C# 程序中使用 Java Access Bridge DLLS 来自动化它。

有没有人有这方面的经验?

Oracle 为 JavaAccessBridge (JAB) 提供了一些 DLLS 来帮助解决这个问题,因为我在阅读了互联网上的几篇文章后理解了这一点。有一些代码示例,但我现在真的不喜欢它。通过分解它,我认为这是需要实现的:

  1. 导入/加载/解析 JAB dll
  2. 将 JAB dll 中的函数映射到我的程序中的方法/调用
  3. 让 Java 应用程序自动运行(启用 JAB)并将其处理给我的程序
  4. 利用 JAB 函数来控制 Java 应用程序

我对 C# 的了解不如对 Java 的了解,但这不会阻止我。

如果有人可以提供帮助、指导、指示或任何让我开始的东西,那真是太棒了。

4

2 回答 2

3

截至 2019 年,我们有一个很棒的工具AccessBridgeExplorer由谷歌创建并开源。这是一个非常好的起点,其中包含一个WindowsAccessBridgeInterop项目,该项目将几乎所有 JAB API 封装到一个面向类的、.NET 友好的程序集中。

一件值得注意的事情,AccessBridge.Initialize()必须在 WPF/WinForm UI 线程或您自己的消息泵线程中调用,否则某些方法AccessBridge.EnumJvms()将始终返回 false/empty。

于 2019-09-18T04:04:04.983 回答
0

建立在 Stackia 使用 Google AccessBridgeExplorer 的绝妙技巧的基础上,以下是一些帮助您入门的技巧:

  • 下载Access Bridge Explorer

  • 在您自己的(WinForms 而非控制台)项目中使用 WindowsAccessBridgeInterop.dll(添加> 项目参考> 选择 DLL)

  • 创建一个新的访问桥对象

    AccessBridge Java = 新的 AccessBridge();

  • 初始化 Access Bridge 对象

    Java.Initialize();

  • 调用 Application.DoEvents() - 等待 Java.Initialize 完成的 hack(我的简单理解是 Java Access Bridge 使用隐藏窗口或类似的)

    应用程序.DoEvents(); //这等待 Java Bridge 初始化 ;)

  • 获取 Java 窗口的句柄(网上有很多关于如何在 C# 中获取窗口句柄的示例)

  • 访问表示窗口的 Java 对象:

    Java.Functions.GetAccessibleContextFromHWND(Handle, out int vmid, out JavaObjectHandle javaObjectHandle);

  • 为 Window 获取 AccessibleWindow 对象(这样你就可以找到它的子对象)

    AccessibleWindow win = Java.CreateAccessibleWindow(handle);

  • 想出你自己的方式来循环遍历孩子,和孩子的孩子,直到你找到你想要的对象:

    //类似:foreach(var child in win.GetChildren()) JavaObjectHandle? javaObject = Java.Functions.GetAccessibleChildFromContext(node.JvmId, parentJavaObject, child.GetIndexInParent());

    //获取对象的标签或标题:

    child.GetTitle();

  • 要与对象交互(例如单击按钮),请执行以下类似操作:(请注意它说 JavaObject 的位置 - 它表示子 Java 对象(例如,要单击按钮,您需要使用 GetAccessibleChildFromContext 获取该按钮的 JavaObject正如我上面提到的)

    //获取可能的操作 JavaAutomation.Java.Functions.GetAccessibleActions(VMID, JavaObject, out AccessibleActionsaccessibleActions);

              foreach( var action in accessibleActions.actionInfo)
              {
                  Log.Info($"DoAction: {action.name}");
              }
    
              AccessibleActionsToDo accessibleActionsToDo = new AccessibleActionsToDo();
              accessibleActionsToDo.actions = accessibleActions.actionInfo;
              accessibleActionsToDo.actionsCount = accessibleActions.actionsCount;
    
              //Do Actions
              JavaAutomation.Java.Functions.DoAccessibleActions(VMID, JavaObject, ref accessibleActionsToDo, out int failure);
    
于 2022-02-20T10:51:46.263 回答