如果测试套件是用于快速检查,我建议你使用新All
模块来代替: http://hackage.haskell.org/packages/archive/QuickCheck/2.4.1.1/doc/html/Test-QuickCheck-All.html
它不只是它一样的东西通过访问文件系统和解析获取属性的名称拼接所在的文件(如果您正在使用其他测试框架,您仍然可以使用相同的方法)。
如果您确实想要引用整个文件,则可以使用准标记符(不需要缩进)。你可以很容易地在haskell-src-meta上构建你的报价器,但是我建议采用这种方法,因为它不会支持一些Haskell特性,它可能会给出糟糕的错误消息。
汇总测试服是一个棘手的问题,一个可能会扩展名聚会常规莫名其妙地跟着进口,但它是一个大量的工作。这里有一个解决方法:
您可以使用forAllProperties
这款改装版:
import Test.QuickCheck
import Test.QuickCheck.All
import Language.Haskell.TH
import Data.Char
import Data.List
import Control.Monad
allProperties :: Q Exp -- :: [(String,Property)]
allProperties = do
Loc { loc_filename = filename } <- location
when (filename == "<interactive>") $ error "don't run this interactively"
ls <- runIO (fmap lines (readFile filename))
let prefixes = map (takeWhile (\c -> isAlphaNum c || c == '_') . dropWhile (\c -> isSpace c || c == '>')) ls
idents = nubBy (\x y -> snd x == snd y) (filter (("prop_" `isPrefixOf`) . snd) (zip [1..] prefixes))
quickCheckOne :: (Int, String) -> Q [Exp]
quickCheckOne (l, x) = do
exists <- return False `recover` (reify (mkName x) >> return True)
if exists then sequence [ [| ($(stringE $ x ++ " on " ++ filename ++ ":" ++ show l),
property $(mono (mkName x))) |] ]
else return []
[|$(fmap (ListE . concat) (mapM quickCheckOne idents)) |]
您还需要没有从所有导出功能runQuickCheckAll
:
runQuickCheckAll :: [(String, Property)] -> (Property -> IO Result) -> IO Bool
runQuickCheckAll ps qc =
fmap and . forM ps $ \(xs, p) -> do
putStrLn $ "=== " ++ xs ++ " ==="
r <- qc p
return $ case r of
Success { } -> True
Failure { } -> False
NoExpectedFailure { } -> False
在每个测试模块现在定义
propsN = $allProperties
其中N
是一些数字或其他唯一标识符(或者您可以在下面的步骤中使用相同的名称和使用限定名称)。
在你的主要测试套件定义
props :: [(String,Property)]
props = concat [props1, props2 ... propsN]
如果你真的想避免添加列表成员为每个模块,你可以把生成此列表中的TH脚本。
要运行所有测试,你干脆说
runTests = runQuickCheckAll quickCheckResult props
我不知道为什么GHC上的缩进不断坚持,但为什么不回避问题,使用文件加引号?也许写一个接受一个完整的模块文件,用'module ... where'头部,并吐出它的顶级声明。 –
@ n.m。什么是文件报价器?另外,请记住,您不能使用TH生成导入声明,固定声明和其他一些内容。 –
@JonasDuregård:对不起,我刚刚完成了这个任期。这是你用'quoteFile'和一个准报价单得到的东西。然而,我的印象是,有一个图书馆提供的类似quotaer,就像'[d | ... |]'一样工作,但现在看起来情况并非如此。 –