Frage

Ich habe eine ungewöhnliche Situation, die ich teste.Ich benutze Espresso, um meine Tests zu schreiben.Ich weiß, dass Espresso und InstrumentationTestCase dazu nicht gedacht sind.

Ich habe einen Listener, den ich in einer meiner Klassen erstellt habe und der mich über eine Änderung eines bestimmten Werts informiert.Ich benutze den Listener in meiner Testsuite.

Wenn ich den Wert vom Listener erhalte, muss ich bestätigen, dass der Wert als solcher geändert wurde.

Mein Problem ist, dass der Test endet, bevor ich den Wert vom Listener erhalte.

    private void sendSpeedChanges() {
    setStaticSpeed(new Random().nextInt(10) + 2);
    try {
        runTestOnUiThread(new Runnable() {
            @Override
            public void run() {
                consoleActivity.onSpeedChanged(getStaticSpeed(), false);
            }
        });
    } catch (Throwable throwable) {
        throwable.printStackTrace();
    }

}

private void createSpeedDelegate() {
    EspressoMachineValues.setOnSpeedChangeListener(new EspressoMachineValues.OnSpeedChangeListener() {
        @Override
        public void onSpeedChanged(double speed) {
            //assert speed is correct.
            assertTrue(getStaticSpeed() == speed);
        }
    });

}

Dies sind die beiden Methoden, die ich verwende.Der createSpeedDelegate() ist Anruf ganz am Anfang.Dann rufe ich an sendSpeedChanges.Ich muss das X-mal machen.


BEACHTEN:

  • Es dauert ungefähr 200 Millisekunden, um Informationen abzurufen (im Durchschnitt).
  • Ich kann nicht anrufen sendSpeedChanges() bis ich den Wert eingecheckt habe onSpeedChange()
  • Ich kann nicht verwenden Thread.sleep(); weil der Listener im Hauptthread ist.

Ich habe es versucht hinzufügen eines getInstrumentation().wait(2000); und auch getInstrumentation().waitForIdleSync(); Offensichtlich funktioniert beides nicht.

In einer perfekten Welt würde ich das tun:

   for (int i = 0; i < 42; i++) {
        sendSpeedChanges();
        i++;
    }

Dies wartet jedoch nicht darauf, dass der Wert überprüft wird.Und wenn ich auf den Wert warte, denkt der Testläufer, dass alle Tests abgeschlossen sind und beendet.

Meine Frage gibt es eine Möglichkeit zu kontrollieren, wann der Test beendet wird?Obwohl meine Tests erscheinen zu erledigen.

War es hilfreich?

Lösung

In Ihrem Test müssen Sie eine Kontrollanweisung erstellen, die diesen Test so lange laufen lässt, wie Sie möchten, dass er ausgeführt wird.

while(myTestNeedsToRun) {
    if(speedChangeReceived) {
        sendSpeedChange();
        speedChangeReceived = false;
    }
}

private void createSpeedDelegate() {
   EspressoMachineValues.setOnSpeedChangeListener(new EspressoMachineValues.OnSpeedChangeListener() {
    @Override
    public void onSpeedChanged(double speed) {
        //assert speed is correct.
        assertTrue(getStaticSpeed() == speed);
        speedChangedReceived = true;
    }
});

Sobald Sie sich entschieden haben, dass Sie mit dem Ausführen Ihres Tests fertig sind, stellen Sie einfach ein myTestNeedsToRun = false und dann wird dein Test enden.

Andere Tipps

Alternativ können Sie eine IdlingResource erstellen, um Ihre Geschwindigkeit zu überwachen.IdlingResource ist die Methode, mit der Espresso überprüft, ob der Hauptthread inaktiv ist oder ob keine AsyncTasks im AsyncTask-Pool ausgeführt werden.

Schauen Sie sich an Coutingidlingresourcen klasse im Quellcode der Bibliothek.Sie könnten etwas Ähnliches implementieren.In Ihrem Fall könnte es so etwas sein:

[...]

private int mTargetSpeed;
private volatile ResourceCallback resourceCallback;

@Override
public boolean isIdleNow() {
  boolean isIdle = false;
  if (getStaticSpeed() == mTargetSpeed) {
     isIdle = true;
     resourceCallback.onTransitionToIdle();
  } else {
     isIdle = false;
  }

  return isIdle;
}

Wenn Sie bei Ihren Tests warten möchten, bis die Geschwindigkeit das gewünschte Niveau erreicht hat, sollten Sie Folgendes tun:

[...]
SpeedIdlingResource speedIdlingResource = new SpeedIdlingResource ("my_idling_resource");
Espresso.registerIdlingResources(speedIdlingResource);

Auf diese Weise blockiert Espresso, bis Ihre Leerlaufressource dem Framework mitteilt, dass Ihr SpeedMonitor inaktiv ist.Das ist gut, weil Sie das gesamte Espresso-Synchronisations-Framework nutzen, um zu überwachen, wann Sie die Zielgeschwindigkeit erreicht haben, sodass Ihre Tests zuverlässiger und schneller sind als eine belegte Wartezeit.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top