Testy jednostkowe z HUnit

Haskell udostępnia framework do testów jednostkowych o nazwie HUnit, który (podobno ;) ) inspirowany jest JUnitem z Javy. Pełna dokumentacja: HUnit Documentation

Instalacja

HUnit nie jest domyślnie instalowany wraz z ghc/ghci. Można go doinstalować z repozytorium:

sudo apt-get install libghc-hunit-dev

Funkcje i typy w HUnit

Podstawowym typem w HUnit 'Assertion' produkująca w wyniku zawsze 'IO ()', aby można było testować fragmenty kodu z tzw. side-effects. Type ten zwracany jest przez szereg funkcji opisanych w tabeli poniżej i to za ich pomocą budować będziemy testy.

`Assertion` stanowią z kolei podstawowy element `Test`, który jest juz gotowym testem jednoskowym (lub ich listą). Testy uruchamiamy funkcją runtestTT, która zwraca typ 'Counts', stanowiący podsumowanie testów.

Typ Definicja Opis
Assertion
type Assertion = IO ()
Podstawowy element każdego testu
Count
data Counts = Counts { cases, tried, errors, failures :: Int } 
    deriving (Eq, Show, Read)
Raport z wykonania testów
Test
data Test = TestCase Assertion 
    | TestList [Test] 
    | TestLabel String Test
Test jednostkowy
Funckja Sygnatura
assert
Assertable t => t -> Assertion
assertFailure
assertFailure :: String -> Assertion
assertBool
String -> Bool -> Assertion
assertEqual
(Show a, Eq a) => String -> a -> a -> Assertion
assertionPredicate
AssertionPredicable t => t -> AssertionPredicate
assertString
String -> Assertion
runTestTT
Test -> IO Counts

Przykłady

import Test.HUnit
 
testSum = TestCase $ assertEqual "10 + 5 = 15" 15 (10 + 5)
 
testProd = TestCase $ assertEqual "10 * 15" 150 (10 * 15)
 
testPred = TestCase $ assertBool "10 > 5" (10 > 5)
 
testFailure = TestCase $ assertEqual "It will fail 10 + 2 = 15" (10 + 2) 15  
 
testlist = TestList [TestLabel "testSum" testSum,
                     TestLabel "testPred" testPred,
                     TestLabel "testFailure" testFailure,
                     TestLabel "testProd" testProd                    
                    ]
 
main :: IO ()
main = do
  runTestTT testlist
  return ()

Operatory w HUnit

Funkcje z tabeli z wcześniejszej sekcji można zastąpić specjalnymi operatorami, przedstawionymi poniżej.

Opis Operator Sygnatura
Assert Bool (True)
(@?)
(AssertionPredicable t) => t -> String -> Assertion
Assert Equal
(@=?)
(Show a, Eq a) => a: expected -> a: value -> Assertion
Assert Equal
(@?=)
(Eq a, Show a) => a: value -> a: expected -> Assertion
Tworzy test o danej etykiecie
(~:)
Testable t => String -> t -> Test
Tworzy test assertEqual
(~?=)
(Show a, Eq a) => a: value -> a: expected -> Test
Tworzy test assertEqual
(~=?)	
(Show a, Eq a) => a: expected -> a: value -> Test

Przykłady

import Test.HUnit
 
 
fact 1 = 1
fact n = n * fact (n - 1)
 
testlist = TestList ["fact 1" ~: fact 1 ~?= 1
    , "fact 2" ~: fact 2 ~?= 2
    , "fact 3" ~: fact 3 ~?= 6
    , "fact 4" ~: fact 4 ~?= 24
    , "fact 5" ~: fact 5 ~?= 120
                    ]
 
main :: IO ()
main = do
  runTestTT testlist
  return ()

HScpec

Innym ciekawym rozwiązaniem do testowania jest HSpec Do rozwiązania zadań wykorzystaj dowolnie HUnit, albo HSpec (jeśli jest dostępny)

Zadania

  1. Przerób przykład z sekcji Testy jednostkowe z HUnit/Przykłady z wykorzystaniem operatorów
  2. Dla programu poniżej, który za zadanie ma odwracanie Stringa napisz testy sprawdzające czy funkcja działa poprawnie dla pustego napisu, dla napisu z dużymi literami (Szymon - nomyzS), dla stringów ze spacjami: „Ala ma kota” - „otak am alA” itp,:
    main = do   
        line <- getLine  
        if null line  
            then return ()  
            else do  
                putStrLn $ reverseWords line  
                main  
     
    reverseWords :: String -> String  
    reverseWords = unwords . map reverse . words
  3. Napisz testy jednostkowe dla implementacji drzewa binarnego z zajęć Monady i Typy dla każdej z funkcji.
pl/dydaktyka/pp/haskell/lab-hunit.txt · ostatnio zmienione: 2019/06/27 15:50 (edycja zewnętrzna)
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0