使用Espresso测试UI(Jenkins)

15

这个应用程序在本地通过了Espresso测试,即直接在设备和Genymotion模拟器上运行。但当我使用Jenkins构建应用程序镜像时,Espresso测试不成功,会出现以下错误:

JENKINS:

 java.lang.RuntimeException: Waited for the root of the view hierarchy to have window focus and not be requesting layout for over 10 seconds. If you specified a non default root matcher, it may be picking a root that never takes focus. Otherwise, something is seriously wrong. Selected Root:
Root{application-window-token=android.view.ViewRootImpl$W@536a97d4, window-token=android.view.ViewRootImpl$W@536a97d4, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) sim=#100 ty=1 fl=#1810100 pfl=0x8 wanim=0x103028f}, decor-view-string=DecorView{id=-1, visibility=VISIBLE, width=800, height=1184, has-focus=true, has-focusable=true, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}
. All Roots:
Root{application-window-token=android.view.ViewRootImpl$W@536a97d4, window-token=android.view.ViewRootImpl$W@536a97d4, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) sim=#100 ty=1 fl=#1810100 pfl=0x8 wanim=0x103028f}, decor-view-string=DecorView{id=-1, visibility=VISIBLE, width=800, height=1184, has-focus=true, has-focusable=true, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}
at com.google.android.apps.common.testing.ui.espresso.base.RootViewPicker.get(RootViewPicker.java:84)
at com.google.android.apps.common.testing.ui.espresso.ViewInteractionModule.provideRootView(ViewInteractionModule.java:51)
at com.google.android.apps.common.testing.ui.espresso.ViewInteractionModule$$ModuleAdapter$ProvideRootViewProvidesAdapter.get(ViewInteractionModule$$ModuleAdapter.java:187)
at com.google.android.apps.common.testing.ui.espresso.ViewInteractionModule$$ModuleAdapter$ProvideRootViewProvidesAdapter.get(ViewInteractionModule$$ModuleAdapter.java:151)
at com.google.android.apps.common.testing.ui.espresso.base.ViewFinderImpl.getView(ViewFinderImpl.java:52)
at com.google.android.apps.common.testing.ui.espresso.ViewInteraction$2.run(ViewInteraction.java:141)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:442)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)

那是Jenkins说的。 - Alfaplus
那个堆栈跟踪是来自于在安卓模拟器或者安卓设备上运行的Espresso测试框架。你在Jenkins服务器上是否正在运行模拟器? - yogurtearl
是的,我是。有问题吗?我一直在使用Robotium而不是Espresso,并且在使用模拟器时没有遇到任何问题,直到使用Espresso进行测试。 - Alfaplus
1
你的模拟器是否使用了“--no-window”参数?尝试在本地使用与Jenkins机器上完全相同的AVD进行复现。 - yogurtearl
1
我也遇到了无人机的同样问题,你找到解决办法了吗? - marbarfa
显示剩余5条评论
4个回答

10

2
除了 scytale 的回复之外 - 您还可以提供一个简单的实现示例,以说明您所建议的方法。 - g00dy

1
解决方案是创建一个自定义测试运行器,以解锁屏幕并启动唤醒锁,直到测试完成。
public class TestRunner extends android.support.test.runner.AndroidJUnitRunner
{
    private PowerManager.WakeLock mWakeLock;

    @Override
    public void callApplicationOnCreate(Application app)
    {
        // Unlock the screen
        KeyguardManager keyguard = (KeyguardManager) app.getSystemService(Context.KEYGUARD_SERVICE);
        keyguard.newKeyguardLock(getClass().getSimpleName()).disableKeyguard();

        // Start a wake lock
        PowerManager power = (PowerManager) app.getSystemService(Context.POWER_SERVICE);
        mWakeLock = power.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, getClass().getSimpleName());
        mWakeLock.acquire();

        super.callApplicationOnCreate(app);
    }

    @Override
    public void onDestroy()
    {
        mWakeLock.release();

        super.onDestroy();
    }
}

然后在您的测试的AndroidManifest.xml中添加必要的权限:

<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>

别忘了编辑你的build.gradle文件,使用新的testInstrumentationRunner类。

源代码


这个解决方案使用了一些已弃用的方法和常量。你能提供一些替代方案吗? - MeLean

0
从我的角度来看,您需要按照以下方式组织Jenkins作业:在运行Espresso测试之前(我假设您已经将connectedAndroidTest添加到gradle的后构建操作中或类似操作),添加一个后构建操作以卸载应用程序包和另一个卸载应用程序测试包。例如:com.example.mypackage.debug和com.example.mypackage.debug.test。这是一种很好的方法,可以刷新应用程序到您的智能手机/模拟器中,以便让Espresso发挥其魔力。
此外,请确保在开发人员工具中激活了“始终开启”选项(根据设备,在设置中您有“开发人员选项”或“开发人员工具”子菜单)。
如果这些都不起作用,那么这意味着在您的Jenkins作业中存在某些操作顺序问题,需要进行澄清。对我来说,卸载软件包帮助我清理了与我的应用程序相关的所有内容。
希望这对您也有帮助。
如果没有,请写下评论,我会帮助您。
祝你好运!

0

我建议使用Test-Butler,在测试时禁用动画并解锁屏幕。


Test-Butler只能用于模拟器,所以如果您正在使用模拟器运行测试,那么使用它是一个好主意。如果您正在对真实设备进行测试,我建议使用UiAutomator - carvaq

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