Domanda

Vorrei testare una funzione con una tupla da un insieme di casi marginali e valori normali.Ad esempio, durante il test di una funzione che restituisce true ogni volta che vengono date tre lunghezze che formano un triangolo valido, avrei casi specifici, numeri negativi / piccoli / grandi, valori prossimi all'overflow, ecc.;inoltre, lo scopo principale è generare combinazioni di questi valori, con O senza ripetizione, al fine di ottenere una serie di dati di test.

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

Come nota:In realtà conosco la risposta a questa domanda, ma potrebbe essere utile per altri e una sfida per le persone qui!--pubblicherò la mia risposta più tardi.

È stato utile?

Soluzione

Assolutamente sì, soprattutto avendo a che fare con molte di queste permutazioni/combinazioni, posso sicuramente vedere che il primo passaggio sarebbe un problema.

Interessante implementazione in Python, anche se ne ho scritto uno carino in C e Ocaml basato su "Algorithm 515" (vedi sotto).Scrisse il suo in Fortran come era comune allora per tutti i documenti di "Algorithm XX", beh, quell'assemblea o c.Ho dovuto riscriverlo e apportare alcuni piccoli miglioramenti per lavorare con matrici e non intervalli di numeri.Questo fa accesso casuale, sto ancora lavorando per ottenere alcune belle implementazioni di quelle menzionate nel fascicolo 2 del quarto volume di Knuth.Spiegherò al lettore come funziona.Tuttavia, se qualcuno è curioso, non mi opporrei a scrivere qualcosa.

/** [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;
}

~"Algoritmo 515:Generazione di un vettore dall'indice lessicografico";Fibbie, B.P. e Lybanon, M.Transazioni ACM sul software matematico, vol.3, n.2, giugno 1977.

Altri suggerimenti

Con il nuovissimo Python 2.6, hai una soluzione standard con il modulo itertools che restituisce il prodotto cartesiano degli iterables:

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)]

Puoi fornire un argomento "ripetizione" per eseguire il prodotto con un iterabile e se stesso:

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)]

Puoi anche modificare qualcosa anche con le combinazioni:

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

E se l'ordine conta, ci sono permutazioni:

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)]

Ovviamente tutte quelle cose interessanti non fanno esattamente la stessa cosa, ma puoi usarle in un modo o nell'altro per risolvere il tuo problema.

Ricorda solo che puoi convertire una tupla o una lista in un set e viceversa usando list(), tuple() e set().

Domanda interessante!

Lo farei selezionando combinazioni, qualcosa di simile alla seguente in Python.La parte più difficile è probabilmente la verifica del primo passaggio, ad es. if f(1,2,3) returns true, è un risultato corretto?Una volta verificato ciò, questa è una buona base per i test di regressione.

Probabilmente è una buona idea creare una serie di casi di test che sai saranno tutti veri (ad es.3,4,5 per questo caso del triangolo) e una serie di casi test che sai saranno tutti falsi (ad es.0,1,inf).Quindi puoi verificare più facilmente che i test siano corretti.

# 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);
...

Penso che tu possa farlo con il Attributo test riga (disponibile in MbUnit e versioni successive di NUnit) in cui è possibile specificare diversi set per popolare uno unit test.

Sebbene sia possibile creare molti dati di test e vedere cosa succede, è più efficiente provare a ridurre al minimo i dati utilizzati.

Da una tipica prospettiva di QA, vorresti identificare diverse classificazioni di input.Produrre una serie di valori di input per ciascuna classificazione e determinare gli output appropriati.

Ecco un esempio di classi di valori di input

  • triangoli validi con numeri piccoli come (1 miliardo, 2, miliardo, 2 miliardi)
  • triangoli validi con numeri grandi come (0.000001, 0.00002, 0.00003)
  • triangoli ottusi validi che sono "quasi" piatti come (10, 10, 19.9999)
  • triangoli acuti validi che sono 'quasi' piatti come (10, 10, 0000001)
  • triangoli non validi con almeno un valore negativo
  • triangoli non validi in cui la somma di due lati è uguale al terzo
  • triangoli non validi in cui la somma di due lati è maggiore del terzo
  • valori di input non numerici

...

Una volta che sei soddisfatto dell'elenco delle classificazioni di input per questa funzione, puoi creare i dati di test effettivi.Probabilmente sarebbe utile testare tutte le permutazioni di ciascun elemento.(per esempio.(2,3,4), (2,4,3), (3,2,4), (3,4,2), (4,2,3), (4,3,2)) Tipicamente, scoprirai che ci sono alcune classificazioni che ti sono sfuggite (come il concetto di inf come parametro di input).

Possono essere utili anche dati casuali per un certo periodo di tempo, che possono trovare strani bug nel codice, ma generalmente non sono produttivi.

Più probabilmente, questa funzione viene utilizzata in un contesto specifico in cui vengono applicate regole aggiuntive. (ad es.solo i valori interi o i valori devono essere in incrementi di 0,01, ecc.) Questi si aggiungono all'elenco delle classificazioni dei parametri di input.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top