unit testing - Verwendung von Satzkombinationen als Testdaten

Translate

Ich möchte eine Funktion mit einem Tupel aus einer Reihe von Randfällen und Normalwerten testen. Zum Beispiel beim Testen einer Funktion, die zurückgibttrueWenn drei Längen gegeben sind, die ein gültiges Dreieck bilden, habe ich spezielle Fälle, negative / kleine / große Zahlen, Werte, die kurz vor dem Überlaufen stehen usw.; Darüber hinaus besteht das Hauptziel darin, Kombinationen dieser Werte zu generieren.mitoderohneWiederholung, um einen Satz von Testdaten zu erhalten.

(inf,0,-1), (5,10,1000), (10,5,5), (0,-1,5), (1000,inf,inf),
...

Als Hinweis: Ich kenne die Antwort darauf tatsächlich, aber sie könnte für andere hilfreich und für die Menschen hier eine Herausforderung sein! - werde meine Antwort später posten.

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

Absolut, besonders wenn ich mich mit vielen dieser Permutationen / Kombinationen befasse, kann ich definitiv sehen, dass der erste Durchgang ein Problem sein würde.

Interessante Implementierung in Python, obwohl ich eine schöne in C und Ocaml geschrieben habe, die auf "Algorithmus 515" basiert (siehe unten). Er schrieb seine in Fortran, wie es damals für alle "Algorithm XX" -Papiere üblich war, na ja, diese Versammlung oder c. Ich musste es neu schreiben und einige kleine Verbesserungen vornehmen, um mit Arrays zu arbeiten, nicht mit Zahlenbereichen. Dieser macht wahlfreien Zugriff. Ich arbeite immer noch daran, einige nette Implementierungen der in Knuth 4. Band 2 genannten zu bekommen. Ich werde dem Leser erklären, wie dies funktioniert. Wenn jemand neugierig ist, würde ich nichts dagegen haben, etwas aufzuschreiben.

/** [combination c n p x]
 * get the [x]th lexicographically ordered set of [p] elements in [n]
 * output is in [c], and should be sizeof(int)*[p] */
void combination(int* c,int n,int p, int x){
    int i,r,k = 0;
    for(i=0;i<p-1;i++){
        c[i] = (i != 0) ? c[i-1] : 0;
        do {
            c[i]++;
            r = choose(n-c[i],p-(i+1));
            k = k + r;
        } while(k < x);
        k = k - r;
    }
    c[p-1] = c[p-2] + x - k;
}

~ "Algorithmus 515: Erzeugung eines Vektors aus dem lexikographischen Index"; Buckles, BP und Lybanon, M. ACM Transactions on Mathematical Software. 2, Juni 1977.

Quelle
Translate

Mit dem brandneuen Python 2.6 haben Sie eine Standardlösung mit dem itertools-Modul, das das kartesische Produkt von iterables zurückgibt:

import itertools

print list(itertools.product([1,2,3], [4,5,6]))
   [(1, 4), (1, 5), (1, 6),
   (2, 4), (2, 5), (2, 6),
   (3, 4), (3, 5), (3, 6)]

Sie können ein "Wiederholungs" -Argument angeben, um das Produkt mit einem iterablen und sich selbst auszuführen:

print list(itertools.product([1,2], repeat=3))
[(1, 1, 1), (1, 1, 2), (1, 2, 1), (1, 2, 2),
(2, 1, 1), (2, 1, 2), (2, 2, 1), (2, 2, 2)]

Sie können auch etwas mit Kombinationen optimieren:

print list(itertools.combinations('123', 2))
[('1', '2'), ('1', '3'), ('2', '3')]

Und wenn Ordnung wichtig ist, gibt es Permutationen:

print list(itertools.permutations([1,2,3,4], 2))
[(1, 2), (1, 3), (1, 4),
   (2, 1), (2, 3), (2, 4),
   (3, 1), (3, 2), (3, 4),
   (4, 1), (4, 2), (4, 3)]

Natürlich machen all diese coolen Sachen nicht genau das Gleiche, aber Sie können sie auf die eine oder andere Weise verwenden, um Ihr Problem zu lösen.

Denken Sie daran, dass Sie ein Tupel oder eine Liste mit list (), tuple () und set () in eine Menge konvertieren können und umgekehrt.

Quelle
Translate

Interessante Frage!

Ich würde dies tun, indem ich Kombinationen auswähle, so etwas wie das Folgende in Python. Der schwierigste Teil ist wahrscheinlich die Überprüfung des ersten Durchgangs, d. H.if f(1,2,3) returns trueIst das ein korrektes Ergebnis? Sobald Sie dies überprüft haben, ist dies eine gute Grundlage für Regressionstests.

Wahrscheinlich ist es eine gute Idee, eine Reihe von Testfällen zu erstellen, von denen Sie wissen, dass sie alle wahr sind (z. B. 3,4,5 für diesen Dreiecksfall), und eine Reihe von Testfällen, von denen Sie wissen, dass sie alle falsch sind (z. B. 0,1) , inf). Dann können Sie leichter überprüfen, ob die Tests korrekt sind.

# xpermutations from http://code.activestate.com/recipes/190465
from xpermutations import *

lengths=[-1,0,1,5,10,0,1000,'inf']
for c in xselections(lengths,3):        # or xuniqueselections
    print c
(-1,-1,-1);
(-1,-1,0);
(-1,-1,1);
(-1,-1,5);
(-1,-1,10);
(-1,-1,0);
(-1,-1,1000);
(-1,-1,inf);
(-1,0,-1);
(-1,0,0);
...
Quelle
Translate

Ich denke du kannst das mit dem machenZeilentestattribut(verfügbar in MbUnit und späteren Versionen von NUnit), in denen Sie mehrere Sätze angeben können, um einen Komponententest zu füllen.

Quelle
Translate

Während es möglich ist, viele Testdaten zu erstellen und zu sehen, was passiert, ist es effizienter zu versuchen, die verwendeten Daten zu minimieren.

Aus einer typischen QS-Perspektive möchten Sie verschiedene Klassifizierungen von Eingaben identifizieren. Erstellen Sie für jede Klassifizierung einen Satz von Eingabewerten und bestimmen Sie die entsprechenden Ausgaben.

Hier ist ein Beispiel für Klassen von Eingabewerten

  • gültige Dreiecke mit kleinen Zahlen wie (1 Milliarde, 2, Milliarde, 2 Milliarde)
  • gültige Dreiecke mit großen Zahlen wie (0,000001, 0,00002, 0,00003)
  • gültige stumpfe Dreiecke, die "fast" flach sind, wie (10, 10, 19.9999)
  • gültige spitze Dreiecke, die "fast" flach sind, wie (10, 10, 0000001)
  • ungültige Dreiecke mit mindestens einem negativen Wert
  • ungültige Dreiecke, bei denen die Summe zweier Seiten gleich der dritten ist
  • ungültige Dreiecke, bei denen die Summe zweier Seiten größer als die dritte ist
  • Eingabewerte, die nicht numerisch sind

...

Wenn Sie mit der Liste der Eingabeklassifizierungen für diese Funktion zufrieden sind, können Sie die tatsächlichen Testdaten erstellen. Wahrscheinlich wäre es hilfreich, alle Permutationen jedes Elements zu testen. (zB (2,3,4), (2,4,3), (3,2,4), (3,4,2), (4,2,3), (4,3,2)) In der Regel werden Sie feststellen, dass einige Klassifizierungen übersehen wurden (z. B. das Konzept von inf als Eingabeparameter).

Zufällige Daten für einen bestimmten Zeitraum können ebenfalls hilfreich sein, die seltsame Fehler im Code finden können, aber im Allgemeinen nicht produktiv sind.

Wahrscheinlicher ist, dass diese Funktion in einem bestimmten Kontext verwendet wird, in dem zusätzliche Regeln angewendet werden (z. B. müssen nur ganzzahlige Werte oder Werte in Schritten von 0,01 usw. vorliegen). Diese ergänzen die Liste der Klassifizierungen von Eingabeparametern.

Quelle