微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Android 单元测试套件在单个测试通过时挂起

如何解决Android 单元测试套件在单个测试通过时挂起

测试类 DummyTest 已经在代码库中存在很长时间了,但是这个测试冻结问题只发生在我添加 Firebase Crashlytics 日志记录之前的几次

enter image description here

class DummyTest {
    @Test
    fun test() {
        val fakeDataSource = Mockito.mock(DummyDataSource::class.java)
        Mockito.`when`(fakeDataSource.invoke()).thenReturn(Single.error(UnkNownError("shit happened")))
        Dummy(fakeDataSource)
    }
}


class Dummy(dataSource: DummyDataSource) {
    init {
        dataSource()
                .subscribe({
                    println("success")
                },{
                    if (true) throw RuntimeException(it.message)
                })
    }
}

class DummyDataSource {
    operator fun invoke(): Single<String> {
        return Single.just("some data")
    }
}

DummyTest 在 Android Studio 中运行时通过,尽管控制台中存在 CompositeException:

io.reactivex.exceptions.CompositeException: 2 exceptions occurred. 
    at io.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:49)
    at io.reactivex.internal.disposables.Emptydisposable.error(Emptydisposable.java:78)
    at io.reactivex.internal.operators.single.SingleError.subscribeActual(SingleError.java:42)
    at io.reactivex.Single.subscribe(Single.java:3603)
    at io.reactivex.Single.subscribe(Single.java:3589)
    at com.myapp.Dummy.<init>(Dummy.kt:9)
    at com.myapp.DummyTest.testErrorCase(DummyTest.kt:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
  ComposedException 1 :
    java.lang.UnkNownError: something went wrong
        at com.myapp.DummyTest.testErrorCase(DummyTest.kt:17)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
        at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
        at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
        at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
        at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
        at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
        at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
  ComposedException 2 :
    java.lang.RuntimeException: something went wrong
        at com.myapp.Dummy$2.accept(Dummy.kt:12)
        at com.myapp.Dummy$2.accept(Dummy.kt:6)
        at io.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:46)
        at io.reactivex.internal.disposables.Emptydisposable.error(Emptydisposable.java:78)
        at io.reactivex.internal.operators.single.SingleError.subscribeActual(SingleError.java:42)
        at io.reactivex.Single.subscribe(Single.java:3603)
        at io.reactivex.Single.subscribe(Single.java:3589)
        at com.myapp.Dummy.<init>(Dummy.kt:9)
        at com.myapp.DummyTest.testErrorCase(DummyTest.kt:18)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
        at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
        at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
        at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
        at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
        at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
        at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

Exception in thread "main" io.reactivex.exceptions.CompositeException: 2 exceptions occurred. 
    at io.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:49)
    at io.reactivex.internal.disposables.Emptydisposable.error(Emptydisposable.java:78)
    at io.reactivex.internal.operators.single.SingleError.subscribeActual(SingleError.java:42)
    at io.reactivex.Single.subscribe(Single.java:3603)
    at io.reactivex.Single.subscribe(Single.java:3589)
    at com.myapp.Dummy.<init>(Dummy.kt:9)
    at com.myapp.DummyTest.testErrorCase(DummyTest.kt:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
  ComposedException 1 :
    java.lang.UnkNownError: something went wrong
        at com.myapp.DummyTest.testErrorCase(DummyTest.kt:17)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
        at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
        at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
        at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
        at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
        at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
        at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
  ComposedException 2 :
    java.lang.RuntimeException: something went wrong
        at com.myapp.Dummy$2.accept(Dummy.kt:12)
        at com.myapp.Dummy$2.accept(Dummy.kt:6)
        at io.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:46)
        at io.reactivex.internal.disposables.Emptydisposable.error(Emptydisposable.java:78)
        at io.reactivex.internal.operators.single.SingleError.subscribeActual(SingleError.java:42)
        at io.reactivex.Single.subscribe(Single.java:3603)
        at io.reactivex.Single.subscribe(Single.java:3589)
        at com.myapp.Dummy.<init>(Dummy.kt:9)
        at com.myapp.DummyTest.testErrorCase(DummyTest.kt:18)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
        at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
        at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
        at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
        at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
        at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:78)
        at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:57)
        at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
        at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
        at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:288)
        at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
        at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
        at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
        at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
        at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
        at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
        at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
        at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
        at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
        at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

当然,冻结不会发生

  • DummyTest 被忽略 (@Ignore)
  • AND 当 throw new RuntimeException() 从 RxJava 的 onError 处理程序中删除

./gradlew tests --debug 表明在同一测试之后似乎有无休止的等待“守护进程地址注册

来自日志的片段:

2021-03-12T15:15:55.747-0500 [DEBUG] [TestEventLogger] com.myapp.DummyTest > testErrorCase STARTED
2021-03-12T15:15:55.756-0500 [DEBUG] [TestEventLogger] 
2021-03-12T15:15:55.756-0500 [DEBUG] [TestEventLogger] com.myapp.DummyTest > testErrorCase STANDARD_ERROR
2021-03-12T15:15:55.757-0500 [DEBUG] [TestEventLogger]     io.reactivex.exceptions.CompositeException: 2 exceptions occurred. 
2021-03-12T15:15:55.757-0500 [DEBUG] [TestEventLogger]          at io.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver
//...
2021-03-12T15:15:55.760-0500 [DEBUG] [TestEventLogger]       ComposedException 1 :
2021-03-12T15:15:55.760-0500 [DEBUG] [TestEventLogger]          java.lang.UnkNownError: something went wrong
2021-03-12T15:15:55.760-0500 [DEBUG] [TestEventLogger]                  at com.myapp.DummyTest.testErrorCase(DummyTest.kt:17)
2021-03-12T15:15:55.760-0500 [DEBUG] [TestEventLogger]                  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
2021-03-12T15:
//...
2021-03-12T15:15:55.763-0500 [DEBUG] [TestEventLogger]       ComposedException 2 :
2021-03-12T15:15:55.763-0500 [DEBUG] [TestEventLogger]          java.lang.RuntimeException: something went wrong
2021-03-12T15:15:55.764-0500 [DEBUG] [TestEventLogger]                  at com.myapp.Dummy$2.accept(Dummy.kt:12)
2021-03-12T15:15:55.764-0500 [DEBUG] [TestEventLogger]                  at com.myapp.Dummy$2.accept(Dummy.kt:6)
//...2021-03-12T15:15:55.767-0500 [DEBUG] [TestEventLogger] 

2021-03-12T15:15:58.516-0500 [LIFECYCLE] [org.gradle.cache.internal.DefaultFileLockManager] 
2021-03-12T15:15:58.516-0500 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Waiting to acquire shared lock on daemon addresses registry.
2021-03-12T15:15:58.516-0500 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Lock acquired on daemon addresses registry.
2021-03-12T15:15:58.516-0500 [DEBUG] [org.gradle.cache.internal.DefaultFileLockManager] Releasing lock on daemon addresses registry.

2021 年 3 月 15 日更新 看起来可能是 Firebase Crashlytics 导致了这种情况 当测试套件挂起时

jps -lv 给出:

41920 org.gradle.launcher.daemon.bootstrap.GradleDaemon -Xmx5120M -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant
42356 worker.org.gradle.process.internal.worker.GradleWorkerMain -Djava.awt.headless=true -Djava.security.manager=worker.org.gradle.process.internal.worker.child.BootstrapSecurityManager -Dorg.gradle.native=false -javaagent:build/tmp/expandedArchives/org.jacoco.agent-0.8.5.jar_6a2df60c47de373ea127d14406367999/jacocoagent.jar=destfile=build/jacoco/testDebugUnitTest.exec,append=true,inclnolocationclasses=true,dumponexit=true,output=file,jmx=false -Xmx512m -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant -ea
42805 sun.tools.jps.Jps -Dapplication.home=/Library/Java/JavaVirtualMachines/jdk1.8.0_261.jdk/Contents/Home -xms8m
41979 org.jetbrains.kotlin.daemon.KotlinCompileDaemon -Djava.awt.headless=true -Djava.rmi.server.hostname=127.0.0.1 -Xmx5120M -Dkotlin.environment.keepalive
41963 org.gradle.wrapper.GradleWrapperMain -Dorg.gradle.appname=gradlew
41500  -xms256m -Xmx1280m -XX:ReservedCodeCacheSize=240m -XX:+UseConcmarkSweepGC -XX:SoftRefLRUPolicyMSPerMB=50 -XX:CICompilerCount=2 -Dsun.io.useCanonPrefixCache=false -Djdk.http.auth.tunneling.disabledSchemes="" -Djdk.attach.allowAttachSelf=true -Dkotlinx.coroutines.debug=off -Djdk.module.illegalAccess.silent=true -Djna.nosys=true -Djna.boot.library.path= -Didea.vendor.name=Google -XX:+UseCompressedOops -Dfile.encoding=UTF-8 -XX:ErrorFile=/Users/ericn/java_error_in_studio_%p.log -XX:HeapDumpPath=/Users/ericn/java_error_in_studio.hprof -Xmx2048m -Djb.vmOptionsFile=/Applications/Android Studio.app/Contents/bin/studio.vmoptions,/Users/ericn/Library/Application Support/Google/AndroidStudio4.1/studio.vmoptions -Didea.paths.selector=AndroidStudio4.1 -Didea.executable=studio -Didea.platform.prefix=AndroidStudio -Didea.vendor.name=Google -Didea.home.path=/Applications/Android Studio.app/Contents

jstack -l 给出:

"Test worker" #20 prio=5 os_prio=31 tid=0x00007ff88ba63800 nid=0x6003 waiting on condition [0x0000700004a77000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000007b9736258> (a java.util.concurrent.CountDownLatch$Sync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
    at com.google.firebase.crashlytics.internal.common.Utils.awaitEvenIfOnMainThread(Utils.java:183)
    at com.google.firebase.crashlytics.internal.common.CrashlyticsController.handleUncaughtException(CrashlyticsController.java:453)
    - locked <0x00000007adde9d08> (a com.google.firebase.crashlytics.internal.common.CrashlyticsController)
    at com.google.firebase.crashlytics.internal.common.CrashlyticsController$5.onUncaughtException(CrashlyticsController.java:361)
    at com.google.firebase.crashlytics.internal.common.CrashlyticsUncaughtExceptionHandler.uncaughtException(CrashlyticsUncaughtExceptionHandler.java:54)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1057)
    at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1052)
    at io.reactivex.plugins.RxJavaPlugins.uncaught(RxJavaPlugins.java:429)
    at io.reactivex.plugins.RxJavaPlugins.onError(RxJavaPlugins.java:383)
    at io.reactivex.internal.observers.ConsumerSingleObserver.onError(ConsumerSingleObserver.java:49)
    at io.reactivex.internal.disposables.Emptydisposable.error(Emptydisposable.java:78)
    at io.reactivex.internal.operators.single.SingleError.subscribeActual(SingleError.java:42)
    at io.reactivex.Single.subscribe(Single.java:3603)
    at io.reactivex.Single.subscribe(Single.java:3589)
    at com.myapp.Dummy.<init>(Dummy.kt:9)
    at com.myapp.DummyTest.testErrorCase(DummyTest.kt:18)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runchild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runchildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
    at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
    at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
    at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
    at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassprocessor.processtestClass(AbstractJUnitTestClassprocessor.java:62)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassprocessor.processtestClass(SuiteTestClassprocessor.java:51)
    at sun.reflect.GeneratedMethodAccessor102.invoke(UnkNown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.Reflectiondispatch.dispatch(Reflectiondispatch.java:36)
    at org.gradle.internal.dispatch.Reflectiondispatch.dispatch(Reflectiondispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderdispatch.dispatch(ContextClassLoaderdispatch.java:33)
    at org.gradle.internal.dispatch.ProxydispatchAdapter$dispatchingInvocationHandler.invoke(ProxydispatchAdapter.java:94)
    at com.sun.proxy.$Proxy2.processtestClass(UnkNown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processtestClass(TestWorker.java:118)
    at sun.reflect.GeneratedMethodAccessor101.invoke(UnkNown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.gradle.internal.dispatch.Reflectiondispatch.dispatch(Reflectiondispatch.java:36)
    at org.gradle.internal.dispatch.Reflectiondispatch.dispatch(Reflectiondispatch.java:24)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedobjectConnection$dispatchWrapper.dispatch(MessageHubBackedobjectConnection.java:182)
    at org.gradle.internal.remote.internal.hub.MessageHubBackedobjectConnection$dispatchWrapper.dispatch(MessageHubBackedobjectConnection.java:164)
    at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
    at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
    at java.lang.Thread.run(Thread.java:748)

   Locked ownable synchronizers:
    - <0x00000007a0026f20> (a java.util.concurrent.ThreadPoolExecutor$Worker)

Crashlytics 源代码 CrashlyticsController:

synchronized void handleUncaughtException(@NonNull final SettingsDataProvider settingsDataProvider,@NonNull final Thread thread,@NonNull final Throwable ex) {
        // ....

        try {
            Utils.awaitEvenIfOnMainThread(handleUncaughtExceptionTask);
        } catch (Exception var7) {
        }

    }

看起来 Crashlytics 没有在 catch {} 块中做任何事情,让测试运行器永远等待?

或者,latch.await() 中的 Utils.awaitEvenIfOnMainThread 只是永远阻塞线程?

Full log here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。