Estoy usando el marco Connexion para Flask para crear un microservicio. Me gustaría escribir pruebas para mi aplicación usando py.test .
En el pytest-flask , dice que se cree un accesorio en conftest.py que crea la aplicación de la siguiente manera:
conftest.py import pytest from api.main import create_app @pytest.fixture def app(): app = create_app() return app En mi prueba, estoy usando el accesorio del client de esta manera:
test_api.py def test_api_ping(client): res = client.get('/status') assert res.status == 200 Sin embargo, cuando ejecuto py.test , aparece el siguiente mensaje de error:
==================================== ERRORS ==================================== _______________________ ERROR at setup of test_api_ping ________________________ request = <SubRequest '_monkeypatch_response_class' for <Function 'test_api_ping'>> monkeypatch = <_pytest.monkeypatch.MonkeyPatch instance at 0x7f9f76b76518> @pytest.fixture(autouse=True) def _monkeypatch_response_class(request, monkeypatch): """Set custom response class before test suite and restore the original after. Custom response has `json` property to easily test JSON responses:: @app.route('/ping') def ping(): return jsonify(ping='pong') def test_json(client): res = client.get(url_for('ping')) assert res.json == {'ping': 'pong'} """ if 'app' not in request.fixturenames: return app = request.getfuncargvalue('app') monkeypatch.setattr(app, 'response_class', > _make_test_response_class(app.response_class)) E AttributeError: 'App' object has no attribute 'response_class' ¿Cómo puedo hacer que py.test funcione? Aquí está mi función create_app :
main.py import connexion def create_app(): app = connexion.App(__name__, port=8002,) app.add_api('swagger.yaml') return app if __name__ == "__main__": create_app().run()prueba_api.py
import pytest import connexion flask_app = connexion.FlaskApp(__name__) flask_app.add_api('swagger.yml') @pytest.fixture(scope='module') def client(): with flask_app.app.test_client() as c: yield c def test_health(client): response = client.get('/health') assert response.status_code == 200swagger.yml
swagger: '2.0' info: title: My API version: '1.0' consumes: - application/json produces: - application/json schemes: - https paths: /health: get: tags: [Health] operationId: api.health summary: Health Check responses: '200': description: Status message from server describing current healthapi.py
def health(): return {'msg': 'ok'}, 200Otra solución usando swagger-tester :
prueba_api.py
from swagger_tester import swagger_test authorize_error = { 'get': { '/health': [200], } } def test_swagger(): swagger_test('swagger.yml', authorize_error=authorize_error) Lo bueno de esta biblioteca es que puede usar los ejemplos proporcionados en su especificación. Pero no creo que funcione de inmediato con connexion.RestyResolver : tendrá que especificar OperationId en cada punto final.
import pytest from json import JSONEncoder import pytest from connexion import App SWAGGER_PATH = "path_to_directory_that_containes_swagger_file" @pytest.fixture def app(): app = App(__name__, specification_dir=SWAGGER_PATH) app.app.json_encoder = JSONEncoder app.add_api("swagger.yaml") app_client = app.app.test_client() return app_client def test_health(app) -> None: """ :except: success """ response = app.get("/health", content_type='application/json') assert response.status_code == 200Para más información revisa esto .