如何在Android设备的uiautomator测试用例中打开WiFi?

8

作为测试用例的一部分,我希望使用 uiautomator 工具在安卓设备上开启wifi。我试过在 uiautomator 测试用例中使用以下代码:

WifiManager wi = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
      if(wi.isWifiEnabled()){
        wi.setWifiEnabled(false);
      }else{
        wi.setWifiEnabled(true);
    }

但是它报了这个错误:
“Mainclass没有定义getSystemservice方法。”
6个回答

9
你实际上可以使用UIAutomator来打开和关闭WiFi设置。我今晚写了这段代码 :)
以下是代码,你可以将其添加到此处的Android示例中:http://developer.android.com/tools/testing/testing_ui.html 在类的顶部添加以下枚举。
private enum OnOff {
    Off,
    On
};

请在以下代码后添加新代码:

    // Validate that the package name is the expected one
    UiObject settingsValidation = new UiObject(new UiSelector()
    .packageName("com.android.settings"));
    assertTrue("Unable to detect Settings", settingsValidation.exists());

这是新代码:

    UiSelector settingsItems = new UiSelector().className(android.widget.TextView.class.getName());
    UiObject wiFi = appViews.getChildByText(settingsItems, "Wi-Fi");

    // We can click on Wi-Fi, e.g. wiFi.clickAndWaitForNewWindow();
    // So we know we have found the Wi-Fi setting

    UiSelector switchElement = new UiSelector().className(android.widget.Switch.class.getName());
    setSwitchTo(OnOff.Off); // Or set it to On as you wish :)
}   

private void setSwitchTo(OnOff value) throws UiObjectNotFoundException {

    String text;
    UiObject switchObject = getSwitchObject();
    for (int attempts = 0; attempts < 5; attempts++) {
        text = switchObject.getText();
        boolean switchIsOn = switchObject.isChecked();
        final OnOff result;
        if (switchIsOn) {
            result = OnOff.On;
        } else {
            result = OnOff.Off;
        }

        System.out.println("Value of switch is " + switchObject.isSelected() + ", " + text + ", " + switchIsOn);
        if (result == value) {
            System.out.println("Switch set to correct value " + result);
            break;
        } else {
            switchObject.click();
        }
    }
}

private UiObject getSwitchObject() {
    UiObject switchObject = new UiObject(new UiSelector().className(android.widget.Switch.class.getName()));
    assertTrue("Unable to find the switch object", switchObject.exists());
    String text;
    return switchObject;
}

循环是为了弥补我观察到的一些行为,其中点击似乎没有改变开关位置的情况。

如果有多个开关元素会发生什么? - Rilwan
@Rilwan,您能否在Android中为一个项目提供多个开关元素的示例?如果可以的话,欢迎在StackOverflow上发布一个新问题,并从本问题中链接到它。 - JulianHarty
在Wi-Fi的情况下,以上代码将起作用。但是如果您查看三星手机上的NFC,如果您单击NFC并转到NFC页面->>再次可以看到两个开关。因此,如果我们将代码更通用地修改为像这样“UiObject item = itemsList.getChildByText(new UiSelector()。className(LinearLayout.class.getName()),switch_label,true); UiObject switchObject = item.getChild(new UiSelector()。className(android.widget.Switch.class.getName()));”这是否有意义? - Rilwan
1
@Kikiwa 我曾经编写过这个循环,那时从Android的角度来看,UI Automator还很年轻,并且存在着一些已知的缺陷。我希望这些缺陷已经在最近的Android工具更新中得到了解决,也许在使用它们时不再需要这个循环。我将在我的答案中保留它有两个主要原因:1)那时是必需的,某些人可能仍然会使用旧版本的工具,因此需要它;2)它提供了一个丑陋但可行的解决方案示例。这一周我一直在为Android Instrumentation寻找解决方法! - JulianHarty
1
@IgorGanapolsky 很好的问题,它可能已经在我2013年编写的原始代码中丢失了。这可能需要一段时间才能找到。我已经检查了Google文档的参考资料,但它们已经发生了重大变化,以至于我没有找到当时使用的示例。我会看看是否可以找到代码和/或重现此示例。如果有更新,我会在这里提供。 - JulianHarty
显示剩余5条评论

7

启用WiFi:
device.executeShellCommand("svc wifi enable");

禁用WiFi:
device.executeShellCommand("svc wifi disable");

这些是您在UiDevice上使用的命令。


2

在Android 4.2和4.4上用于生产

在你的代码中打开Android Wifi设置:

final Intent intent = new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK);
mContext.startActivity(intent);

使用UiAutomator点击开关(在确保您处于正确的活动之后):
public void enableWifiOnAndroidWifiSettings(boolean enabled) throws UiObjectNotFoundException {
    final UiSelector wifiSwitchSelector = new UiSelector().className(android.widget.Switch.class.getName());
    UiObject wifiSwitch = UiDevice.getInstance(sInstrumentation).findObject(wifiSwitchSelector);
    if (wifiSwitch.waitForExists(5000) && wifiSwitch.isEnabled()) {
        if (wifiSwitch.isChecked() != enabled) {
            wifiSwitch.click();
        }
    }
}

已知限制:它只会搜索第一个可用的Switch。如果您有自定义ROM或者如果Android设置应用程序在未来发生变化,这可能不够。


1
在使用UIAutomator进行套件测试时,我使用以下代码:

Runtime.getRuntime().exec("\"svc wifi disable\"")

Runtime.getRuntime().exec("\"svc wifi enable\"")

Runtime.getRuntime().exec("\"svc data disable\"")

Runtime.getRuntime().exec("\"svc data enable\"")

0

您可以通过以下方式使用adb启用或禁用wifi

adb shell sqlite3 /data/data/com.android.providers.settings/databases/settings.db update secure set value=1 where name='wifi_on'; .exit

但是您不能使用uiautomator工具来执行相同的操作


-5

你不能这样做。UI Automator测试不作为Android框架的一部分运行,因此无法访问Android系统服务。它的目的是测试用户界面;它并不声称自己是一个全功能的测试框架。在运行测试之前,请手动打开WiFi。


我还想知道在运行uiautomator测试用例时是否可以检查wifi连接是否处于活动状态,即使我手动打开了wifi,我能否检查数据包是否交换。这是可能的吗? - user1907534
既然我们可以在这里使用Android的所有断言函数,为什么不能使用这个函数呢? - user1907534

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接