2011-12-17 6 views
7

Napisałem skończony moduł maszyny stanowej dla małej gry piłkarskiej, nad którą obecnie pracuję. Zapewnia interfejs do konfigurowania FSM (w zasadzie jego stanów i przejść). Dla każdego stanu można podać funkcje, które będą uruchamiane przy wejściu i wyjściu lub gdy FSM pozostaje w tym samym stanie, funkcje te następnie zwracają niektóre wiadomości. Zapewnia również interfejs reaktywny (Yampa), który zapewnia stan zmieniający się w czasie i zbiera komunikaty, które pojawiają się w czasie. Kod znajduje się tutaj Data/FSM.hs.Haskell: Jak przetestować (reaktywny) FSM z quickcheck?

Szukam dobrego podejścia do testowania tego modułu. Ponieważ jest czysty, pomyślałem o spróbowaniu. Nie jestem doświadczony w szybkiej kontroli, więc każda wskazówka byłaby doceniona! Moje podstawowe zrozumienie do tej pory: można by podać pewne funkcje, które budują FSM mniej lub bardziej losowo, a następnie uruchamiają niektóre (ponownie mniej lub bardziej losowe) przejścia na nich. Ale nie mogę zobaczyć, jak zbudować test w ten sposób ...

+0

Cóż, jakie testy chcesz napisać? Jakie właściwości lub zachowania należy weryfikować? –

+0

Cóż, może problem polega na tym, że tak naprawdę nie wiem ... Dla czegoś prostego jak "dla każdego ważnego fsm, każda skończona lista przejść prowadzi do stanu" Nic "lub stanu" Tylko s ", gdzie s jest stanem w fsm ", ok. Ale bardziej skomplikowane rzeczy, takie jak "dla każdego poprawnego fsm i listy (zmieniających się w czasie) przejść i percepcji, każdy zbiór wiadomości wzdłuż ścieżki przejścia powinien zostać odebrany", nie wiedziałbym, jak to sformalizować. Wiedziałabym, jak skonfigurować testy jednostkowe, ale z szybką kontrolą jestem trochę zagubiony. – martingw

+0

Link jest martwy (https://patch-tag.com/r/martingw/Rasenschach/snapshot/current/content/pretty/Data/FSM.hs) i nie ma archiwum, które można znaleźć – icc97

Odpowiedz

4

Przede wszystkim QuickCheck jest prawdopodobnie najlepiej przystosowany do weryfikacji ogólnych, ogólnych właściwości. Biorąc pod uwagę arbitralne dane pewnego rodzaju, wykonaj niektóre operacje, a następnie użyj predykatu, aby upewnić się, że wynik ma pewną właściwość względem danych wejściowych. Rzeczy związane z precyzyjnymi szczegółami zachowania krok po kroku mogą nie działać tak dobrze w tym stylu i nie powinieneś czuć się zobowiązany do robienia wszystkiego w QuickCheck!

To powiedziawszy, w oparciu o bardziej skomplikowany przykład podany w komentarzu, czy rozważałeś po prostu generowanie oczekiwanego wyniku wraz z FSM i danymi wejściowymi? Jeśli możesz wytworzyć pożądany wynik, który według twojej wiedzy jest poprawny, możesz uruchomić FSM na danych wejściowych i porównać rzeczywisty wynik ze skonstruowaną wersją.

To może pomóc, jeśli nie będziesz myślał o właściwościach QuickCheck jako testowanie funkcji na niektórych wejściach, ale raczej jako sprawdzanie, czy jedna lub więcej wartości spełnia pewne predykaty wyrażone w kategoriach testowanej funkcji. Ten zbiór wartości (który może zawierać wiele wejść, wyników, cokolwiek jest konieczne) jest faktycznie generowany losowo przez QuickCheck.

+0

Najprawdopodobniej najlepsza jest mieszanka: test na konkretny wynik dla konkretnego fsm i wejście z HUnit dla sytuacji krok po kroku i szybkie sprawdzenie dla bardziej ogólnych właściwości? – martingw

+1

@martingw: Myślę, że mix jest najlepszym podejściem domyślnym, tak. Jestem pewien, że w Hackage są nawet rzeczy, które zapewniają ujednolicone wiązki testowe dla HUnit, QuickCheck i być może z innych rzeczy. Prawdopodobnie będę uważał, że QuickCheck powinien być preferowany, gdy jest to możliwe, ale najlepiej sprawdza się, gdy wszystkie testowane są od A do B, a nie szczegóły podjętej trasy. –