當我在佈局一個進度正在運行的一些咖啡,測試時顯示的 - 然後我跑到:ProgressBars和咖啡
Caused by: android.support.test.espresso.AppNotIdleException: Looped for 1670 iterations over 60 SECONDS. The following Idle Conditions failed .
什麼是一個很好的解決這樣?發現一些hackish的東西,但尋找一個不錯的方法
當我在佈局一個進度正在運行的一些咖啡,測試時顯示的 - 然後我跑到:ProgressBars和咖啡
Caused by: android.support.test.espresso.AppNotIdleException: Looped for 1670 iterations over 60 SECONDS. The following Idle Conditions failed .
什麼是一個很好的解決這樣?發現一些hackish的東西,但尋找一個不錯的方法
我有同樣的問題。我無法弄清楚一個完美的解決方案,但我會發布我的方法。
我試圖做的是重寫ProgressBar上的indeterminateDrawable
。當有一個簡單的drawable時,不會發生動畫,Espresso測試不會遇到空閒問題。
不幸的是main
和androidTest
的處理方法是相同的。我沒有找到一種方法來覆蓋ProgressBar的樣式。
現在它結合了https://gist.github.com/Mauin/62c24c8a53593c0a605e#file-progressbar-java和How to detect whether android app is running UI test with Espresso的一些想法。
起初,我創建了自定義的ProgressBar類,一個用於調試,另一個用於發佈。發佈版本只調用超級構造函數,不做別的。調試版本覆蓋方法setIndeterminateDrawable
。有了這個,我可以設置一個簡單的drawable而不是動畫。
發行代碼:
public class ProgressBar extends android.widget.ProgressBar {
public ProgressBar(Context context) {
super(context);
}
public ProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
}
調試代碼:
public class ProgressBar extends android.widget.ProgressBar {
public ProgressBar(Context context) {
super(context);
}
public ProgressBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ProgressBar(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@SuppressWarnings("deprecation")
@Override
public void setIndeterminateDrawable(Drawable d) {
if (isRunningTest()) {
d = getResources().getDrawable(R.drawable.ic_replay);
}
super.setIndeterminateDrawable(d);
}
private boolean isRunningTest() {
try {
Class.forName("base.EspressoTestBase");
return true;
} catch (ClassNotFoundException e) {
/* no-op */
}
return false;
}
}
正如你可以看到我還添加了一個檢查,如果我的應用程序正在運行的咖啡測試,而我正在尋找的類我的Espresso測試的基礎。
不好的一點是您必須更新所有代碼才能使用您的自定義ProgressBar。但好處是您的發行版代碼不會對此解決方案產生重大影響。
基於Thomas R. solution,另一種方法是更改測試中ProgressBar的drawable,以避免修改生產代碼。
實施例:
Activity activity = startActivity();
// override progress bar infinite animation with a simple image
ProgressBar progressBar = (ProgressBar) activity.findViewById(R.id.loading_progressbar);
progressBar.setIndeterminateDrawable(activity.getDrawable(android.R.drawable.ic_lock_lock));
// click on the button that triggers the display of the progress bar
onView(withId(R.id.login_button)).perform(click());
如果ProgressBar
是看不見的測試開始時,Drawable
可以與由定製ViewAction
代替:
// Replace the drawable with a static color
onView(isAssignableFrom(ProgressBar.class)).perform(replaceProgressBarDrawable());
// Click a button (that will make the ProgressBar visible)
onView(withText("Show ProgressBar").perform(click());
定製ViewAction
:
public static ViewAction replaceProgressBarDrawable() {
return actionWithAssertions(new ViewAction() {
@Override
public Matcher<View> getConstraints() {
return isAssignableFrom(ProgressBar.class);
}
@Override
public String getDescription() {
return "replace the ProgressBar drawable";
}
@Override
public void perform(final UiController uiController, final View view) {
// Replace the indeterminate drawable with a static red ColorDrawable
ProgressBar progressBar = (ProgressBar) view;
progressBar.setIndeterminateDrawable(new ColorDrawable(0xffff0000));
uiController.loopMainThreadUntilIdle();
}
});
}
我有類似的問題。早在第一次調用getActivity()時,測試就失敗了。因此,ProgressBar的不確定drawable必須在活動開始後被替換。
Application application = (Application)this.getInstrumentation().getTargetContext().getApplicationContext();
application.registerActivityLifecycleCallbacks(new Application.ActivityLifecycleCallbacks() {
@Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
//not here, it's too early
}
@Override
public void onActivityStarted(Activity activity) {
//find the progressBar in your activity
ProgressBar progressBar = ((ProgressBar) activity.findViewById(R.id.progress_bar));
if(progressBar != null) {
//replace progress bar drawable as not animated
progressBar.setIndeterminateDrawable(new ColorDrawable(0xffff0000));
}
}
@Override
public void onActivityResumed(Activity activity) {
}
@Override
public void onActivityPaused(Activity activity) {
}
@Override
public void onActivityStopped(Activity activity) {
}
@Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
@Override
public void onActivityDestroyed(Activity activity) {
}
});
//Now you can start the activity
getActivity();
謝謝!進度條出現在創建活動時非常有用。 – thenaoh
這是絕妙的解決方案。我只是把這個代碼包裝在一個靜態的'@ ClassRule'中。無需更改應用程序代碼,這正是我所需要的。 –
此答案可能會很晚。用濃咖啡,你必須關閉動畫。
在設備上,設置>開發人員選項禁用 以下3個設置:
窗口動畫縮放,過渡動畫縮放,動畫長比例
https://developer.android.com/training/testing/espresso/setup.html#set-up-environment
有是在Testing progress bar on Android with Espresso由riwnodennyk回答
但要謹慎UIAnimator
注意:我們建議您使用測試的Automator UI只有當 您的應用程序必須與系統交互來滿足關鍵用途情況下,你的應用程序。 由於UI Automator與系統應用程序和用戶界面交互,因此需要在每次系統更新後重新運行並修復UI Automator測試。這樣的 更新包括Android平臺版本升級和 Google Play服務的新版本。作爲使用UI Automator的替代方案,我們建議添加密封測試或將大型測試分爲 套小型和中型測試。尤其要重點測試一次應用程序間通信,例如將 信息發送到其他應用程序並對意圖結果進行響應。意大利濃咖啡工具可幫助您編寫這些較小的測試。
https://developer.android.com/training/testing/fundamentals.html#large-tests
這爲我工作,並在這裏似乎是最直接的解決方案。 – MungoRae
此解決方案是最好的,因爲避免因爲測試而需要修改生產代碼 – pablisco