2014-04-18 8 views
6

Ich automatisiere das Testen eines Flusses in meiner App, wo ich einen Geräteadministrator installieren. Um einen Geräteadministrator auf den meisten Geräten zu aktivieren (nehmen wir hier an, dass ich keine Enterprise-API habe, die mir das ermöglicht, was Samsung anbietet), zeigt das System dem Benutzer ein Popup an, das dann auf die Schaltfläche "Aktivieren" klicken muss.Wie Klick Ereignis mit Android injizieren UiAutomation.injectInputEvent

Ich verwende Robotium und Android JUnit, um meine Tests zu fahren. In einem normalen Testfall kann nur mit der App und dem zu testenden Prozess und nicht mit den Systemaktivitäten, die auftauchen, interagiert werden.

Die UiAutomation behauptet, dass Sie mit anderen Anwendungen interagieren können, indem Sie die Accessibility Framework nutzen und dann eine zu inject arbitrary input events zulassen.

So - hier ist das, was ich versuche zu tun:

public class AbcTests extends ActivityInstrumentationTestCase2<AbcActivity> { 

    private Solo mSolo 

    @Override 
    public void setUp() { 
     mSolo = new Solo(getInstrumentation(), getActivity()); 

    } 

    ... 

    public void testAbc(){ 

     final UiAutomation automation = getInstrumentation().getUiAutomation();   

     MotionEvent motionDown = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), KeyEvent.ACTION_DOWN, 
       100, 100, 0); 

     // This line was added in to give a complete solution 
     motionDown.setSource(InputDevice.SOURCE_TOUCHSCREEN); 

     automation.injectInputEvent(motionDown, true) 
     MotionEvent motionUp = MotionEvent.obtain(SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), KeyEvent.ACTION_UP, 
       100, 100, 0); 

     // This line was added in to give a complete solution 
     motionUp.setSource(InputDevice.SOURCE_TOUCHSCREEN); 

     automation.injectInputEvent(motionUp, true) 
     motionUp.recycle(); 
     motionDown.recycle(); 
    } 

} 

Wenn dieser Test den System-Popup läuft auf „Aktivieren“ der Geräteadministrator aktiv ist, und ich möchte nur auf dem Bildschirm klicken. Ich habe 100,100 als Position für Klicks für die Zwecke dieser Frage fest codiert, aber realistisch klicke ich in der unteren rechten Ecke des Bildschirms, damit ich den Knopf drücken kann.

Ich erhalte keine Klickereignisse auf dem Bildschirm. Hat jemand Erfahrung damit? Gibt es Alternativen, um das zu tun, was ich tun möchte? Aus meiner Sicht gibt es sehr wenige Tools, die das tun.

Danke.

aktualisieren Added setSource für richtige Antwort

+0

Ich glaube, Sie die setSource nehmen sollen() aufruft, die Sie bearbeiten in. Die ursprüngliche Frage, das Problem zeigen soll, wo die Antwort die zeigt, Lösung. So wie es ist, verursacht das Vergleichen der zwei Verwirrung, da sie beide arbeiten. – Project

Antwort

6

Schließlich dies herausgefunden. Ich habe meine MotionEvents mit den beiden Ereignissen verglichen, die beim Klicken auf eine Schaltfläche ausgelöst wurden, und der einzige Unterschied war die Quelle. Also habe ich die Quelle für die beiden motionEvents festgelegt und es hat funktioniert.

.... 
motionDown.setSource(InputDevice.SOURCE_TOUCHSCREEN); 
.... 
motionUp.setSource(InputDevice.SOURCE_TOUCHSCREEN); 

Und hier ist eine Vollversion des Verfahrens

//========================================================================= 
//==      Utility Methods        === 
//========================================================================= 
/** 
* Helper method injects a click event at a point on the active screen via the UiAutomation object. 
* @param x the x position on the screen to inject the click event 
* @param y the y position on the screen to inject the click event 
* @param automation a UiAutomation object rtreived through the current Instrumentation 
*/ 
static void injectClickEvent(float x, float y, UiAutomation automation){ 
    //A MotionEvent is a type of InputEvent. 
    //The event time must be the current uptime. 
    final long eventTime = SystemClock.uptimeMillis(); 

    //A typical click event triggered by a user click on the touchscreen creates two MotionEvents, 
    //first one with the action KeyEvent.ACTION_DOWN and the 2nd with the action KeyEvent.ACTION_UP 
    MotionEvent motionDown = MotionEvent.obtain(eventTime, eventTime, KeyEvent.ACTION_DOWN, 
      x, y, 0); 
    //We must set the source of the MotionEvent or the click doesn't work. 
    motionDown.setSource(InputDevice.SOURCE_TOUCHSCREEN); 
    automation.injectInputEvent(motionDown, true); 
    MotionEvent motionUp = MotionEvent.obtain(eventTime, eventTime, KeyEvent.ACTION_UP, 
      x, y, 0); 
    motionUp.setSource(InputDevice.SOURCE_TOUCHSCREEN); 
    automation.injectInputEvent(motionUp, true); 
    //Recycle our events back to the system pool. 
    motionUp.recycle(); 
    motionDown.recycle(); 
} 
+0

Ich liebe deine Javadoc und Kommentare – David

+0

@David Danke Mann! – jargetz