J'ai besoin de tester beaucoup de fonctions qui accèdent à la base de données (via Persistent). Alors que je peux le faire en utilisant monadicIO
et withSqlitePool
il se traduira par des tests inefficaces. Chaque test, pas la propriété, mais le test, va créer et détruire le pool de DB. Comment puis-je empêcher cela?Comment utiliser QuickCheck pour tester les fonctions liées à la base de données?
Important: Oubliez l'efficacité ou l'élégance. Je n'ai pas pu faire les types QuickCheck
et Persistent
pour composer même.
instance (Monad a) => MonadThrow (PropertyM a)
instance (MonadThrow a) => MonadCatch (PropertyM a)
type NwApp = SqlPersistT IO
prop_childCreation :: PropertyM NwApp Bool
prop_childCreation = do
uid <- pick $ UserKey <$> arbitrary
lid <- pick $ LogKey <$> arbitrary
gid <- pick $ Aria2Gid <$> arbitrary
let createDownload_ = createDownload gid lid uid []
(Entity pid _) <- run $ createDownload_ Nothing
dstatus <- pick arbitrary
parent <- run $ updateGet pid [DownloadStatus =. dstatus]
let test = do
(Entity cid child) <- run $ createDownload_ (Just pid)
case (parent ^. status, child ^. status) of
(DownloadComplete ChildrenComplete, DownloadComplete ChildrenNone) -> return True
(DownloadComplete ChildrenIncomplete, DownloadIncomplete) -> return True
_ -> return False
test `catches` [
Handler (\ (e :: SanityException) -> return True),
Handler (\ (e :: SomeException) -> return False)
]
-- How do I write this function?
runTests = monadicIO $ runSqlite ":memory:" $ do
-- whatever I do, this function fails to typecheck
Pouvez-vous donner un exemple de l'une des propriétés de votre QuickCheck? – ErikR
Ne voulez-vous pas simplement utiliser 'withSqlitePool' en dehors de l'appel de' monadicIO'? Par exemple, 'tests = withSqlitePool $ \ pool -> monadicIO (pool test1); monadicIO (pool test2) '. –
Nous utilisons une connexion SQLite à ': memory:' (je pense que c'est plus ou moins juste une base de données SQLite en mémoire). Cela semble fonctionner assez bien, certainement assez pour ne jamais être un goulot d'étranglement, mais peut-être que vous déplacez plus de données que nous ne le sommes. La tâche lente et ardue que vous pouvez faire est de créer votre propre instance de 'PersistStore' et de l'implémenter avec (par exemple) un tas de' Data.Map's. Mais cela vous empêche absolument d'utiliser quoi que ce soit dans 'Database.Persist.Sql', auquel cas vous auriez besoin de dépenser un bras et une jambe pour construire une valeur' SqlBackend'. – hao