テストスイートがQuickCheck用の場合は、All
代わりに新しいモジュールを使用することをお勧めします:http:
//hackage.haskell.org/packages/archive/QuickCheck/2.4.1.1/doc/html/Test-QuickCheck-All.html
ファイルシステムにアクセスし、スプライスが存在するファイルを解析することによってプロパティの名前をフェッチすることを除いて、同じことを行います(他のテストフレームワークを使用している場合でも、同じアプローチを使用できます)。
本当にファイル全体を引用したい場合は、代わりに準引用符を使用できます(インデントは必要ありません)。haskell-src-metaでquoterを簡単に構築できますが、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
Allからエクスポートされない関数も必要です。
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