我正在使用 UI automator 编写 UI 测试,并遇到了一个问题,我试图滚动到 NumberPicker 的开头,但是当使用具有不同步数的 ScrollToBeginning 或 FlingToBeginning 时,NumberPicker 仅向上滚动两个元素,然后停止滚动。这种行为持续发生是否有任何原因,是否有任何方法可以修复或解决它?
目标: 在设备上进行自动化测试期间截取屏幕截图。测试完成后,使用 adb 拉取屏幕截图文件。
语境:
我目前正在尝试编写自动化测试来拍摄设备屏幕的快照。使用UiDevice进行导航,我想在测试过程中截取屏幕截图。UiDevice 有一个方法takeScreenshot,当我想要拍摄快照时我会调用该方法。
经过一番调查,我意识到负责将图像写入文件UiAutomatorBridge 的类捕获了 Exception :
java.io.FileNotFoundException:/data/local/tmp/screenshots/screen2.png:打开失败:EACCES(权限被拒绝)
我使用adb创建了该文件并为所有用户设置了所有权限。
adb shell touch /data/local/tmp/screenshots/screen1.png
adb shell chmod 777 /data/local/tmp/screenshots
Run Code Online (Sandbox Code Playgroud)
完成后,我可以使用以下命令截取屏幕截图:
@Test
public void takeSnapShot() {
String filename = "/data/local/tmp/screenshots/screen1.png";
File file = new File(filename);
assertEquals(true, mDevice.takeScreenshot(file));
}
Run Code Online (Sandbox Code Playgroud)
问题 :
我希望能够在测试执行时直接创建文件,而不需要使用 adb。我尝试使用createNewFile直接从 Java 创建文件。
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
但我得到一个 IOException
java.io.IOException:打开失败:EACCES(权限被拒绝)
有人知道发生了什么事吗?我对 Linux 还很陌生,所以不要犹豫提出建议,即使它对你来说似乎很明显;)
我应该将其发布在超级用户上吗?
编辑
目录/data具有这些权限
drwxrwx--x …Run Code Online (Sandbox Code Playgroud) 我在 Appium/Python 中有:
//calculation max_height
//calculation of max_width
action = TouchAction(self.driver)
action.tap(None, max_width, max_height).release().perform()
Run Code Online (Sandbox Code Playgroud)
我的目标是执行相同的操作,但是在 Java 中使用 UIautomator 工具。我已经尝试了下一个脚本,但它不起作用。
UiObject appButton = new UiObject(new UiSelector());
appButton.click(int x, int y);
Run Code Online (Sandbox Code Playgroud)
我的应用程序是在 Unity 中制作的,并且没有任何定位器的可访问性,因此我必须使用屏幕上的 XY 位置。
有人解决这个问题吗?谢谢。
我有一个应用程序,它使用两个进程来显示 UI 组件 - 一个用于主应用程序,它使用常规活动,另一个应用程序的 UI 由覆盖层(位于 Service 中)组成,这些覆盖层使用 ViewManager API 添加到 WindowManager中。我想使用 UiAutomator 测试叠加层和应用程序之间的交互。
如本问题所述,覆盖视图/窗口很难直接访问。如果我将覆盖层移至主进程,我可以通过使用反射调用 WindowManagerGlobal 上的方法来访问视图,就像 Appium 在此处所做的那样,但如果它们在覆盖层进程中运行,则对 WindowManagerGlobal 的调用不会返回视图。在任何情况下,测试都无法与视图交互,因为只有创建视图的线程才能访问它们,除非通过 UiAutomator 使用的辅助功能框架来访问它们。
有什么方法可以通过辅助功能框架公开覆盖视图,以便 UiAutomator 可以找到它们,即使它们在不同的进程中运行?
我查看了multiprocess Espresso,这听起来非常有前途,因为它有可能弥合两个进程之间的差距,但 Espresso 找不到覆盖视图。是否可以改变添加叠加层的方式,也许可以通过为该过程提供某种根窗口,让 UiAutomator 甚至可能是 Espresso 找到叠加视图?
如果我使用UiDevice转储视图层次结构,我确实会看到系统装饰视图与应用程序的视图位于同一级别。我查看了将视图添加到 WindowManager 的 SystemUI 代码,它与应用程序添加其叠加层的方式非常相似。与我所看到的唯一区别是图层类型。了解系统 UI 组件如何注入到该层次结构(没有更好的词),以及是否可以对应用程序创建的覆盖层执行相同的操作,这将是很有趣的。
android accessibility android-windowmanager android-uiautomator
在文档中它说的是UiAutomation
用于通过模拟用户操作和自省屏幕内容与设备的 UI 进行交互的类。它依赖于平台辅助功能 API 来检查屏幕并在远程视图树上执行一些操作。它还允许注入任意原始输入事件,模拟用户与键盘和触摸设备的交互。人们可以将 UiAutomation 视为一种特殊类型的 AccessibilityService,它不提供服务生命周期的挂钩,并公开对 UI 测试自动化有用的其他 API。
此类公开的 API 是低级的,以便在开发 UI 测试自动化工具和库时最大限度地提高灵活性。一般来说,UiAutomation 客户端应该使用更高级别的库或实现高级功能。例如,在屏幕上执行点击需要构建和注入触摸向下和向上事件,这些事件必须通过调用injectInputEvent(android.view.InputEvent, boolean)传递到系统。
此类公开的 API 可以跨应用程序运行,使客户端能够编写涵盖跨多个应用程序的用例的测试。例如,转到设置应用程序以更改设置,然后与行为取决于该设置的另一个应用程序进行交互。
UiAutomation与常规的到底有什么不同,因为它在源代码AccessibilityService中没有继承它。
public final class UiAutomation {
private static final String LOG_TAG = UiAutomation.class.getSimpleName();
// omitted the rest...
Run Code Online (Sandbox Code Playgroud) 我想以一种可以InstrumentationRegistry.getInstrumentation()在运行时访问的方式运行 Android 应用程序。
这仅适用于调试版本,通过 ADB 安装应用程序就足够了。因为我不想使用仪器测试套件,所以我不想使用InstrumentationTestRunner但直接启动MainActivity应用程序。
这怎么可能?
我尝试过的:
implementation 'androidx.test.uiautomator:uiautomator:2.2.0'
implementation 'androidx.test:runner:1.1.0'
Run Code Online (Sandbox Code Playgroud)
<instrumentation android:name=".MainActivity"
android:targetPackage="com.android.shell"
android:label="App" />
Run Code Online (Sandbox Code Playgroud)
(不确定这是否真的正确。)
adb shell am instrument -w com.example.app/.MainActivity
Run Code Online (Sandbox Code Playgroud)
这导致:
android.util.AndroidException: INSTRUMENTATION_FAILED: com.example.app/com.example.app.MainActivity
at com.android.commands.am.Instrument.run(Instrument.java:519)
at com.android.commands.am.Am.runInstrument(Am.java:202)
at com.android.commands.am.Am.onRun(Am.java:80)
at com.android.internal.os.BaseCommand.run(BaseCommand.java:60)
at com.android.commands.am.Am.main(Am.java:50)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:399)
Run Code Online (Sandbox Code Playgroud)
UiAutomator所以本质上我的问题是,如何以我可以在运行时使用的方式运行应用程序?
提前致谢!
android android-testing android-instrumentation android-uiautomator
关于将外部jar添加到android项目和ant项目中似乎有相当多的问题,但我找不到在这种情况下有效的解决方案.我对Ant不太熟悉,这可能会激怒这个问题.
问题是:我正在尝试将JSch库添加到我的uiautomator项目中.我将jsch.jar文件放入/ libs文件夹中,希望它可以通过'android create uitest-project'找到.然而,事实并非如此 - 所以我似乎需要修改build.xml/ant.properties/build.properties或者其他什么来获取ant以找到jar
具体错误是:
[javac] Compiling 5 source files to /Users/.../KeyEvents/bin/classes
[javac] /Users/.../KeyEvents/src/com/proj/automation/core/coreSSH.java:9: error: package com.jcraft.jsch does not exist
Run Code Online (Sandbox Code Playgroud)
build.xml是由android脚本创建的,Ant是开箱即用的 - 所以我认为我的蚂蚁知识是问题:P.
我正在使用Android上的UI Automator进行一组测试。我有它的工作,但我目前的测试是用很多字符串文字进行的。
当我刚开始尝试使事情正常工作时,字符串字面值还不错,但是今后它们会很不好。如果更改了应用程序,则字符串文字需要进行更改以匹配。同样,愚蠢的是我的测试必须完全重做才能测试其他语言的本地化版本。
该应用程序本身具有存储在资源中的所有字符串。每个字符串都有一个不变的标识符...这是一个示例:
<string name="more_options">More options</string>
Run Code Online (Sandbox Code Playgroud)
应用程序代码将始终使用名称more_options来查找字符串资源,而不是硬编码"More options"到代码中。
所以我想要的是导入所有字符串资源,将它们存储在某种map对象中,然后在我的UI Automator测试代码中使用类似的东西,m.get("more_options")而不是像"More options"现在那样使用文字字符串。
无论我做什么,我都希望它只是生成并推送到设备以运行测试的JAR文件的一部分。例如,我不想将XML字符串资源文件推送到设备并尝试在测试运行时读取它们。我想在构建JAR文件时内置数据。
我查看了通过构建应用程序生成的文件,并且类似的名称more_options都被设置为整数。这些必须是资源存储中的索引或指针,但是我不确定如何将该存储复制到我的UI Automator项目中并使其连接起来。在Android应用中,您使用Context对象访问资源,而UI Automator JAR文件没有Context。
这必须是一个普遍的问题,人们必须已经解决了这个问题,但是我的Google搜索尚未找到有关人们如何解决此问题的任何讨论。
如果没有任何建议,我将编写一个Python脚本,该脚本导入XML文件,并编写一个Java文件,该Java文件具有构建所需地图的功能,然后从UI Automator测试程序中调用它。(无论如何,我有一个运行命令行工具序列的Python脚本来执行UI Automator测试……我不介意使它做更多的工作。)但是我认为应该有一个纯Java解决方案为此,可能涉及从应用程序的源目录中抓取已编译的文件。
我目前正在测试应该设置为默认启动器的应用程序.
我已经Espresso运行了一组测试,但只有在用户之前选择我的应用程序作为启动器时它们才有效.
向用户显示的对话框是无法访问的Espresso,因为它位于应用程序本身之外.但是,UIAutomator完全能够与它进行交互.
因此,我想知道UIAutomator在Espresso测试之前是否可以使用某种脚本.
我正在尝试使用Android UIAutomator进行一些简单的测试,我知道它需要由Gradle构建,因为UIAutomator 2.0,我可以运行我的简单测试,它只通过Android Studio或命令行按下主页按钮"gradlew .bat cC",我想知道如何用adb命令运行它?
我试过了
adb shell am instrument -w test.simple.uiatest/android.test.InstrumentationTestRunner
Run Code Online (Sandbox Code Playgroud)
正如这里建议的那样,但我明白了
INSTRUMENTATION_STATUS: id=ActivityManagerService
INSTRUMENTATION_STATUS: Error=Unable to find instrumentation info for: ComponentInfo{test.simple.uiatest/android.test.InstrumentationTestRunner}
INSTRUMENTATION_STATUS_CODE: -1
android.util.AndroidException: INSTRUMENTATION_FAILED: test.simple.uiatest/android.test.InstrumentationTestRunner
at com.android.commands.am.Am.runInstrument(Am.java:951)
at com.android.commands.am.Am.onRun(Am.java:316)
at com.android.internal.os.BaseCommand.run(BaseCommand.java:47)
at com.android.commands.am.Am.main(Am.java:99)
at com.android.internal.os.RuntimeInit.nativeFinishInit(Native Method)
at com.android.internal.os.RuntimeInit.main(RuntimeInit.java:250)
Run Code Online (Sandbox Code Playgroud)
下面是我的代码片段和build.gradle,我做错了什么?
package test.simple.uiatest;
import android.support.test.uiautomator.UiDevice;
import android.test.InstrumentationTestCase;
public class ApplicationTest extends InstrumentationTestCase {
private UiDevice theDevice;
@Override
public void setUp() throws Exception {
super.setUp();
theDevice = UiDevice.getInstance(getInstrumentation());
theDevice.pressHome();
}
public void testName() throws Exception {
theDevice.pressHome(); …Run Code Online (Sandbox Code Playgroud)