Вопрос

The following test code does not pass even though manually submitting the form on my web interface actually does work.

import os
from flask.ext.testing import TestCase
from flask import url_for

from config import _basedir
from app import app, db
from app.users.models import User


class TestUser(TestCase):

    def create_app(self):
        """
        Required method. Always implement this so that app is returned with context.
        """
        app.config['TESTING'] = True
        app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(_basedir, 'test.db')
        app.config['WTF_CSRF_ENABLED'] = False  # This must be disabled for post to succeed during tests
        self.client = app.test_client()
        ctx = app.app_context()
        ctx.push()
        return app

    def setUp(self):
        db.create_all()
        #pass

    @app.teardown_appcontext
    def tearDown(self):
        db.session.remove()
        db.drop_all()
        #pass

    def test_admin_home(self):

        # url is the admin home page
        url = url_for('admin.index')
        resp = self.client.get(url)
        self.assertTrue(resp.status_code == 200)

    def test_admin_registration(self):

        url = url_for('admin.register_view')
        data = {'username': 'admin', 'email': 'admin@example.com', 'password': 'admin'}
        resp = self.client.post(url, data)
        self.assertTrue(resp.status_code == 200)

        u = User.query.filter_by(username=u'admin').first()
        self.assertTrue(u.username == 'admin')   # <----- This fails. Why?

After the test client has post to the register_view url and returns a 200 OK response, I fail to retrieve the 'admin' user from the test database. Why is this so?

Here's the view code (this is a flask admin view)

from flask import request
from flask.ext.admin import expose, AdminIndexView, helpers

from app.auth.forms import LoginForm, RegistrationForm
from app.users.models import User
from app import db


class MyAdminIndexView(AdminIndexView):

    @expose('/', methods=('GET', 'POST'))
    def index(self):
        # handle user login
        form = LoginForm(request.form)
        self._template_args['form'] = form
        return super(MyAdminIndexView, self).index()

    @expose('/register/', methods=('GET', 'POST'))
    def register_view(self):
        # handle user registration
        form = RegistrationForm(request.form)
        if helpers.validate_form_on_submit(form):
            user = User()
            form.populate_obj(user)
            db.session.add(user)
            db.session.commit()

        self._template_args['form'] = form
        return super(MyAdminIndexView, self).index()
Это было полезно?

Решение

Dumbest mistake ever.

The offending line in my test code is

resp = self.client.post(url, data)

It should be

resp = self.client.post(url, data=data)

I managed to track it down by painstakingly walking through the logic and inserting ipdb.set_trace() step by step until I found the bad POST request made by my client.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top