2009-08-09 3 views
0

Je veux utiliser un SQLite en mémoire (": memory:") DB pour les tests dans ma webapp. J'utilise nosetests pour les tests, et webpy comme framework.Comment utiliser SQLite: mémoire: base de données dans webpy pour unittesting

Je veux remplir la base de données dans la fonction setup(), puis exécuter tous mes tests. Mon problème est que webpy ferme toutes les connexions DB ouvertes après chaque requête, et SQLite: memory: DB ne dure que jusqu'à ce que vous fermiez la connexion, ainsi seul le premier test est exécuté correctement et tous les autres échouent. Mes choix sont soit d'exécuter les tests sur un DB sauvegardé sur disque, soit de recréer la totalité de la DB en mémoire au début de chaque test individuel. Savez-vous comment empêcher webpy de fermer les connexions DB après chaque requête? Pouvez-vous penser à une autre façon d'obtenir une base de données SQLite en mémoire qui dure plus d'une requête en utilisant webpy?

Répondre

2

Peut-être que vous pourriez exécuter les tests sur une base de données stockée sur le disque, mais en utilisant un RAM disk. Sous Windows, vous pouvez installer un pilote pour configurer un disque RAM (some instructions here). Sous Linux, je crois que vous voulez configurer tmpfs. Un disque ram agira exactement comme un disque dur, mais fonctionnera complètement à partir de la mémoire, de sorte que vous perdrez une partie du temps de chargement des fichiers vers/depuis le disque dur.

+0

C'est une bonne suggestion, mais cela compliquera la mise en place pour un testeur aléatoire. Dans mon cas ça ne vaut pas le coup. –

2

Untested:

class NoCloseDB(web.db.SqliteDB): 
    def _unload_context(self): 
    pass # this keeps the _ctx.db attribute alive 
web.db.register_database('sqlite',NoCloseDB) # overrides the previous registration 

Notez que cela ne peut fonctionner que si vous exécutez web.py d'une manière qui utilise un seul processus de système d'exploitation. Si une demande est répartie entre plusieurs processus, chacun aura sa propre base de données.

+1

Cela ne fonctionne pas, _unload_context n'est pas appelé explicitement à la fin de la requête, seulement après une validation ou une annulation explicite. Creuser un peu plus, il s'avère que tout l'objet _ctx (avec n'importe quel ThreadedDict attaché à ce thread) est réellement supprimé dans web.application._cleanup. Je pense maintenant que peut-être la meilleure façon de résoudre cela est d'installer DBUtils et de se connecter en utilisant un pool de 1 connexion. –

Questions connexes