2014-01-06 54 views
-1

我有一個簡單函數集合的逆函數(簡單的移位碼):快速檢查測試失敗

encode, decode :: Int -> String -> String 

和他們測試通過一些簡單的手動測試正常,但一個快速檢查測試報告失敗:

*** Failed! Falsifiable (after 8 tests and 4 shrinks): 
"\254" 
0 

但運行用手此相同的測試工作正常:

*Main> decode 0 (encode 0 "\254") 
    "c" 

我沒有問爲什麼失敗(即我會追查的東西),但爲什麼QuickCheck在手工操作(看似)相同的測試中失敗?

我懷疑它與字符編碼有關,一個解碼它,另一個把它當作字符串處理,但我不知道爲什麼。


這個問題是關於測試是如何工作的,不是(呢!)功能或失敗的原因,但這裏是代碼:

import Data.Char 
let2int c = ord c - ord 'a' 

int2let n = chr (ord 'a' + n) 

shift :: Int -> Char -> Char 
shift n c | isLower c = int2let ((let2int c + n) `mod` 26) 
      | otherwise = c 

encode, decode :: Int -> String -> String 
encode n xs = [shift n x | x <- xs] 
decode n  = encode (-n) 

參考:赫頓,2007年

quickCheck $ (\s n-> (decode n $ encode n s) == s) 
+6

什麼是實際測試? –

+1

查看「encode」和「decode」的定義也可能有用。 –

+3

您需要在您的問題中包含失敗測試的定義。 –

回答

1

您提供的信息不足 - 下次請給出完整的測試和完整的代碼。當應用到quickCheck的輸出以給出除失敗結果以外的任何內容時,沒有魔術參與並且在測試中沒有充分的理由表達。

從你的代碼我想你的測試是decode 0 . encode 0 ~ id。這是不正確的,只看ghci的輸出:

*Main Test.QuickCheck> quickCheck (\x -> x == decode 0 (encode 0 x)) 
*** Failed! Falsifiable (after 13 tests and 4 shrinks):  
"\244" 
*Main Test.QuickCheck> decode 0 (encode 0 "\244") 
"r" 
*Main Test.QuickCheck> "\244" == "r" 
False 
+0

謝謝,我對「\ 254」符號感到困惑,以及它是如何產生的。我需要爲quickCheck創建一個已消毒的可打印字符串生成器。 – guthrie

+0

你不需要一個新的生成器,你只需要過濾來自當前'Arbitrary'實例的輸入:'((x - > let y = filter isAscii x in y == decode 0(encode 0 y))''。 –

+0

是的,但我發現我得到這麼多的過濾塊非常慢,然後可能因爲丟棄的測試值太多而失敗。 (我使用了一個(\ c - >(isAlpha c)==> ...)的過濾器,我想我需要一個safeChar生成器,並且運行良好,謝謝。 – guthrie