Automatische Parameter-Permutationen

Es ist manchmal verdammt langweilig, alle Permutationen sinnvoller Parameter einer Methode zu testen, nur um jene Kombinationen zu finden, wo es kracht.

Langweilig? Das muss doch irgendwie auch automatisierbar sein!

Ein Beispiel:

public int calulate(int a, int b, int c) {
  return a /(b+c);
}

Das sieht harmlos aus. Aber was ist bei folgender Belegung?

a = 0; // spielt keine Rolle
b = -1;
c = 1; // b+c=0 ; 0 im Nenner? Das geht nicht gut.
calculate(a, b, c);

Krawummm!

Wäre es nicht gut, einen Test schreiben zu können, der interessanterweise die Ergebnisse ignoriert, aber stur alle Parameterkombinationen mit typabhängigen Beispielwerten abfeuert. So ein Test muss ja nicht schnell sein.
Nennen wir diese Methoden mal Stress-Methoden, um sie von den anderen Unit-Test-Methoden zu unterscheiden:

public void testStressCalculate() throws Throwable {
  stress(instance, // object under test
        "calculate(int, int, int)", // method under test

        // JUnitDoclet begin stress calculate(int, int, int)
        DEFAULT_INT_VALUES, // \ Array containing MIN_VALUE,
        DEFAULT_INT_VALUES, // | -1000, -10, -2, -1, 0,
        DEFAULT_INT_VALUES // / 1, 2, 10, 1000, MAX_VALUE
        // JUnitDoclet end stress calculate(int, int, int)

        );
}

Die Kombination von JUnit und Reflection macht sowas möglich. Die Methode "stress" könnte als statische Methode an einer Spezialisierung von TestCase realisiert sein. (Dann ist sie einfach nutzbar, selbst wenn man eine eigene Spezialisierung von TestCase baut oder verwenden muss).

Das Angenehme an diesen Tests ist, sie lassen sich fast zu 100% automatisch generieren! Sicher sogar mit JUnitDoclet!

Im Beispiel oben, wuerden 11^3 Aufrufe abgefeuert. Bei grossen Softwareprojekten kann das Vorgehen schnell auch einen nächtlichen Build-Lauf zum monatlichen Lauf entarten lassen.

Vielleicht will man also die Anzahl der Aufrufe pro Methode begrenzen können. Eine überladene stress-Methode bietet dafür einen weitereren Parameter: die Heftigkeit der Tests oder auch nur ein Flag.


public void testStressCalculate() throws Throwable {
  stress(instance, // object under test
        "calculate(int, int, int)", // method under test

        // JUnitDoclet begin stress calculate(int, int, int)
        DEFAULT_INT_VALUES, // \ Array containing MIN_VALUE,
        DEFAULT_INT_VALUES, // | -1000, -10, -2, -1, 0,
        DEFAULT_INT_VALUES, // / 1, 2, 10, 1000, MAX_VALUE
        // JUnitDoclet end stress calculate(int, int, int)

        coverage // 0.0 to 1.0 or false/true
        );
}

Jetzt müsste man coverage nur noch feingranular steuern können. Sowas Ähliches gibt es doch auch schon irgendwo? Ach ja, bei Log4J!

Und wie wäre es mit ein wenig Dynamik? (Die Tests werden übersprungen, wenn sich Test und Anwendung seit dem letzten erfolgreichen Lauf nicht geändert haben? Man müsste nur die feingranulare Konfiguration generieren....

Das klingt nach ner Menge Zeug zum Experimentieren. Sorry, keine Zeit mehr fürs Weblog...

Recent Assets

  • diagramm_bremspedal_verzoegerung_geschwindigkeit.jpg
  • abschnitt_im_streckenverlauf.jpg
  • zwei_traumautos.jpg
  • bild2.jpg
  • bild1.jpg

August 2009

Sun Mon Tue Wed Thu Fri Sat
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

About this Entry

This page contains a single entry by Gemkow published on 21.07.04 17:14.

Ein Handy gehört ans Ohr, nicht vors Auge! was the previous entry in this blog.

Kontinuierliche Build-Prozesse als Hintergrundmusik is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.