首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QuickCheck测试随机挂起

QuickCheck测试随机挂起
EN

Stack Overflow用户
提问于 2013-08-12 20:43:30
回答 2查看 926关注 0票数 1

我是哈斯克尔的新手。我正在使用QuickCheck测试,试图测试一个简单的函数calculateStrengthSingle (请参阅下面的测试源)

代码语言:javascript
复制
# Fighter.hs
module Fighter
( Quantity(Quantity)
, Fighter(TeamPlayer, LoneWolf, Polymorph)
, Strength(Strength)
, calculateStrengthSingle)
where

import System.Random

data Strength = Strength Double

instance Eq Strength where
    Strength s1 == Strength s2 =
        s1 == s2

instance Ord Strength where
    Strength s1 < Strength s2 =
        s1 < s2

data Quantity = Quantity Int deriving (Show)

instance Random Quantity where
    randomR (Quantity lo, Quantity hi) g =
        let rand = randomR (lo, hi) g
            (r, g1) = rand
        in (Quantity r, g1)
    random g =
        let rand = random g
            (r, g1) = rand
        in (Quantity r, g1)

data Fighter = TeamPlayer
             | LoneWolf
             | Polymorph
    deriving (Show)


calculateStrengthSingle :: Quantity -> Fighter -> Strength
calculateStrengthSingle (Quantity number) TeamPlayer =
    Strength(log (fromIntegral number))
calculateStrengthSingle _ _ = Strength 0.0

测试看起来是这样的

代码语言:javascript
复制
# TestFighter.hs
import qualified Test.QuickCheck as QuickCheck
import Fighter

prop_StrengthPositive quantity fighter =
    Fighter.calculateStrengthSingle quantity fighter >= Strength 0.0

instance QuickCheck.Arbitrary Fighter.Fighter where
    arbitrary = QuickCheck.oneof([return Fighter.TeamPlayer, return Fighter.LoneWolf, return Fighter.Polymorph])

instance QuickCheck.Arbitrary Fighter.Quantity where
    arbitrary = QuickCheck.choose(Fighter.Quantity 1, Fighter.Quantity 10)

main :: IO()
main = do
    QuickCheck.quickCheck prop_StrengthPositive

当我执行runhaskell TestFighter.hs时,有输出(1 test) (数字正在变化,有时是0,有时是4),并且CPU 100%加载。一分钟左右什么都不会发生。当我用Ctrl+C中断程序时,它会发出类似于

代码语言:javascript
复制
^C*** Failed! Exception: 'user interrupt' (after 1 test):  
Quantity 2
TeamPlayer

问题:

  1. 我在哪里搞砸了?
  2. 如何调试这种无限计算的情况?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-08-12 21:04:49

您还没有正确定义StrengthStrength实例。您需要定义<=而不是<

只有<定义了函数,<=进入无限循环,因为它是用compare定义的,compare是用<=定义的。最小定义需要定义compare<=

以下是Ord实例的固定代码

代码语言:javascript
复制
instance Ord Strength where
    Strength s1 <= Strength s2 =
        s1 <= s2
票数 7
EN

Stack Overflow用户

发布于 2013-08-12 21:45:25

您可以尝试使用-o 1作为参数来运行您的测试,这会在1秒后导致超时。然后,它可以显示导致程序挂起的输入。它并不能确切地告诉你问题出在哪里,但这是一个好的开始。

编辑:我就是这样使用测试框架的

代码语言:javascript
复制
test-Suite runTests
   hs-source-dirs:      src, test
   type:                exitcode-stdio-1.0
   main-is:             RunTests.hs
   other-modules:
                       <...>

  build-depends:       base >= 3 && < 5,
                       HUnit,
                       test-framework,
                       test-framework-th,
                       test-framework-hunit,
                       test-framework-quickcheck2,
                       QuickCheck,

为了在我的描述中完整,我使用:

代码语言:javascript
复制
cabal-dev install --enable-tests
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18196362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档