2012-06-11 13 views
5

Istnieje kilka domen aplikacji (np. GameDev), w których wiele funkcji powinno być tworzonych przy użyciu losowych wartości do generowania ich wyników. Jeden z przykładów jest przedstawiony poniżej:W jaki sposób sprawdzić poprawność funkcji, które używają losowo?

def generate_key(monster_key_drop_coef): 
    key_letters = string.ascii_uppercase 
    rand = random.random() 
    if monster_key_drop_coef < rand: 
     return None 

    button = {} 
    button["type"] = random.choice([1,2,3]) 
    button["letter"] = random.choice(key_letters) 
    return button 

Ta funkcja generuje spadek elementu w oparciu o kilka losowych operacji. Problem pojawia się, jeśli chcesz potwierdzić automatyczną poprawność tej funkcji. Wygenerowane wartości nie są deterministyczne, a pisanie testów regresji wydaje się niemożliwe.

Moje pytania są następujące:

  1. Czy to możliwe, aby napisać użytecznych testów regresji dla tego typu funkcji?
  2. Czy istnieje ogólne podejście do tworzenia innych rodzajów testów w tym przypadku?
+4

Istnieją całe książki napisane na ten temat. Przykład: http://www.johndcook.com/Beautiful_Testing_ch10.pdf –

+1

Prześmiewanie RNG w celu dostarczenia znanych wyników (a następnie testowanie z określonymi wynikami, dla których znany jest znany wynik) jest jednym podejściem. –

Odpowiedz

3

Jednym z przydatnych jednostek badań przedstawiono poniżej:

def test_generate_key(): 
    button_list = [] 
    for _ in range(1, 1000): 
     button_list.append(generate_key(0.2)) 

    is_all_none = True 
    is_not_none = False 
    for key in button_list: 
     is_all_none &= (key is None) 
     is_not_none |= (key is not None) 

    assert is_all_none == False 
    assert is_not_none == True 

To potwierdza podpis funkcji, obejmują wszystkie linie kodu (duże prawdopodobieństwo) funkcja i przejdzie w 99,999% przypadków. Potwierdzono również, że funkcja powoduje spadek o co najmniej jeden z 1000, a czasami nie generuje spadku. 0.2 Prawdopodobieństwo upadku przedmiotu.

2

Przepisałbym tę funkcję, aby użyła wtrysku zależności (generator liczb losowych jest przekazywany jako parametr do funkcji). Następnie możesz przekazać pozorowanie generatora liczb losowych w celu przetestowania swojej funkcji za pomocą różnych deterministycznych "losowych" danych wejściowych.

Oczywiście można również przetestować swoje twierdzenia, które nie zależą od wyników losowego połączenia. Takich jak:

  • Funkcje zwracają Brak lub dyktando za pomocą klawiszy "typ" i "litera".
  • Po zwróceniu słownika wartości są odpowiedniego typu i zakresu.

Nigdy nie napisałbym unittest, który ma wyniki niedeterministyczne, nawet 1 na tysiąc. Dbam o każdą porażkę testu, a wyniki stochastyczne byłyby niepokojące. Lepiej byłoby zamknąć hermetyzację, aby funkcja mogła być testowana niezależnie od generatora liczb losowych.

Powiązane problemy