Lors de l'écriture de tests unitaires, il est courant d'utiliser des appareils: peu de données testables, nous pouvons donc dire: 1. Obtenez tous les clients doivent inclure Willy Wonka. 2. Supprimez le client 3, et maintenant les clients ne devraient plus inclure Willy Wonka.
C'est très bien pour les tests unitaires. Utilisez la configuration / le démontage pour recharger les appareils ou annuler la transaction. Les tests de création, de mise à jour et de suppression sont donc effectués dans une transaction . Les nouvelles données temporaires ne durent que pendant la durée de ce test, puis sont réinitialisées.
Mais qu'en est-il lorsque nous avons séparé le serveur REST du client REST?
Nous voulons nous assurer que notre client REST ne lit pas seulement correctement, mais crée, met à jour et supprime correctement.
Je n'ai pas pu trouver d'exemples ou de suggestions sur la façon de procéder avec un serveur REST de test distant.
En supposant que j'ai un serveur REST de test ne servant que des appareils. La nature sans état de HTTP signifie qu'il serait difficile d'envoyer un type de message "BEGIN TRANSACTION" et "ROLLBACK TRANSACTION" ou "RELOAD FIXTURES", non?
Je ne peux pas être le premier à vouloir faire ça, donc j'ai le sentiment que j'ai besoin d'une façon différente de penser à ce sujet.
Aucune suggestion?
la source
Réponses:
Les systèmes logiciels ont idéalement des limites de système bien définies et des interfaces entre eux. Les services REST en sont de bons exemples.
À cette fin, je recommanderais de ne pas faire ce que vous essayez de faire.
Plus précisément:
Ce que je suggérerais plutôt, c'est:
Création de tests pour votre client REST, pour vous assurer qu'il se comporte correctement, compte tenu d'une entrée et d'une sortie spécifiques. Tenez compte des valeurs bonnes (attendues) et mauvaises (inattendues).
Création de tests pour votre service REST (si vous le contrôlez, c'est-à-dire), pour se comporter conformément à sa fonction prévue
Gardez les tests à proximité de leur domaine de problème, afin qu'ils puissent aider à guider la conception et le développement de ce qui est important dans ce contexte
la source
Deux angles à retenir ici:
la source
Je pense que truquer les réponses du serveur REST est le meilleur moyen de tester le client.
Pour Ruby, il y a la gemme FakeWeb que vous pouvez utiliser pour émettre de fausses réponses - https://github.com/chrisk/fakeweb .
De plus, en JavaScript, vous pouvez utiliser quelque chose comme Sinon.JS, qui vous donne un faux serveur - http://sinonjs.org/docs/#fakeServer .
la source
Comme d'autres l'ont dit, si vous testez un client, vous n'avez pas besoin d'aller jusqu'à créer, supprimer, etc. sur le serveur. La plupart du temps, vous n'avez même pas besoin de vous moquer d'un serveur. Vous n'avez vraiment besoin que de vous assurer que vous faites les bonnes demandes et que vous gérez correctement les réponses, que ce soit écrit en Ruby, Python, PHP ou autre, à un moment donné, votre client va probablement utiliser une méthode d'une bibliothèque HTTP pour faire une requête et il suffit de se moquer de cette méthode, de vérifier comment elle est appelée et de renvoyer un résultat de test.
Prenez un hypothétique client Python qui l'utilise
urllib2
pour faire des requêtes. Vous avez probablement une méthode dans le client, appelons-laget()
, qui contient un appelurllib2.Request()
. Il vous suffit vraiment de vous moquer de l'appel de votre classeget()
.Cet exemple très simplifié utilise la bibliothèque Mock de Python pour tester une
your.Client
classe hypothétique avec uneget_object()
méthode qui génère l'URL correcte pour obtenir quelque chose d'une API. Pour effectuer la demande, le client appelle saget()
méthode avec cette URL. Ici, cette méthode est simulée (your.Client.get
est "corrigée" de sorte qu'elle est sous le contrôle deyour_mock
), et le test vérifie si le bon point de terminaison a été demandé.La méthode simulée renvoie la réponse JSON configurée (
your_mock.return_value
) que le client doit gérer et vous feriez d'autres affirmations pour tester qu'il a traité les données attendues de la manière attendue.la source
Ce que vous décrivez est un scénario de test d'intégration. Ceux-ci sont généralement un peu difficiles à installer et à démonter. Cela les rend lents à courir et assez souvent cassants.
L'approche avec les appareils est tout aussi maladroite et maladroite, mais c'est la façon par défaut dont certains frameworks s'y prennent, par exemple Rails, et elle est déjà prise en charge. Ils ont besoin du cas de test abstrait ou quelque chose de similaire pour préparer la base de données avec des appareils. (Méfiez-vous des dénominations inhabituelles des catégories de tests dans Rails, les tests unitaires avec les appareils DB sont à proprement parler également des tests d'intégration.)
La façon dont je procéderais dans votre scénario est d'accepter d'avoir un contrôle spécifique au test sur l'état de l'application API ou sa base de données. Vous pouvez soit avoir des points de terminaison supplémentaires pour la configuration et le démontage, qui ne sont présents que dans l'environnement de test. Ou bien, vous parlez à la base de données (ou tout ce que vous utilisez) à l'arrière de votre application / API.
Si vous pensez que cela représente un effort (au sens excessif) excessif, alors considérez que l'approche avec des appareils pour les bases de données fait exactement cela: utiliser des moyens supplémentaires spécifiques au test pour manipuler l'état de la base de données ou de l'application.
Je ne pense pas que cette discussion ait à voir avec la nature sans état de HTTP, cependant. HTTP est sans état, mais l'application ne l'est certainement pas, dans la majorité des cas. Cela vous ressemble un peu à la recherche de rigueur REST. Vous pourriez tout aussi bien faire en sorte que toutes les ressources soient entièrement créables, lisibles et supprimables. Dans ce cas, vous pouvez simplement effectuer toutes les opérations de configuration et de démontage via les moyens API standard. Cependant, cela n'est souvent pas fait dans la pratique, car vous ne voulez pas inclure certaines opérations à partir d'une compréhension métier de votre application, du moins pas en dehors de l'environnement de test.
la source
Patch de singe
Dans mon travail, nous effectuons ATDD en utilisant un cadre xUnit sortant et des appels réseau de correction de singe entre le client et le serveur. Dans le même espace de processus que nous chargeons le client, monkey corrige l'appel réseau en haut du code de pile du serveur REST. Tous les appels sont ensuite émis par le client comme ils le seraient normalement, et le code du serveur reçoit les demandes exactement telles qu'elles apparaissent normalement.
Avantages
Compromis
la source