2010-09-28 19 views
18

Sto scrivendo casi di test di unità per un gioco su cui sto lavorando. Quando inizia il gioco, il giocatore è posizionato in modo casuale, e ho due problemi con questo:Unità testando un metodo con comportamento casuale

  1. Dal momento che il giocatore è posizionato in modo casuale, non posso essere sicuro che un banco di prova che passa una volta passerà di nuovo. Ad esempio, potrebbe passare la maggior parte del tempo, ma fallire se il giocatore dovesse trovarsi di fronte a un ostacolo.
  2. Devo testare tutte le situazioni in un caso di test. Ad esempio, quando si verifica se il giocatore si muove correttamente, devo verificare se c'è stato un ostacolo e se è stato considerato dall'algoritmo.

Non sono molto contento, ma non vedo una via d'uscita. È accettabile testare metodi con comportamento parzialmente casuale?

+0

Eventuali duplicati di [Unità di testare un metodo che può avere un comportamento casuale] (https://stackoverflow.com/questions/88007/unit-testing-a-method-that-can-have-random-behaviour) –

risposta

23

Ti suggerisco di considerare la tua fonte di casualità (un generatore di numeri casuali o qualsiasi altra cosa) come dipendenza. Quindi puoi testarlo con input conosciuti fornendo un RNG falso o uno con un seme noto. Ciò rimuove la casualità dal test, mantenendolo nel codice reale.

Se falso RNG, è possibile verificare che cosa succede se sarebbe naturalmente posizionare il lettore su un ostacolo - come si muove il giocatore fuori strada, ecc Naturalmente che si basa sulla conoscenza come la classe utilizza il RNG , ma personalmente sono abbastanza contento dei test unitari che fungono da "test white box" con alcune conoscenze interne.

+0

Così questo significa che suggerisci di fornire il mio gioco con un generatore di numeri casuali di cui posso creare un'implementazione fittizia? – forceal

+0

@forceal: Sì, è vero. –

+0

Hm. Ma il generatore di numeri casuali verrebbe utilizzato per diverse cose, quindi sarebbe davvero difficile simularlo. Ad esempio, è anche usato per il colore del giocatore (qualcosa che non ha influenza su nessun altro aspetto del gioco, quindi lo ignoro). L'unico modo che vedo sarebbe quello di creare una classe generatore contenente metodi come "getRandomPlayerPosition()" e "getRandomPlayerColor()", quindi potrei fingere. Sarebbe OK? – forceal

5

Un approccio che è possibile eseguire è dividere la generazione della posizione casuale in una classe/interfaccia separata, in modo da poterla sovrascrivere nel test e quindi controllarla.

3

Rendere la sorgente di casualità un input per il test e configurarlo ogni volta come uguale.

Quasi tutti i generatori di numeri casuali assumono un valore "seme". Fornendo lo stesso valore di seme ogni volta, puoi sapere che otterrai la stessa sequenza di numeri casuali e quindi l'output dell'applicazione dovrebbe essere esattamente lo stesso.

devo testare tutte le situazioni in un caso di test.

Perché? Puoi avere più casi di test. Puoi scegliere un numero qualsiasi di semi di numeri casuali diversi e arbitrari per creare le condizioni che vuoi testare. O semplicemente sostituire il posizionamento casuale con un posizionamento specifico ai fini del test.

1

Ci sono due cose diverse per testare qui, e si dovrebbe verificare separatamente:

  • funziona il programma di logica per tutte le possibili posizioni di partenza? Provalo posizionando il lettore non a caso su in un certo numero di posizioni, cercando di coprire tutti i "casi speciali".
  • Il posizionamento casuale è in realtà casuale? Prova questo chiamando molte volte la logica di posizionamento, e fai una sorta di analisi statistica.
0

Secondo la teoria di prova non è possibile testare comportamento casuale :) D'altra parte, come nelle risposte precedenti detto, per i test si potrebbe fare attività pseudo casuali in qualche modo.

1

Come altre risposte, gli algoritmi casuali sono deterministici. puoi riprodurre una sequenza se usi lo stesso seme.

Le uniche situazioni in cui ho dovuto trattare con un codice non deterministico, è quando era coinvolto il multithreading. Quindi, si dipende dallo scheduler del sistema operativo.

In questi casi, scrivo il test unitario come un ciclo, che ripete migliaia di volte il codice del test.

Problemi correlati