[英]How to write data-driven tests using 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)
您可以定义一个高阶函数,例如:
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
的类型来解决该警告:
let input = [3, 1, 5, 2, 4] :: [Integer]
output = [1, 2, 3, 4, 5] :: [Integer]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.