Flask testing keeps failing
<p>So I have web app where if the user is logged in, he cannot sign up. Instead he is redirected and a message saying he cannot sign up is flashed.</p>

<p>The problem is I can't test it for some reason.</p>

<p>Here is the view</p>

<pre><code>@users_template.route('/signup', methods=['GET', 'POST'])
def signup():
    form = RegisterationForm()
    if current_user.is_authenticated and current_user.is_active:  # prevent the user from seeing the register page if he's already logged in
        flash('You cannot sign up while you\'re logged in')
        return redirect(url_for('main.home'))

    if request.method == 'POST' and form.validate_on_submit():
        username = form.username.data
        password = form.password.data
        user = User(username=username, password=password)
        if db.session.query(User).filter(User.username == username).first() is None:
            current_app.logger.info('&lt;{}&gt; did not register before. Registering him/her now'.format(username))
            db.session.add(user)
            db.session.commit()
            flash('Thank you for registering. Please login now')
            return redirect(url_for('users.login'))
        else:  # the user name has been registered before
            flash('You already registered')
    return render_template('signup.html', form=form)
</code></pre>

<p>Now in my test module I have this method</p>

<pre><code>def test_signup_page_requires_logout(self):
    data_to_signup = {'username': 'mustafa1', 'password': 'mustafa1',
            'confirm_password': 'mustafa1'}
    data_to_login = {'username': 'mustafa1', 'password': 'mustafa1'}
    # with statement preserves the request context for the current_user
    with self.client:
        self.client.post('/signup', data=data_to_signup)
        self.client.post('/login', data=data_to_login)
        response = self.client.get('/signup', follow_redirects=True)
        assert b'You cannot sign up while you\'re logged in' in response.data
</code></pre>

<p>What's even more confusing is that this structure works for other methods</p>

<pre><code>def test_headquarter_after_login(self):
    data_to_signup = {'username': 'mustafa1', 'password': 'mustafa1',
            'confirm_password': 'mustafa1'}
    data_to_login = {'username': 'mustafa1', 'password': 'mustafa1'}
    with self.client:
        self.client.post('/signup', data=data_to_signup)
        self.client.post('/login', data=data_to_login)
        response = self.client.get('/headquarter')
        assert b'Headquarter page' in response.data
</code></pre>

<p>EDIT: here is the login view</p>

<pre><code>from .. import bcrypt
@users_template.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm(request.form)
    if form.validate_on_submit() and request.method == 'POST':
        username = form.username.data
        password = form.password.data

        user = User.query.filter(User.username == username).first()

        if user is not None and bcrypt.check_password_hash(user.password, password):  # authenticate
            login_user(user)  # then log the user in
            flash('You are logged in')
            return redirect(url_for('main.home'))

        else:
            flash('Incorrect username or password')  # if username is wrong, it will be caught by the error handling above
    return render_template('login.html', form=form)  # for a GET request
</code></pre>

<p>This is the error (I'm using py.test fyi)</p>

<pre><code>            assert current_user.is_active() == True
            assert current_user.is_authenticated() == True
&gt;           assert b'You cannot sign up while you\'re logged in' in response.data
E           AssertionError: assert b"You cannot sign up while you're logged in" in b'&lt;!DOCTYPE html&gt;\n&lt;html lang="en"&gt;\n  &lt;head&gt;\n    &lt;meta charset="utf-8"&gt;\n    &lt;meta http-equiv="X-UA-Compatible" cont...jquery/1.12.4/jquery.min.js"&gt;&lt;/script&gt;\n    &lt;script src="/static/js/bootstrap.min.js"&gt; &lt;/script&gt;\n  &lt;/body&gt;\n&lt;/html&gt;\n'
E            +  where b'&lt;!DOCTYPE html&gt;\n&lt;html lang="en"&gt;\n  &lt;head&gt;\n    &lt;meta charset="utf-8"&gt;\n    &lt;meta http-equiv="X-UA-Compatible" cont...jquery/1.12.4/jquery.min.js"&gt;&lt;/script&gt;\n    &lt;script src="/static/js/bootstrap.min.js"&gt; &lt;/script&gt;\n  &lt;/body&gt;\n&lt;/html&gt;\n' = &lt;TestResponse 3874 bytes [200 OK]&gt;.
</code></pre>

<p>This is to display the flashed messages in all my templates(It's in my "base.html" which I inherit from)</p>

<pre><code>    {% if get_flashed_messages() %}
        {% for message in get_flashed_messages() %}
            &lt;div class='container'&gt;
                    &lt;span class='alert alert-info'&gt;
                        &lt;small&gt;{{ message }}&lt;/small&gt;
                    &lt;/span&gt;
            &lt;/div&gt;
        {% endfor %}
    {% endif %}
</code></pre>

<p>I've made more tests using the flashed messages and it worked fine.
Like this one for testing the user signup</p>

<pre><code>assert b'Thank you for registering. Please login now' in response.data
</code></pre>

<p>Suggestion no:</p>

<ol>
<li><p>Because of this line:</p>

<pre><code>if current_user.is_authenticated and current_user.is_active:
</code></pre>

<p>current_user has his <code>is_active</code> flag set as <code>False</code>. If I'm not right, then please paste test error.</p></li>
<li><p>Another clue could be lack of flash messages in home template. Put this code below in for example <code>flashMessages.html</code>:</p>

<pre><code>{% macro render_flashMessages() %}
    {% with messages = get_flashed_messages() %}
        {% if messages %}
        &lt;ul class="list-unstyled"&gt;
            {% for message in messages %}
            &lt;li&gt;&lt;div class="alert alert-info"&gt;{{ message|safe }}&lt;/div&gt;&lt;/li&gt;
            {% endfor %}
        &lt;/ul&gt;
        {% endif %}
    {% endwith %}
{% endmacro %}
</code></pre>

<p>then you can use it in this way in <code>home.html</code>:</p>

<pre><code>{% from "flashMessages.html" import render_flashMessages %}

{{ render_flashMessages() }}
</code></pre></li>
<li><p>Next thing to check is to use assert with something else than response.data, if you're using <a href="https://flask-webtest.readthedocs.io/en/latest/" rel="nofollow">Flask-WebTest</a> you can try:</p>

<pre><code>assert b'You cannot sign up while you\'re logged in' in response.flashes[0][1]
</code></pre>

<p>Where <code>flashes</code> is:</p>

<blockquote>
  <p>List of tuples (category, message) containing messages that were flashed during request.</p>
</blockquote></li>
<li><p>But if you're not using FlaskWebTest, you can check session:</p>

<pre><code>from flask import session

session['_flashes'][0][1]
</code></pre></li>
</ol>

python flask flask-testing