单元测试IO Int和Haskell中的类似

Sha*_*hay 7 haskell

九十九个Haskell问题:

问题23:从列表中提取给定数量的随机选择的元素.

这是部分解决方案.为简单起见,此代码只从列表中选择一个元素.

import System.Random (randomRIO)

randItem :: [a] -> IO a
randItem xs = do
    i <- randomRIO (0,length xs - 1)
    return $ xs !! i
Run Code Online (Sandbox Code Playgroud)

所以randItem [1..10]IO Int从1到10 返回一个对应于(但不等于)某个Int的对象.

到现在为止还挺好.但是我可以为randItem函数编写什么样的测试?我可以在输入和输出之间确定什么关系 - 如果有的话?

我可以使用与上述函数相同的逻辑来生成m Bool,但我无法弄清楚如何测试m Bool.谢谢.

Mar*_*ann 6

你可以做几件事.如果您使用的是QuickCheck,则可以编写以下属性:

  • 返回列表的长度应等于输入长度.
  • 返回列表中的所有元素都应该是候选列表的元素.

除此之外,Haskell的Random库的优点在于(与大多数其他Haskell代码一样)它是确定性的.如果不是基于您的实现randomRIO,您可以将其基于randomRrandomRs.这将使您能够将一些已知RandomGen值传递给某些确定性单元测试用例(而不是QuickCheck).这些可以作为回归测试.


我现在发表了一篇关于上述方法的文章,其中包含源代码.

  • "返回列表中的所有元素都应该是候选列表中的元素." - 我认为这是自由定理的结果.如果是这样,不需要测试!:-) (3认同)