To jest stara wersja strony!
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
Napisz testy jednostkowe dla implementacji drzewa binarnego z zajęć XX
XX