Après beaucoup d'expérimentation et de recherche dans le kit de développement de code, je suis venu avec deux méthodes pour tester les points de terminaison dans python:
1. À l'aide de webtest + banc d'essai pour tester le SPI côté
Vous êtes sur la bonne voie avec webtest, mais juste besoin de s'assurer que vous transformer vos demandes pour le SPI point de terminaison.
Le Nuage de points de terminaison de l'API front-end et l' EndpointsDispatcher
en dev_appserver
transforme les appels d' /_ah/api/*
correspondants "backend" appels à l' /_ah/spi/*
. La transformation semble être:
- Tous les appels sont
application/json
HTTP Postes (même si le point de terminaison REST est autre chose).
- Les paramètres de la requête (chemin d'accès, d'interrogation et de JSON corps) sont fusionnés en un seul JSON corps du message.
- Le "backend" point de terminaison utilise le réel python classe et les noms de méthode dans l'URL, par exemple,
POST /_ah/spi/TestEndpoint.insert_message
appellerons TestEndpoint.insert_message()
dans votre code.
- La réponse JSON n'est reformaté avant d'être retournés au client d'origine.
Cela signifie que vous pouvez tester le point de terminaison avec la configuration suivante:
from google.appengine.ext import testbed
import webtest
# ...
def setUp(self):
tb = testbed.Testbed()
tb.setup_env(current_version_id='testbed.version') #needed because endpoints expects a . in this value
tb.activate()
tb.init_all_stubs()
self.testbed = tb
def tearDown(self):
self.testbed.deactivate()
def test_endpoint_insert(self):
app = endpoints.api_server([TestEndpoint], restricted=False)
testapp = webtest.TestApp(app)
msg = {...} # a dict representing the message object expected by insert
# To be serialised to JSON by webtest
resp = testapp.post_json('/_ah/spi/TestEndpoint.insert', msg)
self.assertEqual(resp.json, {'expected': 'json response msg as dict'})
La chose ici est que vous pouvez facilement l'installation des appareils appropriés dans la banque de données ou d'autres GAE services avant d'appeler le point de terminaison, ainsi vous permettre de mieux faire valoir les attendus effets secondaires de l'appel.
2. Le démarrage du serveur de développement pour l'intégration complète de test
Vous pouvez démarrer le serveur de dev dans le même environnement python en utilisant quelque chose comme ce qui suit:
import sys
import os
import dev_appserver
sys.path[1:1] = dev_appserver._DEVAPPSERVER2_PATHS
from google.appengine.tools.devappserver2 import devappserver2
from google.appengine.tools.devappserver2 import python_runtime
# ...
def setUp(self):
APP_CONFIGS = ['/path/to/app.yaml']
python_runtime._RUNTIME_ARGS = [
sys.executable,
os.path.join(os.path.dirname(dev_appserver.__file__),
'_python_runtime.py')
]
options = devappserver2.PARSER.parse_args([
'--admin_port', '0',
'--port', '8123',
'--datastore_path', ':memory:',
'--logs_path', ':memory:',
'--skip_sdk_update_check',
'--',
] + APP_CONFIGS)
server = devappserver2.DevelopmentServer()
server.start(options)
self.server = server
def tearDown(self):
self.server.stop()
Maintenant, vous devez émettre réel les requêtes HTTP vers localhost:8123 pour exécuter des tests à l'encontre de l'API, mais encore une fois peut interagir avec GAE Api pour configurer le matériel, etc. C'est évidemment lent que vous êtes à la création et la destruction d'un nouveau serveur de dev pour chaque série de tests.
À ce stade, j'utilise l' API de Google Python client à consommer de l'API au lieu de construire les requêtes HTTP de moi:
import apiclient.discovery
# ...
def test_something(self):
apiurl = 'http://%s/_ah/api/discovery/v1/apis/{api}/{apiVersion}/rest' \
% self.server.module_to_address('default')
service = apiclient.discovery.build('testendpoint', 'v1', apiurl)
res = service.testresource().insert({... message ... }).execute()
self.assertEquals(res, { ... expected reponse as dict ... })
C'est une amélioration par rapport à l'essai avec CURL, car elle vous donne un accès direct à la FGA Api pour créer facilement des montages et d'inspecter l'état interne. Je soupçonne qu'il ya une meilleure façon de faire des tests d'intégration qui contourne HTTP par assembler le minimum de composants dans le serveur de dev qui mettent en œuvre le point de terminaison d'expédition mécanisme, mais qui nécessite plus de temps de recherche que j'ai en ce moment.