Comment tester les fonctions et applications sans serveur - AWS Lambda

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

Comment tester les fonctions et applications sans serveur

Le test des fonctions sans serveur utilise les types et techniques de tests traditionnels, mais vous devez également envisager de tester les applications sans serveur dans leur ensemble. Les tests basés sur le cloud fourniront la mesure la plus précise de la qualité de vos fonctions et de vos applications sans serveur.

Une architecture d'application sans serveur comprend des services gérés qui fournissent des fonctionnalités d'applications critiques par le biais d'appels d'API. C'est pourquoi votre cycle de développement doit inclure des tests automatisés qui vérifient la fonctionnalité lorsque votre fonction et vos services interagissent.

Si vous ne créez pas de tests basés sur le cloud, vous pouvez rencontrer des problèmes en raison des différences entre votre environnement local et l'environnement déployé. Votre processus d'intégration continue doit exécuter des tests sur une série de ressources allouées dans le cloud avant de promouvoir votre code vers l'environnement de déploiement suivant, comme l'assurance qualité, la mise en place ou la production.

Poursuivez la lecture de ce petit guide pour en savoir plus sur les stratégies de test pour les applications sans serveur, ou rendez-vous sur le référentiel Serverless Test Samples pour vous plonger dans des exemples pratiques, spécifiques au langage et à l'exécution que vous avez choisis.

illustration showing the relationship between types of tests

Pour les tests sans serveur, vous écrirez toujours des tests unitaires, d'intégration et de bout en bout.

  • Tests unitaires : tests exécutés sur un bloc de code isolé. Par exemple, la vérification de la logique métier permettant de calculer les frais de livraison en fonction d'un article et d'une destination donnés.

  • Tests d'intégration : tests impliquant au moins deux composants ou services qui interagissent, généralement dans un environnement cloud. Par exemple, la vérification d'une fonction traite les événements d'une file d'attente.

  • nd-to-end Tests E : tests qui vérifient le comportement de l'ensemble d'une application. Il s'agit par exemple de s'assurer que l'infrastructure est correctement mise en place et que les événements circulent entre les services comme prévu pour enregistrer la commande d'un client.

Résultats commerciaux ciblés

Le test des solutions sans serveur peut nécessiter un peu plus de temps pour mettre en place des tests qui vérifient les interactions dirigées par les événements entre les services. En lisant ce guide, gardez à l'esprit les raisons commerciales pratiques suivantes :

  • Améliorer la qualité de votre application

  • Réduire le temps nécessaire à la création de fonctionnalités et à la correction des bogues

La qualité d'une application dépend de la réalisation de tests dans différents scénarios afin de vérifier sa fonctionnalité. Une réflexion approfondie sur les scénarios commerciaux et l'automatisation de ces tests pour les exécuter sur des services cloud amélioreront la qualité de votre application.

Les bogues logiciels et les problèmes de configuration ont le moins d'impact sur les coûts et le calendrier lorsqu'ils sont détectés au cours d'un cycle de développement itératif. Si des problèmes ne sont pas détectés au cours du développement, leur détection et leur résolution en production exigent davantage d'efforts de la part d'un plus grand nombre de personnes.

Une stratégie de test sans serveur bien planifiée augmentera la qualité des logiciels et améliorera le temps d'itération en vérifiant que vos fonctions Lambda et vos applications fonctionnent comme prévu dans un environnement cloud.

Que faut-il tester ?

Nous vous recommandons d'adopter une stratégie de test qui évalue les comportements des services gérés, la configuration du cloud, les politiques de sécurité et l'intégration à votre code afin d'améliorer la qualité du logiciel. Les tests de comportement, également connus sous le nom de tests en boîte noire, permettent de vérifier qu'un système fonctionne comme prévu sans en connaître tous les rouages.

  • Exécutez des tests unitaires pour vérifier la logique métier au sein des fonctions Lambda.

  • Vérifiez que les services intégrés sont réellement invoqués et que les paramètres d'entrée sont corrects.

  • Vérifiez qu'un événement passe par tous les services attendus end-to-end dans un flux de travail.

Dans les architectures traditionnelles basées sur des serveurs, les équipes définissent souvent une portée de test afin d'inclure uniquement le code qui s'exécute sur le serveur d'application. Les autres composants, services ou dépendances sont souvent considérés comme externes et hors de portée des tests.

Les applications sans serveur sont souvent composées de petites unités de travail, telles que les fonctions Lambda qui récupèrent des produits d'une base de données, traitent des éléments d'une file d'attente ou redimensionnent une image stockée. Chaque composant s'exécute dans son propre environnement. Les équipes seront probablement responsables de plusieurs de ces petites unités au sein d'une même application.

Certaines fonctionnalités de l'application peuvent être entièrement déléguées à des services gérés tels qu'Amazon S3, ou créées sans utiliser de code développé en interne. Il n'est pas nécessaire de tester ces services gérés, mais vous devez tester l'intégration avec ces services.

Comment tester le sans serveur

Vous savez probablement comment tester des applications déployées localement : vous rédigez des tests qui s'exécutent sur du code fonctionnant entièrement sur votre système d'exploitation de bureau ou à l'intérieur de conteneurs. Par exemple, vous pouvez invoquer un composant de service Web local avec une requête, puis faire des assertions sur la réponse.

Les solutions sans serveur sont conçues à partir du code de votre fonction et de services gérés basés sur le cloud, tels que les files d'attente, les bases de données, les bus d'événements et les systèmes de messagerie. Ces composants sont tous connectés par le biais d'une architecture orientée événements, dans laquelle les messages, appelés événements, circulent d'une ressource à l'autre. Ces interactions peuvent être synchrones, par exemple lorsqu'un service Web renvoie des résultats immédiatement, ou être asynchrones qui se terminent ultérieurement, comme le placement d'éléments dans une file d'attente ou le démarrage d'une étape du flux de travail. Votre stratégie de test doit inclure les deux scénarios et tester les interactions entre les services. Pour les interactions asynchrones, vous devrez peut-être détecter les effets secondaires dans les composants en aval qui peuvent ne pas être immédiatement observables.

Il n'est pas pratique de répliquer l'ensemble d'un environnement cloud, y compris les files d'attente, les tables de base de données, les bus d'événements, les politiques de sécurité, etc. Vous rencontrerez inévitablement des problèmes en raison des différences entre votre environnement local et vos environnements déployés dans le cloud. Les variations entre vos environnements augmenteront le temps nécessaire à la reproduction et à la correction des bogues.

Dans les applications sans serveur, les composants de l'architecture existent généralement à part entière dans le cloud. Il est donc nécessaire de les tester par rapport au code et aux services du cloud pour développer des fonctionnalités et corriger les bogues.

Techniques de test

En réalité, votre stratégie de test comprendra probablement une combinaison de techniques visant à améliorer la qualité de vos solutions. Vous utiliserez des tests interactifs rapides pour déboguer les fonctions de la console, des tests unitaires automatisés pour vérifier la logique métier isolée, la vérification des appels vers des services externes à l'aide de simulations, et des tests occasionnels sur des émulateurs imitant un service.

  • Tests dans le cloud : vous déployez l'infrastructure et le code à tester avec des services réels, des politiques de sécurité, des configurations et des paramètres spécifiques à l'infrastructure. Les tests basés sur le cloud fournissent la mesure la plus précise de la qualité de votre code.

    Le débogage d'une fonction dans la console est un moyen rapide de la tester dans le cloud. Vous pouvez choisir parmi une bibliothèque d'exemples d'événements de test ou créer un événement personnalisé pour tester une fonction de manière isolée. Vous pouvez également partager des événements de test via la console avec votre équipe.

    Pour automatiser les tests au cours du cycle de vie du développement et de génération, vous devez effectuer des tests en dehors de la console. Consultez les sections de ce guide relatives aux tests spécifiques à chaque langue pour connaître les stratégies et les ressources d'automatisation.

  • Tests à l'aide de simulations (également appelés faux) : les simulations sont des objets de votre code qui simulent et remplacent un service externe. Les simulations fournissent un comportement prédéfini pour vérifier les appels de service et les paramètres. Un faux est une implémentation fictive qui utilise des raccourcis pour simplifier ou améliorer les performances. Par exemple, un faux objet d'accès aux données peut renvoyer des données depuis un entrepôt de données en mémoire. Les simulations peuvent imiter et simplifier des dépendances complexes, mais peuvent également conduire à d'autres simulations afin de remplacer les dépendances imbriquées.

  • Tests à l'aide d'émulateurs : vous pouvez configurer des applications (parfois provenant d'un tiers) pour imiter un service cloud dans votre environnement local. La vitesse est leur force, mais la configuration et la parité avec les services de production sont leur point faible. Utilisez les émulateurs avec parcimonie.

Tests dans le cloud

Les tests dans le cloud sont utiles pour toutes les phases de test, y compris les tests unitaires, les tests d'intégration et les end-to-end tests. Lorsque vous exécutez des tests sur du code basé sur le cloud qui interagit également avec des services basés sur le cloud, vous obtenez la mesure la plus précise de la qualité de votre code.

Un moyen pratique d'exécuter une fonction Lambda dans le cloud consiste à utiliser un événement de test dans la AWS Management Console. Un événement de test est une entrée JSON pour votre fonction. Si votre fonction ne nécessite pas d'entrée, l'événement peut être un document JSON vide ({}). La console fournit des exemples d'événements pour diverses intégrations de services. Après avoir créé un événement dans la console, vous pouvez également le partager avec votre équipe pour faciliter les tests et les rendre plus cohérents.

Découvrez comment déboguer un exemple de fonction dans la console.

Note

Bien que l'exécution de fonctions dans la console soit un moyen rapide de déboguer, l'automatisation de vos cycles de test est essentielle pour améliorer la qualité des applications et la vitesse de développement.

Des exemples d'automatisation des tests sont disponibles dans le référentiel Serverless Test Samples. La ligne de commande suivante exécute un exemple de test d'intégration Python automatique :

python -m pytest -s tests/integration -v

Bien que le test soit exécuté localement, il interagit avec des ressources basées dans le cloud. Ces ressources ont été déployées à l'aide de l'outil de ligne de AWS SAM commande AWS Serverless Application Model and. Le code de test récupère d'abord les sorties de la pile déployée, qui comprend le point de terminaison de l'API, l'ARN de la fonction et le rôle de sécurité. Le test envoie ensuite une demande au point de terminaison de l'API, qui répond par une liste de compartiments Amazon S3. Ce test s'exécute entièrement sur des ressources basées sur le cloud afin de vérifier que ces ressources sont déployées, sécurisées et qu'elles fonctionnent comme prévu.

========================= test session starts ========================= platform darwin -- Python 3.10.10, pytest-7.3.1, pluggy-1.0.0 -- /Users/t/code/aws/serverless-test-samples/python-test-samples/apigw-lambda/venv/bin/python cachedir: .pytest_cache rootdir: /Users/t/code/aws/serverless-test-samples/python-test-samples/apigw-lambda plugins: mock-3.10.0 collected 1 item tests/integration/test_api_gateway.py::TestApiGateway::test_api_gateway --> Stack outputs: HelloWorldApi = https://p7teqs3162.execute-api.us-west-2.amazonaws.com/Prod/hello/ > API Gateway endpoint URL for Prod stage for Hello World function PythonTestDemo = arn:aws:lambda:us-west-2:1234567890:function:testing-apigw-lambda-PythonTestDemo-iSij8evaTdxl > Hello World Lambda Function ARN PythonTestDemoIamRole = arn:aws:iam::1234567890:role/testing-apigw-lambda-PythonTestDemoRole-IZELQQ9MG4HQ > Implicit IAM Role created for Hello World function --> Found API endpoint for "testing-apigw-lambda" stack... --> https://p7teqs3162.execute-api.us-west-2.amazonaws.com/Prod/hello/ API Gateway response: amplify-dev-123456789-deployment|myapp-prod-p-loggingbucket-123456|s3-java-bucket-123456789 PASSED ========================= 1 passed in 1.53s =========================

Pour le développement d'applications natives cloud, les tests dans le cloud offrent les avantages suivants :

  • Vous pouvez tester tous les services disponibles.

  • Vous utilisez toujours les API de service et les valeurs de retour les plus récentes.

  • Un environnement de test dans le cloud ressemble beaucoup à votre environnement de production.

  • Les tests peuvent porter sur les politiques de sécurité, les quotas de service, les configurations et les paramètres spécifiques à l'infrastructure.

  • Chaque développeur peut rapidement créer un ou plusieurs environnements de test dans le cloud.

  • Les tests dans le cloud augmentent la confiance dans le fait que votre code fonctionnera correctement en production.

Les tests dans le cloud présentent certains inconvénients. L'inconvénient le plus évident des tests dans le cloud est que les déploiements vers des environnements cloud prennent généralement plus de temps que les déploiements vers des environnements de bureau locaux.

Heureusement, des outils tels que AWS Serverless Application Model (AWS SAM) Accelerate, le mode veille du AWS Cloud Development Kit (AWS CDK) et le SST (tiers) réduisent la latence associée aux itérations de déploiement dans le cloud. Ces outils peuvent surveiller votre infrastructure et votre code et déploient automatiquement des mises à jour incrémentielles dans votre environnement cloud.

Note

Découvrez comment créer une infrastructure sous forme de code dans le Guide du développeur sans serveur pour en savoir plus sur AWS Serverless Application Model AWS CloudFormation, et AWS Cloud Development Kit (AWS CDK).

Contrairement aux tests locaux, les tests dans le cloud nécessitent des ressources supplémentaires qui peuvent entraîner des coûts de service. La création d'environnements de test isolés peut alourdir la charge de travail de vos DevOps équipes, en particulier dans les organisations où les comptes et l'infrastructure sont soumis à des contrôles stricts. Néanmoins, lorsque l'on travaille avec des scénarios d'infrastructure complexes, le coût en temps de développement pour mettre en place et maintenir un environnement local complexe peut être similaire (voire plus coûteux) que l'utilisation d'environnements de test jetables créés avec des outils d'automatisation d'infrastructure en tant que code.

Même en tenant compte de ces considérations, les tests dans le cloud restent le meilleur moyen de garantir la qualité de vos solutions sans serveur.

Tester avec des simulations

Les tests avec des simulations sont une technique qui consiste à créer des objets de remplacement dans votre code afin de simuler le comportement d'un service cloud.

Par exemple, vous pouvez écrire un test qui utilise une maquette du service Amazon S3 qui renvoie une réponse spécifique chaque fois que la CreateObjectméthode est appelée. Lorsqu'un test s'exécute, la simulation renvoie cette réponse programmée sans appeler Amazon S3 ni aucun autre point de terminaison de service.

Les objets simulés sont souvent générés par un cadre simulé afin de réduire les efforts de développement. Certains frameworks fictifs sont génériques tandis que d'autres sont conçus spécifiquement pour AWS les SDK, comme Moto, une bibliothèque Python permettant de simuler des AWS services et des ressources.

Il convient de noter que les objets simulés diffèrent des émulateurs dans la mesure où les simulations sont généralement créées ou configurées par un développeur dans le cadre du code de test, alors que les émulateurs sont des applications autonomes qui exposent les fonctionnalités de la même manière que les systèmes qu'ils émulent.

Les avantages de l'utilisation de simulations incluent les avantages suivants :

  • Les simulations peuvent simuler des services tiers qui échappent au contrôle de votre application, tels que les API et les fournisseurs de logiciels en tant que service (SaaS), sans qu'il soit nécessaire d'accéder directement à ces services.

  • Les simulations sont utiles pour tester les conditions d'échec, en particulier lorsque ces conditions sont difficiles à simuler, comme dans le cas d'une panne de service.

  • Une fois configurée, la simulation permet d'effectuer des tests locaux rapides.

  • Les simulations peuvent fournir un comportement de substitution pour pratiquement n'importe quel type d'objet. Les stratégies de simulations peuvent donc couvrir une plus grande variété de services que les émulateurs.

  • Lorsque de nouvelles fonctionnalités ou de nouveaux comportements sont disponibles, les tests simulés permettent de réagir plus rapidement. En utilisant un framework de simulation générique, vous pouvez simuler de nouvelles fonctionnalités dès que le AWS SDK mis à jour sera disponible.

Les tests simulés présentent les inconvénients suivants :

  • Les simulations nécessitent généralement un effort d'installation et de configuration non négligeable, en particulier lorsqu'il s'agit de déterminer les valeurs de retour de différents services afin de simuler correctement les réponses.

  • Les simulations sont écrites, configurées et doivent être mises à jour par les développeurs, ce qui accroît leurs responsabilités.

  • Vous pouvez avoir besoin d'un accès au cloud pour comprendre les API et les valeurs de retour des services.

  • Les simulations peuvent être difficiles à entretenir. Lorsque les signatures des API cloud simulées changent ou que les schémas de valeurs de retour évoluent, vous devez mettre à jour vos simulations. Les simulations nécessitent également des mises à jour si vous étendez la logique de votre application pour effectuer des appels vers de nouvelles API.

  • Les tests utilisant des simulations peuvent réussir dans les environnements de bureau, mais échouer dans le cloud. Les résultats peuvent ne pas correspondre à l'API actuelle. La configuration du service et les quotas ne peuvent pas être testés.

  • Les frameworks fictifs sont limités lorsqu'il s'agit de tester ou de détecter les limites de quotas ou de politiques de gestion des AWS identités et des accès (IAM). Bien que les simulations permettent de mieux simuler l'échec d'une autorisation ou le dépassement d'un quota, les tests ne peuvent pas déterminer le résultat qui se produira réellement dans un environnement de production.

Tester avec émulation

Les émulateurs sont généralement une application exécutée localement qui imite un service de production AWS .

Les émulateurs ont des API similaires à celles de leurs homologues dans le cloud et fournissent des valeurs de retour similaires. Ils peuvent également simuler des changements d'état initiés par des appels d'API. Par exemple, vous pouvez AWS SAM exécuter une fonction avec AWS SAM local pour émuler le service Lambda afin de pouvoir appeler rapidement une fonction. Pour plus d'informations, consultez AWS SAM local dans le Guide du développeur AWS Serverless Application Model .

Les avantages des tests avec émulateurs sont les suivants :

  • Les émulateurs peuvent faciliter les itérations de développement et les tests locaux rapides.

  • Les émulateurs fournissent un environnement familier aux développeurs habitués à développer du code dans un environnement local. Par exemple, si vous êtes habitué au développement d'une application à plusieurs niveaux, vous pouvez disposer d'un moteur de base de données et d'un serveur Web, similaires à ceux qui fonctionnent en production, exécutés sur votre ordinateur local afin de fournir une capacité de test rapide, locale et isolée.

  • Les émulateurs ne nécessitent aucune modification de l'infrastructure cloud (telle que les comptes cloud des développeurs). Ils sont donc faciles à implémenter avec les modèles de test existants.

Les tests avec des émulateurs présentent les inconvénients suivants :

  • Les émulateurs peuvent être difficiles à mettre en place et à répliquer, en particulier lorsqu'ils sont utilisés dans des pipelines CI/CD. Cela peut accroître la charge de travail du personnel informatique ou des développeurs qui gèrent leurs propres logiciels.

  • Les fonctionnalités et les API émulées sont généralement en retard par rapport aux mises à jour des services. Cela peut entraîner des erreurs parce que le code testé ne correspond pas à l'API réelle, et entraver l'adoption de nouvelles fonctionnalités.

  • Les émulateurs nécessitent une assistance, des mises à jour, des corrections de bogues et des améliorations de la parité des fonctions. La responsabilité en incombe à l'auteur de l'émulateur, qui peut être une société tierce.

  • Les tests qui s'appuient sur des émulateurs peuvent donner des résultats positifs au niveau local, mais échouer dans le cloud en raison des politiques de sécurité de la production, des configurations interservices ou du dépassement des quotas Lambda.

  • De nombreux AWS services ne disposent pas d'émulateurs. Si vous comptez sur l'émulation, vous risquez de ne pas disposer d'une option de test satisfaisante pour certaines parties de votre application.

Bonnes pratiques

Les sections suivantes fournissent des recommandations pour réussir les tests d'applications sans serveur.

Vous trouverez des exemples pratiques de tests et d'automatisation des tests dans le référentiel Serverless Test Samples.

Prioriser les tests dans le cloud

Les tests dans le cloud fournissent la couverture de test la plus fiable, la plus précise et la plus complète. La réalisation de tests dans le contexte du cloud permettra de tester de manière exhaustive non seulement la logique métier, mais également les politiques de sécurité, les configurations de service, les quotas, ainsi que les signatures d'API et les valeurs de retour les plus récentes.

Structurer votre code pour le rendre testable

Simplifiez vos tests et vos fonctions Lambda en séparant le code spécifique à Lambda de votre logique métier principale.

Votre gestionnaire de fonctions Lambda doit être un adaptateur léger qui prend en charge les données des événements et ne transmet que les détails importants à votre ou vos méthodes de logique métier. Avec cette stratégie, vous pouvez envelopper des tests complets autour de votre logique métier sans vous soucier des détails spécifiques à Lambda. Vos fonctions AWS Lambda ne devraient pas nécessiter la configuration d'un environnement complexe ou d'un grand nombre de dépendances pour créer et initialiser le composant testé.

D'une manière générale, vous devez écrire un gestionnaire qui extrait et valide les données des objets d'événement et de contexte entrants, puis envoie ces données aux méthodes qui exécutent votre logique métier.

Accélérer les boucles de rétroaction du développement

Il existe des outils et des techniques permettant d'accélérer les boucles de rétroaction du développement. Par exemple, AWS SAM Accelerate et le mode de surveillance AWS CDK réduisent tous deux le temps nécessaire à la mise à jour des environnements cloud.

Les exemples du référentiel GitHub Serverless Test Samples explorent certaines de ces techniques.

Nous vous recommandons également de créer et de tester les ressources cloud le plus tôt possible au cours du développement, et pas seulement après une vérification du contrôle du code source. Cette pratique permet d'accélérer l'exploration et l'expérimentation lors du développement de solutions. En outre, l'automatisation du déploiement à partir d'une machine de développement vous permet de découvrir plus rapidement les problèmes de configuration du cloud et de réduire les efforts inutiles liés aux mises à jour et aux processus de révision du code.

Se concentrer sur les tests d'intégration

Lors de la création d'applications avec Lambda, il est recommandé de tester les composants ensemble.

Les tests exécutés sur deux composants architecturaux ou plus sont appelés tests d'intégration. L'objectif des tests d'intégration est de comprendre non seulement comment votre code s'exécutera entre les composants, mais aussi comment l'environnement qui héberge votre code se comportera. Les nd-to-end tests E sont des types spéciaux de tests d'intégration qui vérifient les comportements dans l'ensemble d'une application.

Pour créer des tests d'intégration, déployez votre application dans un environnement cloud. Cela peut se faire à partir d'un environnement local ou par le biais d'un pipeline CI/CD. Rédigez ensuite des tests pour exécuter le système sous test (SUT) et valider le comportement attendu.

Par exemple, le système testé pourrait être une application qui utilise API Gateway, Lambda et DynamoDB. Un test peut effectuer un appel HTTP synthétique vers un point de terminaison d'API Gateway et valider que la réponse contient la charge utile attendue. Ce test confirme que le code AWS Lambda est correct et que chaque service est correctement configuré pour traiter la demande, y compris les autorisations IAM entre eux. En outre, vous pouvez concevoir le test pour écrire des enregistrements de différentes tailles afin de vérifier que vos quotas de service, tels que la taille d'enregistrement maximale dans DynamoDB, sont correctement configurés.

Schéma montrant un système en cours de test composé de trois services.

Créer des environnements de test isolés

Les tests dans le cloud nécessitent généralement des environnements de développement isolés, de sorte que les tests, les données et les événements ne se chevauchent pas.

L'une des approches consiste à fournir à chaque développeur un AWS compte dédié. Cela permettra d'éviter les conflits de dénomination des ressources qui peuvent survenir lorsque plusieurs développeurs travaillant dans une base de code partagée tentent de déployer des ressources ou d'invoquer une API.

Les processus de test automatisés doivent créer des ressources portant un nom unique pour chaque pile. Par exemple, vous pouvez configurer des scripts ou des fichiers de configuration TOML afin que les commandes SAM deploy ou sam sync de la AWS SAM CLI spécifient automatiquement une pile avec un préfixe unique.

Dans certains cas, les développeurs partagent un AWS compte. Cela peut être dû au fait que les ressources de votre pile sont coûteuses à exploiter, ou à provisionner et à configurer. Par exemple, une base de données peut être partagée pour faciliter la configuration et remplir correctement les données

Si les développeurs partagent un compte, vous devez définir des limites afin d'identifier les propriétaires et d'éliminer les chevauchements. L'un des moyens d'y parvenir est de mettre des préfixes sur les noms de piles avec les identifiants d'utilisateurs des développeurs. Une autre approche populaire consiste à configurer des piles basées sur des branches de code. Avec les limites de branches, les environnements sont isolés, mais les développeurs peuvent toujours partager des ressources, telles qu'une base de données relationnelle. Cette approche est une bonne pratique lorsque les développeurs travaillent sur plusieurs branches à la fois.

Les tests dans le cloud sont utiles pour toutes les phases de test, y compris les tests unitaires, les tests d'intégration et les end-to-end tests. Il est essentiel de maintenir une isolation adéquate, mais vous souhaitez tout de même que votre environnement d'assurance qualité ressemble le plus possible à votre environnement de production. C'est pourquoi les équipes ajoutent des processus de contrôle des modifications pour les environnements d'assurance qualité.

Pour les environnements de pré-production et de production, les limites sont généralement définies au niveau du compte afin d'isoler les charges de travail de leurs bruyants voisins et de mettre en œuvre des contrôles de sécurité du moindre privilège pour protéger les données sensibles. Les charges de travail sont soumises à des quotas. Vous ne voulez pas que vos tests consomment les quotas alloués à la production (voisin bruyant) ou qu'ils aient accès aux données des clients. Les tests de charge constituent une autre activité que vous devez isoler de votre pile de production.

Dans tous les cas, les environnements doivent être configurés avec des alertes et des contrôles afin d'éviter des dépenses inutiles. Par exemple, vous pouvez limiter le type, le niveau ou la taille des ressources qui peuvent être créées, et configurer des alertes par e-mail lorsque les coûts estimés dépassent un seuil donné.

Utiliser des simulations pour isoler la logique métier

Les cadres simulés sont un outil précieux pour écrire des tests unitaires rapides. Ils sont particulièrement utiles lorsque les tests couvrent une logique interne complexe, tels que des calculs mathématiques ou financiers ou des simulations. Recherchez les tests unitaires qui comportent un grand nombre de cas de test ou de variations d'entrée, dans lesquels ces entrées ne modifient ni le modèle ni le contenu des appels vers d'autres services cloud.

Le code couvert par des tests unitaires avec des simulations doit également être couvert par des tests dans le cloud. Cela est recommandé, car un ordinateur portable de développeur ou un environnement de machine de génération peuvent être configurés différemment d'un environnement de production dans le cloud. Par exemple, vos fonctions Lambda peuvent utiliser plus de mémoire ou de temps que ce qui est alloué lorsqu'elles sont exécutées avec certains paramètres d'entrée. Votre code peut également inclure des variables d'environnement qui ne sont pas configurées de la même manière (ou pas du tout), et les différences peuvent entraîner un comportement différent ou un échec du code.

L'avantage des simulations est moindre pour les tests d'intégration, car le niveau d'effort pour mettre en œuvre les simulations nécessaires augmente avec le nombre de points de connexion. nd-to-end Les tests E ne doivent pas utiliser de simulations, car ces tests portent généralement sur des états et une logique complexe qui ne peuvent pas être facilement simulés avec des frameworks fictifs.

Enfin, évitez d'utiliser des services cloud simulés pour valider la bonne mise en œuvre des appels de service. Au lieu de cela, faites des appels de services dans le cloud pour valider le comportement, la configuration et la mise en œuvre fonctionnelle.

Utiliser les émulateurs avec parcimonie

Les émulateurs peuvent être pratiques dans certains cas d'utilisation, par exemple pour une équipe de développement disposant d'un accès Internet limité, peu fiable ou lent. Mais, dans la plupart des cas, choisissez d'utiliser les émulateurs avec parcimonie.

En évitant les émulateurs, vous serez en mesure de construire et d'innover avec les dernières fonctionnalités de service et les API les plus récentes. Vous ne serez pas obligé d'attendre les versions des fournisseurs pour atteindre la parité des fonctionnalités. Vous réduirez vos dépenses initiales et continues liées à l'achat et à la configuration sur plusieurs systèmes de développement et machines de génération. En outre, vous éviterez le problème lié au fait que de nombreux services cloud n'ont tout simplement pas d'émulateurs disponibles. Une stratégie de test qui repose sur l'émulation rendra impossible l'utilisation de ces services (ce qui entraînera des solutions de contournement potentiellement plus coûteuses) ou produira un code et des configurations qui ne sont pas correctement testés.

Lorsque vous utilisez l'émulation à des fins de test, vous devez tout de même effectuer des tests dans le cloud pour vérifier la configuration et tester les interactions avec les services cloud qui ne peuvent être simulés que dans un environnement émulé.

Défis liés aux tests locaux

Lorsque vous utilisez des émulateurs et des appels simulés pour tester sur votre bureau local, vous pouvez rencontrer des incohérences de test lorsque votre code progresse d'un environnement à l'autre dans votre pipeline CI/CD. Les tests unitaires visant à valider la logique métier de votre application sur votre bureau peuvent ne pas tester avec précision certains aspects critiques des services cloud.

Les exemples suivants présentent des cas à surveiller lors de tests locaux à l'aide de simulations et d'émulateurs :

Exemple : la fonction Lambda crée un compartiment S3

Si la logique d'une fonction Lambda dépend de la création d'un compartiment S3, un test complet doit confirmer qu'Amazon S3 a été appelé et que le compartiment a été créé avec succès.

  • Dans le cas d'un test simulé, vous pouvez simuler une réponse de réussite et éventuellement ajouter un scénario de test pour gérer une réponse d'échec.

  • Dans un scénario de test d'émulation, l'CreateBucketAPI peut être appelée, mais vous devez savoir que l'identité à l'origine de l'appel local ne proviendra pas du service Lambda. L'identité appelante n'assumera pas un rôle de sécurité comme elle le ferait dans le cloud. C'est pourquoi une authentification par espace réservé sera utilisée à la place, éventuellement avec un rôle ou une identité d'utilisateur plus permissif qui sera différente lorsqu'elle sera exécutée dans le cloud.

Les configurations de simulation et d'émulation testeront ce que fera la fonction Lambda si elle appelle Amazon S3 ; toutefois, ces tests ne vérifieront pas que la fonction Lambda, telle que configurée, est capable de créer correctement le compartiment Amazon S3. Vous devez vous assurer que le rôle attribué à la fonction dispose d'une politique de sécurité attachée qui autorise la fonction à effectuer l'action s3:CreateBucket. Si ce n'est pas le cas, la fonction échouera probablement lorsqu'elle sera déployée dans un environnement en nuage.

Exemple : la fonction Lambda traite les messages d'une file d'attente Amazon SQS

Si une file d'attente Amazon SQS est la source d'une fonction Lambda, un test complet doit vérifier que la fonction Lambda est correctement invoquée lorsqu'un message est placé dans une file d'attente.

Les tests d'émulation et les tests simulés sont généralement configurés pour exécuter directement le code de la fonction Lambda et pour simuler l'intégration d'Amazon SQS en transmettant une charge utile d'événement JSON (ou un objet désérialisé) en tant qu'entrée du gestionnaire de fonction.

Les tests locaux qui simulent l'intégration d'Amazon SQS testeront ce que la fonction Lambda fera lorsqu'elle sera invoquée par Amazon SQS avec une charge utile donnée, mais le test ne vérifiera pas qu'Amazon SQS invoquera avec succès la fonction Lambda lors de son déploiement dans un environnement cloud.

Voici quelques exemples de problèmes de configuration que vous pouvez rencontrer avec Amazon SQS et Lambda :

  • Le délai de visibilité d'Amazon SQS est trop court, ce qui entraîne des invocations multiples alors qu'une seule était prévue.

  • Le rôle d'exécution de la fonction Lambda ne permet pas de lire les messages de la file d'attente (via sqs:ReceiveMessage, sqs:DeleteMessage, ou sqs:GetQueueAttributes).

  • L'exemple d'événement transmis à la fonction Lambda dépasse le quota de taille de message Amazon SQS. Par conséquent, le test n'est pas valide, car Amazon SQS ne sera jamais en mesure d'envoyer un message de cette taille.

Comme le montrent ces exemples, les tests qui couvrent la logique métier mais pas les configurations entre les services cloud sont susceptibles de fournir des résultats peu fiables.

FAQ

J'ai une fonction Lambda qui effectue des calculs et renvoie un résultat sans appeler aucun autre service. Dois-je vraiment le tester dans le cloud ?

Oui. Les fonctions Lambda comportent des paramètres de configuration susceptibles de modifier le résultat du test. Tout le code de fonction Lambda dépend du délai d'expiration et des paramètres de mémoire, ce qui peut entraîner l'échec de la fonction si ces paramètres ne sont pas définis correctement. Les politiques Lambda permettent également la journalisation des sorties standard sur Amazon. CloudWatch Même si votre code n'appelle pas CloudWatch directement, une autorisation est nécessaire pour activer la journalisation. Cette autorisation requise ne peut pas être simulée ou émulée avec précision.

Comment les tests dans le cloud peuvent-ils faciliter les tests unitaires ? S'il se trouve dans le cloud et se connecte à d'autres ressources, ne s'agit-il pas d'un test d'intégration ?

Nous définissons les tests unitaires comme des tests qui opèrent sur des composants architecturaux de manière isolée, ce qui n'empêche pas les tests d'inclure des composants susceptibles d'appeler d'autres services ou d'utiliser certaines communications réseau.

De nombreuses applications sans serveur possèdent des composants architecturaux qui peuvent être testés de manière isolée, même dans le cloud. Un exemple est celui d'une fonction Lambda qui prend une entrée, traite les données et envoie un message à une file d'attente Amazon SQS. Un test unitaire de cette fonction devrait permettre de vérifier si les valeurs d'entrée entraînent la présence de certaines valeurs dans le message en file d'attente.

Prenons l'exemple d'un test écrit en utilisant le modèle organiser, agir, affirmer :

  • Organiser : allouez des ressources (une file d'attente pour recevoir des messages et la fonction en cours de test).

  • Agir : appelez la fonction en cours de test.

  • Affirmer : récupérez le message envoyé par la fonction et validez la sortie.

Une approche de test simulé consiste à simuler la file d'attente avec un objet simulé en cours de traitement et à créer une instance en cours de traitement de la classe ou du module contenant le code de la fonction Lambda. Pendant la phase d'assertion, le message en file d'attente est récupéré dans l'objet simulé.

Dans une approche basée sur le cloud, le test crée une file d'attente Amazon SQS pour les besoins du test et déploie la fonction Lambda avec des variables d'environnement configurées pour utiliser la file d'attente Amazon SQS isolée comme destination de sortie. Après avoir exécuté la fonction Lambda, le test récupère le message dans la file d'attente Amazon SQS.

Le test basé sur le cloud exécute le même code, confirme le même comportement et valide l'exactitude fonctionnelle de l'application. Cela aurait toutefois l'avantage supplémentaire de pouvoir valider les paramètres de la fonction Lambda : le rôle IAM, les politiques IAM, ainsi que les paramètres de délai d'expiration et de mémoire de la fonction.

Prochaines étapes et ressources

Les ressources suivantes vous permettront d'en savoir plus et de découvrir des exemples pratiques de tests.

Exemples d'implémentations

Le référentiel Serverless Test Samples GitHub contient des exemples concrets de tests qui suivent les modèles et les meilleures pratiques décrits dans ce guide. Le référentiel contient des exemples de code et des descriptions guidées des processus de simulation, d'émulation et de test dans le cloud décrits dans les sections précédentes. Utilisez ce référentiel pour vous familiariser avec les derniers conseils de test sans serveur publiés par AWS.

Suggestions de lecture

Visitez Serverless Land pour accéder aux derniers blogs, vidéos et formations sur les technologies AWS sans serveur.

Il est également recommandé de lire les articles de AWS blog suivants :

Outils