Both sides previous revision
Poprzednia wersja
Nowa wersja
|
Poprzednia wersja
|
pl:dydaktyka:pp:haskell:lab-hunit [2018/06/08 22:59] esimon [Instalacja] |
pl:dydaktyka:pp:haskell:lab-hunit [2019/06/27 15:50] (aktualna) |
| |
===== Funkcje i typy w HUnit ===== | ===== 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|<code>type Assertion = IO ()</code>|Podstawowy element każdego testu| |
| |Count|<code haskell>data Counts = Counts { cases, tried, errors, failures :: Int } |
| deriving (Eq, Show, Read)</code>|Raport z wykonania testów| |
| |Test|<code haskell>data Test = TestCase Assertion |
| | TestList [Test] |
| | TestLabel String Test</code>|Test jednostkowy| |
| |
^Funckja^ Sygnatura^ | ^Funckja^ Sygnatura^ |
| |
| |
^Typ ^ Definicja^ Opis^ | |
|Assertion|<code>type Assertion = IO ()</code>|X| | |
|Count|<code haskell>data Counts = Counts { cases, tried, errors, failures :: Int } | |
deriving (Eq, Show, Read)</code>|X| | |
|Test|<code haskell>data Test = TestCase Assertion | |
| TestList [Test] | |
| TestLabel String Test</code>|X| | |
| |
| |
==== Przykłady ==== | ==== Przykłady ==== |
| <code haskell> |
| 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 () |
| </code> |
===== Operatory w HUnit ===== | ===== 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)| <code>(@?)</code> | <code haskell>(AssertionPredicable t) => t -> String -> Assertion</code>| |
| |Assert Equal| <code>(@=?)</code> |<code haskell>(Show a, Eq a) => a: expected -> a: value -> Assertion</code>| |
| |Assert Equal | <code>(@?=)</code> |<code haskell>(Eq a, Show a) => a: value -> a: expected -> Assertion</code>| |
| |Tworzy test o danej etykiecie|<code>(~:)</code> |<code haskell>Testable t => String -> t -> Test</code>| |
| |Tworzy test assertEqual |<code>(~?=)</code> |<code haskell>(Show a, Eq a) => a: value -> a: expected -> Test</code>| |
| |Tworzy test assertEqual |<code>(~=?) </code>|<code haskell>(Show a, Eq a) => a: expected -> a: value -> Test</code>| |
==== Przykłady ==== | ==== Przykłady ==== |
| <code haskell> |
| 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 () |
| |
| </code> |
| ===== HScpec ===== |
| Innym ciekawym rozwiązaniem do testowania jest [[http://hspec.github.io/|HSpec]] |
| Do rozwiązania zadań wykorzystaj dowolnie HUnit, albo HSpec (jeśli jest dostępny) |
| |
===== Zadania ===== | ===== Zadania ===== |
| - Przerób przykład z sekcji [[pl:dydaktyka:pp:haskell:lab-hunit#przyklady|Testy jednostkowe z HUnit/Przykłady]] z wykorzystaniem operatorów |
| - 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,: <code haskell>main = do |
| line <- getLine |
| if null line |
| then return () |
| else do |
| putStrLn $ reverseWords line |
| main |
| |
| reverseWords :: String -> String |
| reverseWords = unwords . map reverse . words</code> |
| - Napisz testy jednostkowe dla implementacji drzewa binarnego z zajęć [[pl:dydaktyka:pp:haskell:lab-monads-types|Monady i Typy]] dla każdej z funkcji. |
| |
| |