Ich versuche, einige Tests mit dem integrierten Test-Framework von Android Junit zu schreiben. Ich habe ein Problem mit einem Test, bei dem ich eine Ausnahme erwarte. In JUnit lauten die Anmerkungen für die Testmethode:
@Test(expected = ArithmeticException.class)
In Android schlägt dieser Test jedoch mit einer ArithmeticException fehl.
Ich verstehe, dass die Android-Implementierung nur eine Teilmenge von JUnit 3 ist und nicht einmal die Annotation @Test zulässt (muss @SmallTest, @MediumTest oder @LargeTest sein, und keine davon erlaubt das 'Erwartete = ..'. parameter), aber dies scheint ein ziemlich bedeutender Test zu sein, und es scheint, als würde das Android-Testframework ernsthaft fehlen, wenn es diese Funktion nicht hätte.
Hinweis: Ich habe dies getestet, indem ich die JUnit-Dose zum Projekt und die Anmerkungen zu meinen Testmethoden hinzugefügt habe. Es ist für mich sinnvoll, warum die Anmerkungen vollständig ignoriert werden, da das Android-Framework (Runner?) Nicht nach dieser Anmerkung sucht und diese einfach ignoriert. Grundsätzlich suche ich nur nach dem "richtigen" Weg, dies im Rahmen zu tun.
Die Standardsprache für Junit 3 für diese Art von Test lautete:
public void testThatMethodThrowsException()
{
try
{
doSomethingThatShouldThrow();
Assert.fail("Should have thrown Arithmetic exception");
}
catch(ArithmeticException e)
{
//success
}
}
Jetzt ist JUnit4 über Android SDK verfügbar (siehe Android-Test-Kit ).
Update : Es ist jetzt offiziell am d.Android.com :
Der AndroidJUnitRunner ist ein neuer entbündelter Testläufer für Android , Der Teil der Android Support Test Library ist und Über das Android Support Repository heruntergeladen werden kann. Der neue Läufer enthält Alle Verbesserungen von GoogleInstrumentationTestRunner und fügt weitere Funktionen hinzu:
- JUnit4-Unterstützung
- Instrumentation Registry für den Zugriff auf Instrumentation, Context und Bündelargumente
- Testen Sie die Filter @SdkSupress und @RequiresDevice
- Test-Timeouts
- Scherben von Tests
- RunListener-Unterstützung zum Ankoppeln an den Testlauf-Lebenszyklus
- Aktivitätsüberwachungsmechanismus ActivityLifecycleMonitorRegistry
Also JUnit4-Stil für Ausnahmetests mit erwarteter Annotation:
@Test(expected= IndexOutOfBoundsException.class)
public void empty() {
new ArrayList<Object>().get(0);
}
oder erwartete Ausnahmeregeln:
@Rule
public ExpectedException thrown = ExpectedException.none();
@Test
public void shouldTestExceptionMessage() throws IndexOutOfBoundsException {
List<Object> list = new ArrayList<Object>();
thrown.expect(IndexOutOfBoundsException.class);
thrown.expectMessage("Index: 0, Size: 0");
list.get(0); // execution will never get past this line
}
ist auch möglich.
Weitere Informationen zum Einrichten der Test-Support-Bibliothek finden Sie unter offizielle Dokumentation .
Ich habe nach guten Lösungen gesucht, aber keine der Lösungen war für mich wirklich zufriedenstellend. Also habe ich meine eigene erstellt.
public final void assertThrows(VoidFunction v, Class<? extends Exception> e) {
try {
v.call();
} catch (Exception ex) {
if (!ex.getClass().equals(e)) {
Assert.fail();
}
// Do nothing, basically succeeds test if same exception was thrown.
return;
}
// Fails if no exception is thrown by default.
Assert.fail();
}
Wobei VoidFunction eine einfache Schnittstelle ist:
@FunctionalInterface
public interface VoidFunction {
void call();
}
Dies wird zum Beispiel wie folgt verwendet:
@Test
public void testFoo() {
assertThrows(() -> foo.bar(null)), NullPointerException.class);
assertThrows(() -> foo.setPositiveInt(-5)), IllegalArgumentException.class);
assertThrows(() -> foo.getObjectAt(-100)), IndexOutOfBoundsException.class);
assertThrows(new VoidFunction() {
@Override
public void call() {
foo.getObjectAt(-100);
}
}, IndexOutOfBoundsException.class); // Success
assertThrows(new VoidFunction() {
@Override
public void call() {
throw new Exception();
}
}, NullPointerException.class); // Fail
}
Ich habe einen Aufruf ohne Lambda hinzugefügt, dies macht es manchmal einfacher, den Code zu verstehen, zumindest für mich. Einfach zu verwenden und erlaubt mehrere Ausnahmebefehle in der ONE-Methode.