pytest-dev / pytest-flask

A set of pytest fixtures to test Flask applications

Home Page:http://pytest-flask.readthedocs.org/en/latest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

404 error on second client.get call

nicolo opened this issue · comments

My client get call always fails in the second test. Any idea what I'm doing wrong?

from app import create_app
import pytest
from config import TestConfig


@pytest.fixture
def app():
    app = create_app(TestConfig)
    return app


class TestSomething:
    def test_index(self, client):
        res = client.get("/")
        assert res.status_code == 200

    def test_index_again(self, client):
        res = client.get("/")
        assert res.status_code == 200

I get the following error.

========================================================================================================================= FAILURES 
______________________________________________________________________________________________________________ TestSomething.test_index_again ______________________________________________________________________________________________________________

self = <conftest.TestSomething object at 0x10b2f9710>, client = <FlaskClient <Flask 'app'>>

    def test_index_again(self, client):
        res = client.get("/")
>       assert res.status_code == 200
E       AssertionError: assert 404 == 200
E        +  where 404 = <<class 'pytest_flask.plugin.JSONResponse'> streamed [404 NOT FOUND]>.status_code

conftest.py:19: AssertionError
================================================================================================================= short test summary info 
FAILED conftest.py::TestSomething::test_index_again - AssertionError: assert 404 == 200
=============================================================================================================== 1 failed, 1 passed in 0.26s 

I'm having this issue too. Checking app.url_map shows that on the second test, the routes I define are not registered. So I have no idea why this is.

The same thing also happens without using pytest-flask, however - even if I call create_app twice in a python shell.

Manually adding in the routes with app.add_url_rule() in the app factory function does end up working for me.

Update: I don't know how you're defining your routes, but my hunch is that it's because I'm using @current_app.route() for routes outside of blueprints, and creating multiple Flask instances doesn't play nicely with that.

@CassiusClose Thanks for leaving these comments. It helped me figure out a solution.

I'm not sure I fully understand why this happening, but the issue stemmed from using a create_app factory and importing routes. Moving to a proper blueprint implementation solved the issue.

I still don't understand why the first call of create_app would initialize the routes via the import, but subsequent calls did not.

@nicolo Glad I could help! Could I ask what your solution was?

I switched my create_app method in my app/__init__.py to use blueprints
So from:

def create_app(config_class=None):
    app = Flask(__name__)
   
    app.config.from_object(config_class)

    with app.app_context():
        from . import routes 

        return app

to using

def create_app(config_class=None):
    app = Flask(__name__)
   
    app.config.from_object(config_class)

    from app.main import bp as main_bp
    app.register_blueprint(main_bp)

    return app

For some reason the from . import routes wouldn't map the urls the second call of the app fixture. I'm pretty new to Flask so the issue here might be obvious to someone else.

Oh yes, you did say that above, my bad. Thanks!