如何从 Espresso 中获取视图以传递到 IdlingResource?
How to get a view from within Espresso to pass into an IdlingResource?
我基本上有一个自定义 IdlingResource
,它接受一个 View
构造函数参数。我找不到任何地方真正谈论如何实现它。
我正在尝试使用这个答案:
如您所见,它需要 ViewPager
,但是当我在测试 class 中注册 IdlingResource
时,我不确定如何获得我的查看。
我试过 findViewById()
,我试过获取当前 运行 activity 然后调用 findViewById()
,但没有成功。
有人知道在这种情况下该怎么办吗?
我还没有在 Espresso
中使用过 IdilingResources
,但是你看过这些文章了吗:
- Espresso: Custom Idling Resource by Chiuki
- Wait for it...a deep dive into Espresso's Idling Resources
另请查看官方Android文档:Idling Resources (reference)
为了回答你的问题,
最好的方法是将其中一个视图的实例传递到 class 的构造函数中。检查:Calling findViewById() from outside an activity
另一种方法是根据上下文获取视图。检查 android - How to get view from context?
这是一个取自上面 link 的例子:
Starting with a context, the root view of the
associated activity can be had by
View rootView = ((Activity)_context).Window.DecorView.FindViewById(Android.Resource.Id.Content);
In Raw Android it'd look something like:
View rootView = ((Activity)mContext).getWindow().getDecorView().findViewById(android.R.id.content)
Then simply call the findViewById on this
View v = rootView.findViewById(R.id.your_view_id);
这可能也有用:How to call getResources() from a class which has no context?
希望对您有所帮助
想通了。要让视图传递到空闲资源中,您所要做的就是获取 ActivityTestRule
的成员变量
例如:
@Rule
public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<>(
MainActivity.class);
然后只需调用 getActivity().findViewById(R.id.viewId)
所以最后的结果是:
activityTestRule.getActivity().findViewById(R.id.viewId);
只要同一 activity 中的测试 运行,接受的答案就有效。但是,如果测试导航到另一个 activity activityTestRule.getActivity()
将 return 错误 activity (第一个)。为了解决这个问题,可以创建一个辅助方法 returning 一个实际的 activity:
public Activity getCurrentActivity() {
final Activity[] currentActivity = new Activity[1];
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
Collection<Activity> allActivities = ActivityLifecycleMonitorRegistry.getInstance()
.getActivitiesInStage(Stage.RESUMED);
if (!allActivities.isEmpty()) {
currentActivity[0] = allActivities.iterator().next();
}
}
});
return currentActivity[0];
}
然后可以这样使用:
Activity currentActivity = getCurrentActivity();
if (currentActivity != null) {
currentActivity.findViewById(R.id.viewId);
}
如果您使用 androidx.test.ext.junit.rules
中的 ActivityScenarioRule
(因为 ActivityTestRule
"will be deprecated and eventually removed from library in the future"),您可以获取 Activity
实例并调用 findViewById
方法:
import androidx.test.ext.junit.rules.activityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
@RunWith(AndroidJUnit4::class) {
@get: Rule
var testRule = activityScenarioRule<MainActivity>()
@Test
fun mainTestCase() {
testRule.scenario.onActivity { activity ->
val view = activity.findViewById<YourView>(R.id.view)
}
}
}
我基本上有一个自定义 IdlingResource
,它接受一个 View
构造函数参数。我找不到任何地方真正谈论如何实现它。
我正在尝试使用这个答案:
如您所见,它需要 ViewPager
,但是当我在测试 class 中注册 IdlingResource
时,我不确定如何获得我的查看。
我试过 findViewById()
,我试过获取当前 运行 activity 然后调用 findViewById()
,但没有成功。
有人知道在这种情况下该怎么办吗?
我还没有在 Espresso
中使用过 IdilingResources
,但是你看过这些文章了吗:
- Espresso: Custom Idling Resource by Chiuki
- Wait for it...a deep dive into Espresso's Idling Resources
另请查看官方Android文档:Idling Resources (reference)
为了回答你的问题,
最好的方法是将其中一个视图的实例传递到 class 的构造函数中。检查:Calling findViewById() from outside an activity
另一种方法是根据上下文获取视图。检查 android - How to get view from context?
这是一个取自上面 link 的例子:
Starting with a context, the root view of the associated activity can be had by
View rootView = ((Activity)_context).Window.DecorView.FindViewById(Android.Resource.Id.Content);
In Raw Android it'd look something like:
View rootView = ((Activity)mContext).getWindow().getDecorView().findViewById(android.R.id.content)
Then simply call the findViewById on this
View v = rootView.findViewById(R.id.your_view_id);
这可能也有用:How to call getResources() from a class which has no context?
希望对您有所帮助
想通了。要让视图传递到空闲资源中,您所要做的就是获取 ActivityTestRule
的成员变量例如:
@Rule
public ActivityTestRule<MainActivity> activityTestRule = new ActivityTestRule<>(
MainActivity.class);
然后只需调用 getActivity().findViewById(R.id.viewId)
所以最后的结果是:
activityTestRule.getActivity().findViewById(R.id.viewId);
只要同一 activity 中的测试 运行,接受的答案就有效。但是,如果测试导航到另一个 activity activityTestRule.getActivity()
将 return 错误 activity (第一个)。为了解决这个问题,可以创建一个辅助方法 returning 一个实际的 activity:
public Activity getCurrentActivity() {
final Activity[] currentActivity = new Activity[1];
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
@Override
public void run() {
Collection<Activity> allActivities = ActivityLifecycleMonitorRegistry.getInstance()
.getActivitiesInStage(Stage.RESUMED);
if (!allActivities.isEmpty()) {
currentActivity[0] = allActivities.iterator().next();
}
}
});
return currentActivity[0];
}
然后可以这样使用:
Activity currentActivity = getCurrentActivity();
if (currentActivity != null) {
currentActivity.findViewById(R.id.viewId);
}
如果您使用 androidx.test.ext.junit.rules
中的 ActivityScenarioRule
(因为 ActivityTestRule
"will be deprecated and eventually removed from library in the future"),您可以获取 Activity
实例并调用 findViewById
方法:
import androidx.test.ext.junit.rules.activityScenarioRule
import androidx.test.ext.junit.runners.AndroidJUnit4
@RunWith(AndroidJUnit4::class) {
@get: Rule
var testRule = activityScenarioRule<MainActivity>()
@Test
fun mainTestCase() {
testRule.scenario.onActivity { activity ->
val view = activity.findViewById<YourView>(R.id.view)
}
}
}