2013-04-07 17 views
6

Qualcuno prova l'Android UITesting framework UIAutomator? Quando uso la classe UiScrollabl "per trovare alcuni oggetti in una scorrevole oggetto , non riesce a trovare l'oggetto se la lunghezza del scorrevole oggetto è troppo lungo (necessario scorrere due volte per trovarlo), come "opzioni sviluppatore" nella "Impostazioni" app. qualcuno ha lo stesso problema?UiScrollable non funziona su Android uiautomator

risposta

3

Potete fornire qualche dettaglio in più si prega esempio

  • Quale versione di ADT stai usando?
  • Quale versione di Android sono i test che vengono eseguiti in/on ?

Il motivo per cui faccio queste domande è perché ci sono alcuni problemi specifici della versione con UIAutomator. Ad esempio ho scoperto un problema di scorrimento in esecuzione su dispositivi con 4.2.2 di Android che sembra simile a quello che hai citato. Ho codificato una soluzione alternativa in cui il mio codice esegue lo scorrimento se il metodo standard di Android non sembra trovare l'elemento che mi aspetto di essere disponibile.

ho riprodotto l'essenza del mio codice qui, troverete l'esempio completo in http://blog.bettersoftwaretesting.com/?p=84

 // The following loop is to workaround a bug in Android 4.2.2 which 
     // fails to scroll more than once into view. 
     for (int i = 0; i < maxSearchSwipes; i++) { 

      try { 
       appToLaunch = appViews.getChildByText(selector, nameOfAppToLaunch); 
       if (appToLaunch != null) { 
        // Create a UiSelector to find the Settings app and simulate  
        // a user click to launch the app. 
        appToLaunch.clickAndWaitForNewWindow(); 
        break; 
       } 
      } catch (UiObjectNotFoundException e) { 
       System.out.println("Did not find match for " + e.getLocalizedMessage()); 
      } 

      for (int j = 0; j < i; j++) { 
       appViews.scrollForward(); 
       System.out.println("scrolling forward 1 page of apps."); 
      } 
     } 

Nota: Non so se questo codice risolverà il vostro problema in quanto non lo faccio avere un esempio della tua app. Se sei in grado di pubblicare i tuoi test e il layout XML dell'interfaccia utente pertinente, sarebbe più facile diagnosticare il problema.

+0

Potresti essere interessato alla correzione riportata di seguito, ignorando la classe di scrittura indiretta, poiché risolverà il problema in più punti. – newfivefour

+0

questa risposta ha funzionato per me ... la correzione qui sotto non è stata –

0
scrollableObject.scrollIntoView(btn_1); 
try {if(scrollableObject.scrollIntoView(btn_1)) 
    btn_1.click(); 
} 
catch (UiObjectNotFoundException e){ 
System.out.print("error1: "+e); 
} 

non so se questo può aiutarti ma questo è quello che faccio nella mia app. La prima riga è di farlo scorrere fino a trovare btn_1, quindi se trova l'oggetto, eseguirà un clic su di esso.

8

L'ho risolto eseguendo l'override di una classe UiScrollable.

public class UiScrollable extends com.android.uiautomator.core.UiScrollable { 

    public UiScrollable(UiSelector container) { 
     super(container); 
    } 

    @Override 
    public boolean scrollIntoView(UiSelector selector) throws UiObjectNotFoundException { 
     if (exists(getSelector().childSelector(selector))) { 
      return (true); 
     } else { 
      System.out.println("It doesn't exist on this page"); 
      // we will need to reset the search from the beginning to start search 
      scrollToBeginning(getMaxSearchSwipes()); 
      if (exists(getSelector().childSelector(selector))) { 
       return (true); 
      } 
      for (int x = 0; x < getMaxSearchSwipes(); x++) { 
       System.out.println("I'm going forward a page: " + x); 
       if(!scrollForward() && x!=0) { // x!=0 is the hack 
        return false; 
       } 

       if(exists(getSelector().childSelector(selector))) { 
        return true; 
       } 
      } 
     } 
     return false; 
    }  

} 

Ho copiato la fonte da: UiScrollable.java (che può essere superata a un certo punto, attenzione) e semplicemente ha cambiato la linea if(!scrollForward() && x!=0).

Dalle mie osservazioni, nel caso del codice di esempio sulla pagina di test dell'interfaccia utente di Google che scorre la schermata delle app per l'app delle impostazioni, il metodo scrollForwards() non riesce al primo tentativo. Dio solo sa perché.

Quanto sopra dice semplicemente se non riesce al primo scorrimento, continuare a prescindere. Se non riesce a scorrere sul secondo scroll, in effetti restituisce un errore.

1

Io in generale ho più fortuna con UiDevice di drag() rispetto ai metodi di Scrollable.

+0

Ottimo consiglio! Avevo problemi con elementi scorrevoli sovrapposti e trascinare era l'unica soluzione per questo. – Phil

4

Per trovare e qualsiasi elemento in una vista in cui è necessario lo scorrimento Ho utilizzato il metodo indicato di seguito e sembra funzionare correttamente.

public void searchForText(String searchText) 
      throws UiObjectNotFoundException { 
     UiScrollable textScroll = null; 
     UiObject text = null; 
     if (searchText != null) { 
      textScroll = new UiScrollable(new UiSelector().scrollable(true)); 
      textScroll.scrollIntoView(new UiSelector().text(searchText)); 
      text = new UiObject(new UiSelector().text(searchText)); 
      text.click(); 
     } 
    } 
+0

Strano ... questo metodo non ha funzionato neanche per me ... si comporta allo stesso modo di getChildByText ... smette di scorrere intorno a 67 elementi –

+0

Grazie. Funziona come previsto. – wojciii

1

Inoltre incontro lo getChildByText solo per scorrere una volta e cerco di rintracciarlo. Trovo che la causa principale potrebbe essere il sistema.

Quando si chiama il getChildByText, il suo flusso è:

getChildByText -> scrollIntoView -> scrollForward -> scrollSwipe 

In scrollSwipe, il sistema di comando colpo eseguito, attendere, di trovare tutte AccessibilityEvent e filtrare AccessibilityEvent.TYPE_VIEW_SCROLLED a schermo corrente. Questo passaggio rende nuovamente scorrevole l'UiScrollable o lo controlla alla fine.

Ma il bug è qui, il sistema non può tornare a destra AccessibilityEvent.

public boolean scrollSwipe(final int downX, final int downY, final int upX, final int upY, 
     final int steps) { 

    Runnable command = new Runnable() { 
     @Override 
     public void run() { 
      swipe(downX, downY, upX, upY, steps); 
     } 
    }; 

    // Collect all accessibility events generated during the swipe command and get the 
    // last event 
    ArrayList<AccessibilityEvent> events = new ArrayList<AccessibilityEvent>(); 

    runAndWaitForEvents(command, 
      new EventCollectingPredicate(AccessibilityEvent.TYPE_VIEW_SCROLLED, events), 
      Configurator.getInstance().getScrollAcknowledgmentTimeout()); 

    //**Root cause** 
    //Some times the events list size will be 0 , 
    //but in fact it can scroll again. 
    Log.e(LOG_TAG,"events size = " + events.size()); 

    AccessibilityEvent event = getLastMatchingEvent(events, 
      AccessibilityEvent.TYPE_VIEW_SCROLLED); 

    if (event == null) { 
     // end of scroll since no new scroll events received 
     recycleAccessibilityEvents(events); 
     return false; 
    } 
    ... 
    .. 
    . 
} 

Penso che il modo migliore è che Override il codice e la definizione della adatto MaxSearchSwipes, e se l'articolo è su questo formato, fare il test sicuro.

public class UiScrollableFix extends UiScrollable { 

public UiScrollableFix(UiSelector container) { 
    super(container); 
} 

@Override 
public boolean scrollIntoView(UiSelector selector) throws UiObjectNotFoundException { 
    Tracer.trace(selector); 
    // if we happen to be on top of the text we want then return here 
    UiSelector childSelector = getSelector().childSelector(selector); 
    if (exists(childSelector)) { 
     return (true); 
    } else { 
     // we will need to reset the search from the beginning to start search 
     scrollToBeginning(getMaxSearchSwipes()); 
     if (exists(childSelector)) { 
      return (true); 
     } 

     for (int x = 0; x < getMaxSearchSwipes(); x++) { 
      Log.e("test", "x=" + x); 
      boolean scrolled = scrollForward(); 
      if (exists(childSelector)) { 
       return true; 
      } 
      //For avoiding the scroll fail. 
      // if (!scrolled && x!=0) { 
      //  return false; 
      // } 

     } 
    } 
    return false; 
} 

} 
Problemi correlati