2015-09-25 3 views
1

Я хочу иметь Espresso монитор Picasso как IdlingResource, так что я могу запустить ViewMatcher s, как только изображение будет успешно загружено.Мониторинг Picasso для IdlingResource в Espresso

От навигации по исходному коду Picasso я не понимаю, почему это не работает. Вот что я пробовал:

Picasso picasso = new Picasso.Builder(context).build(); 
Field dispatcherField = Picasso.class.getDeclaredField("dispatcher"); 
dispatcherField.setAccessible(true); 

try { 
    Dispatcher dispatcher = (Dispatcher) dispatcherField.get(picasso); 
    Espresso.registerLooperAsIdlingResource(dispatcher.dispatcherThread.getLooper()); 
} catch (NoSuchFieldException e) { 
    throw new PicassoHasBeenRefactoredException(); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

onView(withId(R.id.image_view)).check(matches(withImage(R.drawable.drawable))); 

(да, я знаю, что отражает это неприглядное, но я не мог найти другой способ получить ручку на Looper)

Но это приводит к ошибке при попытке чтобы получить Bitmap от ImageView:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.Bitmap android.graphics.drawable.BitmapDrawable.getBitmap()' on a null object reference 

чтобы проверить, что тест работает, как ожидается, когда изображение было загружено, я попытался введения Thread.sleep(1000) вместо этого IdlingResource проверки ап d он прошел.

Можно ли предположить, что IdlingResource не был настроен правильно и, что более важно, что было бы правильным способом подождать, пока Пикассо завершит загрузку, прежде чем проверять виды с помощью Espresso?

+0

вы не можете использовать [onSucess обратного вызова] (https://square.github.io/picasso/javadoc/com/squareup/picasso/Callback.html # onSuccess--) от Picasso для настройки вашего IdelingResource? –

+0

@RahulTiwari Я не хочу изменять какой-либо производственный код для размещения тестов, если вы не имели в виду что-то еще? –

+0

Я говорил об использовании обратных вызовов, которые Пикассо предоставляет 'onSuccess' и' onError' и, если возможно, избавляется от отражения. Так что да, я говорил о модификации кода, но это не повлияет на какую-либо функциональность. –

ответ

2

Я использую IdlingResource, который проверяет, остались ли действия.

Обратите внимание, что IdlingResource должны жить в том же пакете, Пикассо, чтобы получить доступ к пакету защищен переменной

package com.squareup.picasso; 

public class PicassoIdlingResource implements IdlingResource, ActivityLifecycleCallback { 
    protected ResourceCallback callback; 

    WeakReference<Picasso> picassoWeakReference; 

    @Override 
    public String getName() { 
    return "PicassoIdlingResource"; 
    } 

    @Override 
    public boolean isIdleNow() { 
    if (isIdle()) { 
     notifyDone(); 
     return true; 
    } else { 
     return false; 
    } 
    } 

    public boolean isIdle() { 
    return picassoWeakReference == null 
      || picassoWeakReference.get() == null 
      || picassoWeakReference.get().targetToAction.isEmpty(); 
    } 

    @Override 
    public void registerIdleTransitionCallback(ResourceCallback resourceCallback) { 
    this.callback = resourceCallback; 
    } 

    void notifyDone() { 
    if (callback != null) { 
     callback.onTransitionToIdle(); 
    } 
    } 

    @Override 
    public void onActivityLifecycleChanged(Activity activity, Stage stage) { 
    switch (stage) { 
     case CREATED: 
     picassoWeakReference = new WeakReference<>(Picasso.with(activity)); 
     break; 
     case STOPPED: 
     // Clean up reference 
     picassoWeakReference = null; 
     break; 
     default: // NOP 
    } 
    } 
} 

Я не думаю, что с помощью WeakReference необходимо, но это не повредит.

Кроме того, я идентифицировал один случай, когда он не дожидался окончания Пикассо (при использовании . (Null)). Таким образом, используйте на свой страх и риск и, пожалуйста, вернитесь, если вы его улучшите.

Смотрите суть для получения подробной информации и использования (https://gist.github.com/Maragues/0c0db81a137c8d067396)

+0

Спасибо! Решение работает некорректно при перемещении между действиями. Чтобы исправить это, я заменил состояния CREATED & STOPPED на ** RESUMED & PAUSED ** –

+0

Также я обнаружил, что это приводит к большим задержкам (** до 5 секунд задержки на загруженное изображение **), потому что Espresso имеет задержку в несколько секунд между повторами, чеки. Решение состоит в том, чтобы принудительно повторить проверку на PicassoIdlingResource, как в этом примере: https://gist.github.com/vaughandroid/e2fda716c7cf6853fa79#file-viewvisibilityidlingresource-java-L62 –

+0

Спасибо @SebasLG, я сейчас в другом проекте, Проверьте свой код, как только я вернусь к старой. – Maragues