Простое юнит-тестирование на Haskell

Я хочу пройти через 99 проблем Хаскелла и хочу сосредоточиться на решении, но с тестированием. Если у меня есть решение первой проблемы в виде 3 строки .hs файл,

myLast :: [a] -> a
myLast [x] = x
myLast (_:xs) = myLast xs

Какой минимальный объем кода я могу добавить к этому, чтобы я мог добавлять встроенные тесты и запускать их с runhaskell?

2 ответа

Решение

QuickCheck (который генерирует тестовые входные данные для вас), вероятно, лучший способ проверить чистую функцию. И если у рассматриваемой функции есть аналог из стандартной библиотеки, вы можете просто протестировать свою функцию, используя стандартную в качестве модели:

{-# LANGUAGE TemplateHaskell #-}

import Test.QuickCheck
import Test.QuickCheck.All

myLast :: [a] -> a
myLast [x] = x
myLast (_:xs) = myLast xs

-- here we specify that 'myLast' should return exactly the same result
-- as 'last' for any given 'xs'
prop_myLast xs = myLast xs == last xs


return [] -- need this for GHC 7.8
-- quickCheckAll generates test cases for all 'prop_*' properties
main = $(quickCheckAll)

Если вы запустите его, вы получите:

=== prop_myLast on tmp3.hs:12 ===
*** Failed! Exception: 'tmp3.hs:(7,1)-(8,25): Non-exhaustive patterns in function myLast' (after 1 test):  
[]
False

потому что ваш myLast не справляется [] case (он должен, но, вероятно, должен выдавать ошибку вроде 'last'). Но здесь мы можем просто настроить наш тест, но указав, что должны использоваться только непустые строки (используя ==> Комбинатор):

prop_myLast xs = length xs > 0 ==> myLast xs == last xs

Что делает все 100 автоматически сгенерированных тестовых случаев для передачи myLast:

=== prop_myLast on tmp3.hs:11 ===
+++ OK, passed 100 tests.
True

PS Еще один способ указать myLast поведение может быть:

prop_myLast2 x xs = myLast (xs++[x]) == x

Или лучше:

prop_myLast3 x xs = x `notElem` xs ==> myLast (xs++[x]) == x

hspec также является средой тестирования для Haskell, которая основана на Ruby RSpec. Он интегрируется с QuickCheck, SmallCheck и HUnit.

Другие вопросы по тегам