Steuern, wann ein Automatisierungstest endet - Espresso
-
21-12-2019 - |
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 habeonSpeedChange()
- 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.
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.