我正在尝试运行UI测试。当我不模拟任何注入依赖时,一切运行良好。当我切换模块的@Provides返回到模拟对象时,我收到以下消息:
开始运行测试
测试仪器过程崩溃。
检查 com.nerfy.features.core.CoreTest#a_shouldDisplayLocationPermissionRequestDialogAtStartup.txt 详情。
测试已完成。
我无法在任何地方找到这个txt文件,只有一些测试xml根本没有提供信息。
编辑:该文件仅包含:INSTRUMENTATION_RESULT:shortMsg =进程崩溃。 INSTRUMENTATION_CODE:0。
应用程序效果不错。
申请代码:
public class Nerfy extends Application {
private AppComponent appComponent;
public static Nerfy get(Context context) {
return (Nerfy) context.getApplicationContext();
}
@Override
public void onCreate() {
super.onCreate();
System.out.println("on create");
if (appComponent == null) {
appComponent = buildProdAppComponent();
appComponent.inject(this);
}
}
public AppComponent buildProdAppComponent() {
return DaggerAppComponent.builder()
.appModule(new AppModule(this))
.navigationModule(new NavigationModule())
.refreshModule(new RefreshModule())
.repoModule(new RepoModule())
.sharedDataModule(new SharedDataModule())
.threadsModule(new ThreadsModule())
.build();
}
//@VisibleForTesting
public void setAppComponent(AppComponent appComponent) {
System.out.println("on set");
this.appComponent = appComponent;
this.appComponent.inject(this);
}
public AppComponent getAppComponent() {
return appComponent;
}
}
以下是一些测试代码:
@RunWith(AndroidJUnit4.class)
@LargeTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class CoreTest {
private UiDevice device;
public SharedData sharedData;
private AppComponent espressoAppComponent;
@Rule
public ActivityTestRule<Core> mActivityRule =
new ActivityTestRule<Core>(Core.class) {
@Override
protected void beforeActivityLaunched() {
System.out.println("beforeActivityLaunched");
sharedData = mock(SharedData.class);
System.out.println("shared data " + sharedData);
espressoAppComponent = DaggerAppComponent.builder()
.appModule(new AppModule((Application) getTargetContext().getApplicationContext()))
.navigationModule(new NavigationModule())
.refreshModule(new RefreshModule())
.repoModule(new RepoModule())
.sharedDataModule(new SharedDataModule(){
@Override
public SharedData providesSharedData(Application application) {
return sharedData;
}
})
.threadsModule(new ThreadsModule())
.build();
((Nerfy) getTargetContext().getApplicationContext()).setAppComponent(espressoAppComponent);
super.beforeActivityLaunched();
}
};
@Before
public void setUp() {
}
@Test
@SdkSuppress(minSdkVersion = 23)
public void a_shouldDisplayLocationPermissionRequestDialogAtStartup() throws Exception {
assertViewWithTextIsVisible(device, TEXT_ALLOW);
assertViewWithTextIsVisible(device, TEXT_DENY);
denyCurrentPermission(device);
}
什么都没打印出来。
但是,如果我将模拟的共享数据切换到真实的
@Override
public SharedData providesSharedData(Application application) {
return super.providesSharedData(application);
一切运行良好,测试失败,因为共享数据没有被模拟。 然后我还注意到应用程序onCreate在测试活动规则之前调用了beforeActivityLaunched,尽管在一些教程中他们说应该在创建应用程序之前调用它。
我已经按照教程了 http://blog.sqisland.com/2015/04/dagger-2-espresso-2-mockito.html
Android Mocking a Dagger2 injected dependency for a Espresso test
How do you override a module/dependency in a unit test with Dagger 2.0?
和类似;也是官方的dagger2文档。
我已经尝试了子类化应用程序,只为测试创建新模型和子类化组件;也不会在setUp()结束之前启动activityRule,之后在这里注入组件而不是覆盖beforeActivityLaunched()。
还尝试了一些简单的修复,比如重建项目,重启android studio,更新依赖项。
模拟其他模块也会带来相同的结果,而模仿其他模块也可以正常工作。
有什么想法吗?
答案 0 :(得分:3)
我测试了其他模块。发现模拟的Refresher模块会因为它具有Observable字段而导致测试过程崩溃。测试活动试图订阅它,但它是空的。
SharedData更难以弄清楚 - 它处理共享首选项,所以基本上只是字符串和布尔值。我必须检查所有用法。在尝试将字符串值作为url(未经过模拟,再次为null)时,崩溃发生在Picasso上以获取图像。
故事的道德 - 一个正确的崩溃消息值得两天盲目调试。
答案 1 :(得分:0)
我认为问题是System.out.print
方法。尝试删除所有它们并运行代码。
使用Log.e
或Log.i
代替获取输出,稍后再获取日志。
答案 2 :(得分:0)
对我来说,我无法在模拟器上(仅在物理设备上)运行UI工具测试。切换到使用64位x86 ABI可以解决此问题。 https://github.com/android/android-test/issues/352