2012-09-14 16 views
6

Zastanawiam się, jakie metody (jeśli są) są używane do testowania aplikacji Haskell, które wykonują żądania przez sieć? Pochodzę z ziemi Ruby, szukałem wszystkiego, co może albo pobić, albo "zasymulować" połączenia sieciowe w celu przetestowania funkcji Haskella. Szczególnie interesuje mnie rozwiązanie typu "VCR" (np .: https://github.com/myronmarston/vcr), ponieważ wydaje się najbardziej realną opcją, IMHO.Haskell: Testowanie internetowych interfejsów API

Tak więc chcę mieć możliwość jednorazowego rejestrowania par żądań/odpowiedzi sieci, a następnie ponownego użycia tych rekordów w kolejnych testach. Wymyśliłem własną uproszczoną miksturę, która uruchamia serwer WWW (warp) przed testami, obsługując wcześniej nagrane odpowiedzi, ale muszę wskazać wszystkie adresy URL w aplikacji na "localhost". Zakładam, że nie zawsze jest możliwe zastąpienie wszystkich adresów URL w aplikacji. Chociaż jestem całkiem zadowolony z mojej własnej konfiguracji opisanej powyżej (i chciałbym zrobić z niej dedykowane narzędzie testujące/framework "wtyczkę" później), ale wolałbym nie wymyślać koła.

+0

Rozpocząłem projekt Haskell oparty na ideach magnetowidu. Przekaż opinię lub prześlij ją, jeśli będziesz: https://github.com/cordawyn/havcr –

Odpowiedz

3

Zapoznaj się z . Jeżeli można napisać Proxy otoki wokół danego typu, można łatwo zamienić na interfejs testową i prawdziwy interfejs tak:

client <-< simulatedServer 

client <-< realServer 

EDIT: Aby odpowiedzieć na to pytanie w komentarzu, użyć Server napisać owinięcie wokół simpleHTTP wniosków:

realServer 
:: HStream ty => Request ty -> Server (Request ty) (Result (Response ty)) IO r 
realServer = foreverK $ \req -> do 
    result <- lift $ simpleHTTP req 
    respond result 

serwer symulowany będzie wyglądać następująco:

simulatedServer 
:: (Monad m, HStream ty) 
=> Request ty -> Server (Request ty) (Result (Response ty)) m r 
simulatedServer = foreverK $ \req -> do 
    result <- lift $ simulatedRequest req 
    respond result 

i Twojego klienta będzie wyglądać lik e:

client 
:: (Monad m, HStream ty) =>() -> Client (Request ty) (Result (Response ty)) m r 
client() = forever $ do 
    let req = <something> 
    result <- request req 
    lift $ doSomethingWith result 

Następnie można przetestować prawdziwy serwer i fałszywego serwera przy użyciu:

-- Test the real server 
main = runSession $ client <-< realServer 

-- Test the fake server 
main = runSession $ client <-< simulatedServer 

client i simulatedServer są polimorficzne w monady bazowej tylko dlatego, że nie wiem, co oni monady bazowej używać do testów. Jedynym wymaganiem jest to, że dwie rzeczy, które skomponujesz, mają tę samą podstawową monadę lub że przynajmniej jedna z nich jest polimorficzna w monadzie podstawowej.

+0

Więc, w zasadzie mój bieżący 'Network.HTTP.simpleHTTP req' zmienia się w' Control.Proxy.request req' po stronie klienta, a następnie Umieszczam 'Control.Proxy.respond $ Network.HTTP.simpleHTTP req' dla" realServer "i' Control.Proxy.respond $ Simulated.Network req' dla "simulatedServer". Następnie łączę je tak, jak pokazano powyżej. Czy to prawda? –

+0

@SlavaKravchenko Tak. Edytowałem swoją odpowiedź, aby podać konkretne przykłady kodu, jak to zrobić teraz, gdy wiem dokładnie, co miałeś na myśli. –

+0

Awesome! Bardzo dziękuję za pomoc! –

Powiązane problemy