Proces testowania Haskella

101

Właśnie zacząłem nowy projekt Haskell i od samego początku chciałem ustawić dobry przepływ pracy podczas testowania. Wygląda na to, że Haskell ma wiele doskonałych i unikalnych narzędzi testowych oraz wiele różnych sposobów ich integracji.

Przyjrzałem się:

Które wszystkie wydają się działać bardzo dobrze w swoich domenach, ale szukam kompleksowego podejścia do testowania i zastanawiałem się, co zadziałało dobrze dla innych ludzi.

amccausl
źródło

Odpowiedzi:

70

Właściwe wykonanie testów jednostkowych, pokrycia kodu i testów porównawczych polega głównie na wyborze odpowiednich narzędzi.

  • test-framework zapewnia kompleksową obsługę wszystkich przypadków testowych HUnit i właściwości QuickCheck z jednej wiązki.
  • Pokrycie kodu jest wbudowane w GHC w postaci narzędzia HPC .
  • Criterion zapewnia całkiem niezłą maszynę do testów porównawczych

Jako działający przykład użyję pakietu, który właśnie zacząłem włączać z testami jednostkowymi, pokryciem kodu i testami porównawczymi:

http://github.com/ekmett/speculation

Możesz zintegrować swoje testy i testy porównawcze bezpośrednio w pliku cabal, dodając dla nich sekcje i maskując je za flagami, aby nie sprawiały, że każdy użytkownik Twojej biblioteki musi mieć dostęp do (i chce używać dla siebie ) dokładną wersję wybranych narzędzi testowych.

http://github.com/ekmett/speculation/blob/master/speculation.cabal

Następnie możesz powiedzieć Cabal o tym, jak uruchomić zestaw testów. Ponieważ test Cabal jeszcze nie istnieje - mamy studenta pracującego nad nim na tegoroczne lato kodu! - najlepszy mechanizm jaki mamy to Oto jak używać mechanizmu haka użytkownika Cabal. Oznacza to przejście na kompilację „niestandardową” z Cabal i skonfigurowanie testHook. Przykład elementu testHook, który uruchamia program testowy napisany za pomocą platformy testowej, a następnie stosuje hpc do profilu, można znaleźć tutaj:

http://github.com/ekmett/speculation/blob/master/Setup.lhs

Następnie możesz użyć test-framework, aby połączyć testy QuickCheck i HUnit w jeden program:

http://github.com/ekmett/speculation/blob/master/Test.hs

Znajdujący się tam plik cabal ostrożnie włącza opcję -fhpc, aby umożliwić testowanie pokrycia kodu, a następnie testHook w pliku Setup.lhs ręcznie uruchamia hpc i zapisuje wyniki w katalogu dist.

Jeśli chodzi o testy porównawcze, historia jest nieco bardziej ręczna, nie ma opcji „benchmarku kabały”. Możesz podłączyć swoje testy porównawcze do haka testowego, ale ja lubię uruchamiać je ręcznie, ponieważ Criterion ma tak wiele opcji raportowania graficznego. Możesz dodać swoje benchmarki do pliku cabal, jak pokazano powyżej, nadać im osobne flagi kompilacji, ukryć je za flagą cabal, a następnie użyć Criterion, aby wykonać całą ciężką pracę:

http://github.com/ekmett/speculation/blob/master/Benchmark.hs

Następnie możesz uruchomić testy porównawcze z wiersza poleceń i wyświetlić wyskakujące okna KDE z wynikami testów itp.

Ponieważ w praktyce i tak żyjesz w kabale podczas tworzenia kodu Haskell, sensowne jest zintegrowanie z nim łańcucha narzędzi.

Edycja : wsparcie dla testów Cabal teraz istnieje. Zobacz http://www.haskell.org/cabal/release/cabal-latest/doc/users-guide/developing-packages.html#test-suites

Edward KMETT
źródło
2
I cabal benchteraz istnieje również.
nh2
6
Prawdziwe. Chciałbym wskazać github.com/ekmett/lens jako bardziej nowoczesny przykład tego, jak radzić sobie z cabal testi cabal bench, mieszając HUnit, doctestoraz quickchecktesty oparte o criterionbenchmarków. Kod w speculationwersjach starszych cabal testi cabal bench.
Edward KMETT
2
@EdwardKmett: Widziałem, że pakiet lense używa tylko interfejsu zestawu testów exitcode-stdio-1.0. Podręcznik użytkownika Cabal stwierdza, że ​​`` preferowane jest, aby nowe zestawy testów były napisane dla interfejsu Detailed-1.0 ''. Jakieś uwagi na ten temat?
copton,
9
@copton Nigdy go nie zaimplementowali. Ta dokumentacja musi zostać zabrana i zastrzelona.
Edward KMETT,
2
Niestety, wszystkie linki do github wskazywały na gałąź master i wygląda na to, że wszystko, co jest związane z testowaniem, zostało usunięte z pliku cabal, więc linki są skutecznie zepsute.
Andrew Thaddeus Martin
52

Podejście jest zwolennikiem w RWH rozdz. 11, aw XMonad jest w przybliżeniu:

  • Określić wszystkie właściwości systemu w QuickCheck
  • Pokaż pokrycie testu za pomocą HPC.
  • Potwierdź zachowanie przestrzeni za pomocą profilowania sterty .
  • Potwierdź zachowanie wątku / równoległości za pomocą ThreadScope .
  • Potwierdź zachowanie mikroznaków za pomocą Kryterium .

Po ustaleniu głównych niezmienników za pomocą narzędzia QuickCheck można rozpocząć refaktoryzację, przenosząc te testy do niezmienników typu.

Praktyki wspierające twoje wysiłki:

  • Uruchom uproszczoną regresję QuickCheck dla każdego zatwierdzenia.
  • Opublikuj szczegóły pokrycia HPC.
Don Stewart
źródło
14

Pakiet test-framework jest naprawdę niesamowity. Możesz łatwo zintegrować testy HUnit i QuickCheck i uzyskać pliki wykonywalne, które uruchamiają tylko określone zestawy, w oparciu o flagi wiersza polecenia, z wieloma celami wyjściowymi.

Testowanie i profilowanie to jednak różne bestie. Do profilowania utworzyłbym osobny plik wykonywalny, który podkreśla tylko sekcję, którą chcesz profilować, i po prostu uważnie przyglądając się wynikom kompilacji i uruchomień profilowania (z -prof-auto-all do kompilacji i + RTS -p dla środowiska uruchomieniowego flaga).

sclv
źródło
Bardziej aktywnie utrzymywany następca platformy testowej jest smaczny .
sjakobi
10

Do testowania opieram się na właściwościach HUnit i QuickCheck i używam Haskell Test Framework do automatycznego zbierania wszystkich testów jednostkowych i wszystkich właściwości QuickCheck.

Zastrzeżenie: Jestem głównym programistą Haskell Test Framework.

stefanwehr
źródło
5
Stefan, jest tak mało dokumentacji na ten temat. Myślę, że jest to główny powód, dla którego pozostaje niepopularny. Jest tutaj pytanie, na które zdecydowanie warto zwrócić uwagę: stackoverflow.com/questions/8919556/testing-with-htf
Nikita Volkov
2
Nowa wersja 0.9.0.0 HTF zawiera teraz sporo dokumentacji. Ponadto przeniosłem programowanie na github.com/skogsbaer/HTF . Mam nadzieję, że ułatwi to ludziom korzystanie z HTF i zadawanie pytań na temat HTF. Zapraszam do zrobienia tego!
stefanwehr