基础配置以及常见错误
目前版本的Android Studio 3.6.3/4.0/4.1/4.2使用Robolectric-3.8/4.3.1/4.5.1/4.6.1,只能配合Powermock-1.6.6,不能高于这个版本PowerMock ,尽管软件源中的版本已经更新升级到2.0.7版本了,但是Robolectric并没有及时更新依赖。尝试过使用最新版本的PowerMock,结果很多莫名的报错。
// 单元测试 testImplementation "com.android.support.test:runner:1.0.2" testImplementation "junit:junit:4.13.2" testImplementation "org.robolectric:robolectric:4.5.1" // 注意AndroidX环境下,不能引入shadows-supportv4,Jetifier转换的时候报错 testImplementation "org.robolectric:shadows-supportv4:4.5.1" // MultiDex支持 testImplementation "org.robolectric:shadows-multidex:4.5.1" // 此处版本更新需要特别小心,目前 robolectric 跟 powermock 存在兼容问题, // 需要固定的某些版本才能正常配合 // 依赖关系参考 // https://github.com/robolectric/robolectric/wiki/Using-PowerMock testImplementation "org.powermock:powermock-module-junit4:1.6.6" testImplementation "org.powermock:powermock-module-junit4-rule:1.6.6" testImplementation "org.powermock:powermock-classloading-xstream:1.6.6" testImplementation "org.powermock:powermock-api-mockito:1.6.6"
如果 Windows 系统下出现如下提示,受限于Windows系统路径不能超过260个字符的限制
13:36 Error running 'xxxTest': Command line is too long. Shorten command line for xxxTest or also for Android JUnit default configuration.
貌似Windows 10 Build 14352版中已经可以通过修改注册表去除260字符的路径长度限制了。
在项目`/.idea/workspace.xml`文件中添加一行代码如下
<component name="PropertiesComponent"> ... <property name="dynamic.classpath" value="true" /> </component>
对于使用MultiDex的应用,如果报告如下错误:
java.lang.RuntimeException: MultiDex installation failed (/var/folders/h6/4__l0pyn32j1mkkysynnxydr0000gn/T/robolectric-Method_xxxxxxxxxxxx_isCorrect4035485067136008322/com.xxxx.xxxx.app-sourceDir (Is a directory)). at android.support.multidex.MultiDex.install(MultiDex.java:121) at com.xxx.xx.app.xx.application.xxxxxx.attachBaseContext(MyApplication.java:212) at android.app.Application.attach(Application.java:212) at org.robolectric.util.ReflectionHelpers.callInstanceMethod(ReflectionHelpers.java:283) at org.robolectric.shadows.ShadowApplication.callAttach(ShadowApplication.java:79) at org.robolectric.android.internal.AndroidTestEnvironment.installAndCreateApplication(AndroidTestEnvironment.java:250) at org.robolectric.android.internal.AndroidTestEnvironment.setUpApplicationState(AndroidTestEnvironment.java:169) at org.robolectric.RobolectricTestRunner.beforeTest(RobolectricTestRunner.java:301) at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:243) at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89) at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) at java.util.concurrent.FutureTask.run(FutureTask.java) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
需要在`build.gradle`中引入
// MultiDex支持 testImplementation "org.robolectric:shadows-multidex:4.5.1"
例子测试代码:
package com.mobibrw.example; import org.junit.Test; import static org.junit.Assert.*; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; import org.robolectric.shadows.multidex.ShadowMultiDex; /** * Example local unit test, which will execute on the development machine (host). * * @see <a href="http://d.android.com/tools/testing">Testing documentation</a> */ @RunWith(RobolectricTestRunner.class) @PowerMockIgnore("jdk.internal.reflect.*") @Config(shadows = ShadowMultiDex.class) public class ExampleUnitTest { @Test public void addition_isCorrect() { assertEquals(4, 2 + 2); } }
注意,需要
@Config(shadows = ShadowMultiDex.class)
才能使得配置生效。
如果发生如下错误:
java.lang.VerifyError: Expecting a stackmap frame at branch target 43 Exception Details: Location: com/meizu/cloud/pushsdk/base/IntentReceiver.onReceive(Landroid/content/Context;Landroid/content/Intent;)V @6: ifne Reason: Expected stackmap frame at this location. Bytecode: 0x0000000: b200 08b6 0013 9a00 25bb 0004 5912 0110 0x0000010: 0ab7 000e 59b3 000a b600 10bb 0003 59b2 0x0000020: 000a b600 0fb7 000c b300 09b2 0009 bb00 0x0000030: 0659 2a2b 2cb7 0011 b600 0d57 b1 at java.lang.Class.getDeclaredConstructors0(Native Method) at java.lang.Class.privateGetDeclaredConstructors(Class.java:2671) at java.lang.Class.getConstructor0(Class.java:3075) at java.lang.Class.getDeclaredConstructor(Class.java:2178) at org.robolectric.util.ReflectionHelpers.callConstructor(ReflectionHelpers.java:396) at org.robolectric.internal.bytecode.ShadowImpl.newInstanceOf(ShadowImpl.java:18) at org.robolectric.shadow.api.Shadow.newInstanceOf(Shadow.java:35) at org.robolectric.android.internal.AndroidTestEnvironment.registerBroadcastReceivers(AndroidTestEnvironment.java:541) at org.robolectric.android.internal.AndroidTestEnvironment.installAndCreateApplication(AndroidTestEnvironment.java:265) at org.robolectric.android.internal.AndroidTestEnvironment.setUpApplicationState(AndroidTestEnvironment.java:169) at org.robolectric.RobolectricTestRunner.beforeTest(RobolectricTestRunner.java:301) at org.robolectric.internal.SandboxTestRunner$2.lambda$evaluate$0(SandboxTestRunner.java:243) at org.robolectric.internal.bytecode.Sandbox.lambda$runOnMainThread$0(Sandbox.java:89) at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) at java.util.concurrent.FutureTask.run(FutureTask.java) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
继续阅读Android Studio 3.6.3/4.0/4.1/4.2配置Robolectric-3.8/4.3.1/4.5.1/4.6.1 Powermock-1.6.6单元测试环境