Как написать управляемые данными тесты, используя Hspec?

Я изучаю Haskell и являюсь хорошим разработчиком, пишу юнит-тесты на ходу. Я реализовал различные алгоритмы сортировки и соответствующие тесты. Тем не менее, я чувствую, что отдельные тесты являются избыточными, потому что вход и выход не меняются, только алгоритмы, используемые для сортировки ввода. Есть ли способ создать управляемые данными тесты или таблицы данных в различных других инфраструктурах модульного тестирования?

module RecursionSpec (main, spec) where

import Test.Hspec
import Recursion

main :: IO ()
main = hspec spec

spec :: Spec
spec = do
  let input = [3, 1, 5, 2, 4]
      output = [1, 2, 3, 4, 5]
  describe "bubblesort" $ do
    it ("sorts " ++ show input) $ do
      bubblesort input `shouldBe` output

  describe "mergesort" $ do
    it ("sorts " ++ show input) $ do
      mergesort input `shouldBe` output

  describe "quicksort" $ do
      it ("sorts " ++ show input) $ do
        quicksort input `shouldBe` output

Кроме того, я получаю следующее предупреждение, которое я хотел бы понять и устранить.

warning: [-Wtype-defaults]
    • Defaulting the following constraints to type ‘Integer’
        (Show a0)
          arising from a use of ‘show’ at test/RecursionSpec.hs:14:21-30
        (Eq a0)
          arising from a use of ‘shouldBe’ at test/RecursionSpec.hs:15:7-40
        (Ord a0)
          arising from a use of ‘bubblesort’ at test/RecursionSpec.hs:15:7-22
        (Num a0)
          arising from the literal ‘1’ at test/RecursionSpec.hs:12:17
        (Num a0)
          arising from the literal ‘3’ at test/RecursionSpec.hs:11:16
    • In the second argument of ‘(++)’, namely ‘show input’
      In the first argument of ‘it’, namely ‘("sorts " ++ show input)’
      In the expression: it ("sorts " ++ show input)

1 ответ

Вы можете определить функцию высшего порядка, например:

describeSort :: Ord a => String -> ([a] -> [a]) -> [a] -> [a] -> SpecWith b
describeSort sortName sorter input output =
    describe sortName $ do
        it ("sorts " ++ show input) $ do
        sorter input `shouldBe` output

Он не управляется данными, но в данном случае он в основном удаляет шаблон (я не могу убедиться, что синтаксис абсолютно правильный, у меня нет установки HSpec).

Тогда вы можете определить свои тесты как:

spec :: Spec
spec = do
    let input  = [3, 1, 5, 2, 4]
        output = [1, 2, 3, 4, 5]

    describeSort "bubblesort" bubblesort input output
    describeSort "mergesort"  mergeSort  input output
    describeSort "quicksort"  quickSort  input output

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

quickCheck (\xl -> bubblesort xl == sort xl)

куда sort это Data.List версия и bubblesort ваша реализация тестируется. QuickCheck создаст 100 списков, которые соответствуют ограничениям (должны быть списки Ord значения), и сообщать о любых обнаруженных ошибках.


Вы, вероятно, можете исправить это предупреждение, явно указав тип вашего input а также output s:

let input  = [3, 1, 5, 2, 4] :: [Integer]
    output = [1, 2, 3, 4, 5] :: [Integer]
Другие вопросы по тегам