Issue
I'm trying to make a small Flask app based on client-server architecture. I'm struggling with arranging app with pytest to make tests use prepared database. Here's project structure:
| config.py
| Pipfile
|
+---client
+---mobile_app
+---server
| | database.py
| | server.py
|
+---tests
| | test_database.py
| | test_server.py
| | __init__.py
Below content of server.py
from flask import Flask
from flask_restful import Api, Resource
def create_app(config_obj):
app = Flask(__name__)
app.config.from_object(config_obj)
return app
app = create_app('config.DefaultConfig')
api = Api(app)
class Balance(Resource):
@staticmethod
def get(user_id):
balance = 0 * user_id
return {"balance": balance}
api.add_resource(Balance, "/<int:user_id>/balance")
if __name__ == "__main__":
app.run(debug=True)
config.py:
class DefaultConfig:
DEBUG = True
TESTING = False
PROPAGATE_EXCEPTIONS = None
SECRET_KEY = 'mysecretkey'
PERMANENT_SESSION_LIFETIME = '31 days, 0: 00:00'
USE_X_SENDFILE = False
SERVER_NAME = None
APPLICATION_ROOT = '/'
SESSION_COOKIE_NAME = 'session'
SESSION_COOKIE_DOMAIN = None
SESSION_COOKIE_PATH = None
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SECURE = False
SESSION_COOKIE_SAMESITE = None
SESSION_REFRESH_EACH_REQUEST = True
MAX_CONTENT_LENGTH = None
SEND_FILE_MAX_AGE_DEFAULT = None
TRAP_BAD_REQUEST_ERRORS = None
TRAP_HTTP_EXCEPTIONS = False
EXPLAIN_TEMPLATE_LOADING = False
PREFERRED_URL_SCHEME = 'http'
TEMPLATES_AUTO_RELOAD = None
MAX_COOKIE_SIZE = 4093
class TestingConfig:
DEBUG = True
TESTING = True
PROPAGATE_EXCEPTIONS = True
SECRET_KEY = 'mysecretkey'
PERMANENT_SESSION_LIFETIME = '31 days, 0: 00:00'
USE_X_SENDFILE = False
SERVER_NAME = None
APPLICATION_ROOT = '/'
SESSION_COOKIE_NAME = 'session'
SESSION_COOKIE_DOMAIN = None
SESSION_COOKIE_PATH = None
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SECURE = False
SESSION_COOKIE_SAMESITE = None
SESSION_REFRESH_EACH_REQUEST = True
MAX_CONTENT_LENGTH = None
SEND_FILE_MAX_AGE_DEFAULT = None
TRAP_BAD_REQUEST_ERRORS = None
TRAP_HTTP_EXCEPTIONS = False
EXPLAIN_TEMPLATE_LOADING = False
PREFERRED_URL_SCHEME = 'http'
TEMPLATES_AUTO_RELOAD = None
MAX_COOKIE_SIZE = 4093
and last but not least - test_server.py
import pytest
from server.server import create_app, app
@pytest.fixture()
def client_not_working():
client = create_app('config.TestingConfig')
with client.test_client() as testing_client:
# with client.app_context():
# yield testing_client
yield testing_client
@pytest.fixture()
def client_working():
yield app.test_client()
fixture = client_not_working
def test_get_balance(fixture):
response = fixture.get('/1/balance')
assert response.status_code == 200
assert response.headers['Content-Type'] == 'application/json'
assert b'balance' in response.data
assert response.json["balance"] == 0
If I set fixture
as client_working
test is passed. But when I set fixture
as client_not_working
which I want to use to customize configuration, i get Assertion Error:
tests\test_server.py:19 (test_get_balance)
404 != 200
Expected :200
Actual :404
<Click to see difference>
fixture = <FlaskClient <Flask 'server.server'>>
def test_get_balance(fixture):
response = fixture.get('/1/balance')
> assert response.status_code == 200
E assert 404 == 200
E + where 404 = <WrapperTestResponse streamed [404 NOT FOUND]>.status_code
tests\test_server.py:22: AssertionError
What am I doing wrong?
Solution
I figured out some obvious solution. The API resource wasn't built around object that was created by create_app factory, but it was built around app instance, that was functioning only in server.py itself.
I put those line, responsible for building Api around app into the factory and it works now.
server.py:
from flask import Flask
from flask_restful import Api, Resource
class Balance(Resource):
@staticmethod
def get(user_id):
balance = 0 * user_id
return {"balance": balance}
def create_app(config_obj):
app = Flask(__name__)
app.config.from_object(config_obj)
api = Api(app)
api.add_resource(Balance, "/<int:user_id>/balance")
return app
app = create_app('config.DefaultConfig')
if __name__ == "__main__":
# na środowisku produkcyjnym wyłączyć tryb debug!
# najlepiej stworzyć main.py uwzględniający rozruch serwera
app.run(debug=True)
Answered By - kubablo
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.