Detox + React Native Android启动后出现空白屏幕

3

问题

虽然我在iOS上使用detox很好,但是当通过detox cli打开我的react-native android detox构建时,会出现空白屏幕。

值得一提的是,在这种状态下,cmd + mrr都无法重新加载应用程序。

Package.json

  "react-native": "0.51.0",
  ...
  "detox": "^7.0.0-alpha.0",
  ...
  "android.emu.debug": {
    "binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
    "build": "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..",
    "type": "android.emulator",
    "name": "Nexus_5X_API_26"
  },

故障排除

在运行时,如果遇到问题,请尝试以下步骤进行故障排查:

detox test -c android.emu.debug --loglevel verbose

安卓应用程序(APK)安装、启动时,但在空白屏幕处卡住。

Detox日志

detox info 15:26:02: server listening on localhost:63324...
detox verb ws onOpen [object Object]
detox verb ws send: {"type":"login","params":{"sessionId":"300068b9-c44f-8b8a-81cb-73f8c66b0752","role":"tester"},"messageId":0}
detox verb ws onMessage: {"type":"loginSuccess","params":{"sessionId":"300068b9-c44f-8b8a-81cb-73f8c66b0752","role":"tester"},"messageId":0}
detox verb ws
detox verb 1: /Users/me/Library/Android/sdk/tools/emulator -list-avds --verbose
detox verb 1: stdout: Nexus_5X_API_26
detox verb 1: stdout:
detox verb /Users/me/Library/Android/sdk/tools/emulator -verbose -gpu host -no-audio @Nexus_5X_API_26
detox verb 2: /Users/me/Library/Android/sdk/platform-tools/adb  devices
detox verb 2: stdout: List of devices attached
detox verb 2: stdout: emulator-5554 device
detox verb 2: stdout:
detox verb 2: stdout:
detox verb 3: /Users/me/Library/Android/sdk/platform-tools/adb -s emulator-5554 shell getprop dev.bootcomplete
detox verb 3: stdout: 1
detox verb 3: stdout:
detox verb 4: /Users/me/Library/Android/sdk/platform-tools/adb -s emulator-5554 shell input keyevent 82
detox verb adb -s emulator-5554 shell am instrument -w -r -e detoxServer ws://localhost:63324 -e detoxSessionId 300068b9-c44f-8b8a-81cb-73f8c66b0752 -e debug false com.mypackage.mobile.test/android.support.test.runner.AndroidJUnitRunner
detox verb Instrumentation spawned, childProcess.pid:  24565
detox verb ws send: {"type":"isReady","params":{},"messageId":-1000}
detox verb Instrumentation stdout:  INSTRUMENTATION_STATUS: numtests=1
detox verb Instrumentation stdout:  INSTRUMENTATION_STATUS: stream=
detox verb Instrumentation stdout:  com.mypackage.mobile.DetoxTest:
detox verb Instrumentation stdout:  INSTRUMENTATION_STATUS: id=AndroidJUnitRunner
detox verb Instrumentation stdout:  INSTRUMENTATION_STATUS: test=runDetoxTests
detox verb Instrumentation stdout:  INSTRUMENTATION_STATUS: class=com.mypackage.mobile.DetoxTest
detox verb Instrumentation stdout:  INSTRUMENTATION_STATUS: current=1
detox verb Instrumentation stdout:
detox verb Instrumentation stdout:  INSTRUMENTATION_STATUS_CODE: 1
detox verb Instrumentation stdout:

2分钟后

detox verb Instrumentation stdout:  INSTRUMENTATION_CODE: 0
detox verb Instrumentation stdout:
detox verb instrumentationProcess terminated due to receipt of signal null
  1) "before all" hook: _callee

  0 passing (2m)
  1 failing

  1) "before all" hook: _callee:
     Error: Timeout of 120000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.





  0 passing (2m)
  1 failing

  1) "before all" hook: _callee:
     Error: Timeout of 120000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

Android 日志

通过运行 react-native log-android 可以查看日志

01-17 15:11:01.053  5248  5318 D ReactNative: Initializing React Xplat Bridge.
01-17 15:11:01.055  5248  5318 D ReactNative: Initializing React Xplat Bridge before initializeBridge
01-17 15:11:01.060  5248  5318 D ReactNative: Initializing React Xplat Bridge after initializeBridge
01-17 15:11:01.061  5248  5318 D ReactNative: CatalystInstanceImpl.runJSBundle()
01-17 15:11:01.061  5248  5323 D ReactNative: ReactInstanceManager.setupReactContext()
01-17 15:11:01.061  5248  5323 D ReactNative: CatalystInstanceImpl.initialize()
01-17 15:11:01.065  5248  5323 D ReactNative: ReactInstanceManager.attachRootViewToInstance()

模拟器行为

在上述日志之后,应用程序会超时,因此我终止它。当我从模拟器中启动相同的应用程序(由detox安装的相同apk)时,它按预期工作!

当apk按预期启动时,来自react-native log-android的日志具有额外的一行。

01-17 15:24:10.207  6447  6530 I ReactNativeJS: Running application "MyApp" with appParams: {"rootTag":1}. __DEV__ === true, development-level warning are ON, performance optimizations are OFF

目前我知道apk是好的,所以我尝试使用--reuse标志,但出现了同样的问题。

DetoxTest.java

package com.mypackage.mobile;
import android.support.test.filters.LargeTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;

import com.wix.detox.Detox;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class DetoxTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false);

    @Test
    public void runDetoxTests() throws InterruptedException {
        Detox.runTests(mActivityRule);
    }
}

问题

有人知道如何解决这个问题吗?当通过detox命令行运行时,应用程序将如预期般启动,而不是出现空白屏幕。如果没有解决方案,是否有下一步可以采取的好方法来隔离从DetoxTest.java启动应用程序的问题?


我在生产发布模式下遇到了同样的问题。你解决了吗? - Alex Harrison
@AlexHarrison 虽然我已经多年没有使用Detox了,但我相当确定在公司代理后面有一些网络调用从未完成加载,而Detox正在等待它们在幕后完成。一旦我们解决了这个问题,我们就能够继续前进了。虽然我们的用例可能不同,但请知道,如果Detox认为应用程序正在执行某些操作,它将会等待。 - Steven
2个回答

0
如果应用程序无法启动,很可能是因为 Android 应用程序没有正确构建。请确保您的 "android.emu.debug" 正确嵌套在 detox.configurations 下的 package.json 中,就像这样:
"detox": {
    "configurations": {
        "android.emu.debug": {
            "binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk",
            "build": "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..",
            "type": "android.emulator",
            "name": "Nexus_5X_API_26"
        },
    }
}

另外,请检查您的 android/app/build.gradle 文件中是否有以下内容

androidTestImplementation(project(path: ":detox"))
androidTestImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test:rules:1.0.1'

0

我在Android方面遇到了类似的问题。其中一部分帮助了我,是使用这个:

beforeAll(() => {
    device.reloadReactNative();
});

另外,我在运行测试之前会先打开模拟器进行测试。


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