J'écris des tests unitaires pour une API REST écrite dans Flask avec l'extension flask_sqlalchemy. Parce que j'ai un certain nombre de classes de modèles, j'ai écrit une sous-classe TestCase
pour faire le standard setUp/cleanUp de la base de données de test. Toutes mes classes de test en héritent. Chaque test réussit lorsqu'il est exécuté seul, mais lorsque j'exécute plus d'un test dans une seule classe, le second setUp() échoue sur le self.db.session.commit()
(j'essaie d'ajouter une entrée à la table User) car self.db.create_all()
a (en silence) échoué pour créer des tables. Voici ma classe de test de base, dans le __init__.py
du paquet de test:flask_sqlalchemy create_all() échoue silencieusement dans les tests unitaires
import unittest
from .test_client import TestClient
from .. import create_app
from pdb import set_trace as DBG
class ApiTest(unittest.TestCase):
default_username = 'fred'
default_password = 'bloggs'
db = None
def setUp(self):
try:
self.app = create_app('testing')
self.addCleanup(self.cleanUp)
self.ctx = self.app.app_context()
self.ctx.push()
from .. import db
self.db = db
self.db.session.commit()
self.db.drop_all(app=self.app)
from ..models import User, Player, Team, Match, Game
# self.app.logger.debug('drop_all())')
self.db.create_all(app=self.app)
# self.app.logger.debug('create_all())')
user = User(user_name=self.default_username)
user.password = self.default_password
self.db.session.add(u)
self.db.session.commit()
self.client = TestClient(self.app, user.generate_auth_token(), '')
except Exception, ex:
self.app.logger.error("Error during setUp: %s" % ex)
raise
def cleanUp(self):
try:
self.db.session.commit()
self.db.session.remove()
self.db.drop_all(app=self.app)
# self.app.logger.debug('drop_all())')
self.ctx.pop()
except Exception, ex:
self.app.logger.error("Error during cleanUp: %s" % ex)
raise
Quelqu'un peut-il me dire ce qui ne va pas ici s'il vous plaît?
EDIT: Ajout du code pour create_app()
comme demandé.
# chessleague/__init__.py
import os
from flask import Flask, g
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from . import config
app = None
db = None # The database, initialised in create_app()
def create_app(config_name):
app = Flask(__name__)
app.config.update(config.get_config(config_name))
# if app.config['USE_TOKEN_AUTH']:
# from api.token import token as token_blueprint
# app.register_blueprint(token_blueprint, url_prefix='/auth')
import logging
from logging.handlers import SysLogHandler
syslog_handler = SysLogHandler()
syslog_handler.setLevel(logging.WARNING)
app.logger.addHandler(syslog_handler)
login_manager = LoginManager()
login_manager.login_view = 'auth.login'
login_manager.init_app(app)
global db
db = SQLAlchemy(app)
db.init_app(app)
from .models import User,Player,Game,Match,Team,Post
db.create_all()
from .api import api as api_blueprint
app.register_blueprint(api_blueprint, url_prefix='/chessleague')
return app
`
Vous avez parlé d'un problème avec le 'create_all' mais n'ont pas ajouté la façon dont elle est invoquée. Je suppose que ça s'appelle 'create_app ', pouvez-vous ajouter cette fonction à votre question? – Fian
'db.create_all()' est appelé dans la méthode 'setUp()' ci-dessus, mais votre question m'a amené à regarder 'create_app()' dans le paquet principal. Il s'avère qu'il appelle aussi 'db.create_all()', comme vous l'avez deviné. Je l'ai ajouté à la question. – ProfCalculus
... mais AFAIK 'create_all()' devrait être idempotent. – ProfCalculus