Blog ENI : Toute la veille numérique !
🐠 -25€ dès 75€ 
+ 7 jours d'accès à la Bibliothèque Numérique ENI. Cliquez ici
Accès illimité 24h/24 à tous nos livres & vidéos ! 
Découvrez la Bibliothèque Numérique ENI. Cliquez ici
  1. Livres et vidéos
  2. AWS Lambda
  3. Tester les fonctions Lambda
Extrait - AWS Lambda Développez des micro-services en Java sur la plateforme serverless d'Amazon
Extraits du livre
AWS Lambda Développez des micro-services en Java sur la plateforme serverless d'Amazon
1 avis
Revenir à la page d'achat du livre

Tester les fonctions Lambda

Introduction

Une des conditions sine qua non pour un code robuste et fiable est de disposer d’une base de test solide, couvrant le maximum des fonctionnalités des applications et services. Plus notre base de test est solide, plus on est confiant lorsqu’il s’agit d’ajouter de nouvelles fonctionnalités, de fixer des anomalies ou de procéder à des opérations de refactoring complexes.

Dans les chapitres précédents, nous venons de développer un mini-projet qui a été testé manuellement. Vous l’avez peut-être constaté, ces tests manuels ont été assez laborieux, car répétitifs. De plus, il a fallu que tous les composants soient disponibles au même moment. Ainsi, pour tester notre moulinette consistant à recevoir un fichier XML avec des ordres de virements bancaires et le traiter, il a fallu que nos services REST soient disponibles et accessibles via l’API Gateway, que la file d’attente dédiée soit créée et configurée, que notre base de données DynamoDB soit en place, et que toutes les fonctions Lambda soient implémentées, etc.

Mais cette situation n’est pas du tout typique d’un projet réel. Imaginez une équipe de développeurs travaillant en parallèle sur différentes fonctionnalités d’une...

La pyramide des tests

L’expression « pyramide des tests » est une métaphore utilisée pour la première fois dans un ouvrage très connu de Mike Cohn, paru en 2009 et intitulé Succeeding with Agile. Dans cet ouvrage, l’auteur définit cette pyramide des tests comme l’ensemble des tests qui accompagnent nos applications et services et dont le rôle est de garantir la qualité du code.

La pyramide des tests Lambda

La pyramide des tests

L’activité de test a beaucoup évolué depuis et, selon les auteurs, il existe différentes classifications, mais elles convergent toutes généralement vers une pyramide à trois couches :

  • Les tests unitaires, qui représentent la base de la pyramide. Il s’agit des tests dont l’objet est constitué par l’ensemble des fonctionnalités de nos composants ou applications et qui sont effectués en complète isolation, à l’exclusion de toute dépendance externe. Ce sont des tests plutôt simples, tentant à garantir que chaque composant est valide séparément. Vu leur relative simplicité, ils sont généralement très nombreux, ce qui fait qu’ils se trouvent à la base de la pyramide. Les tests unitaires sont automatiques et doivent pouvoir s’exécuter rapidement. Typiquement, lorsqu’une...

Les tests unitaires

En Java, les tests unitaires sont exécutés avec JUnit, un framework open source qui permet de définir des cas de tests et les exécuter. C’est un framework qui date de 1997, mais sa version la plus récente, la 5, apporte un certain nombre de nouveautés liées aux nouvelles versions de Java (de 8 à 14). La documentation complète se trouve ici : https://junit.org/junit5/docs/current/user-guide

Cet ouvrage n’est pas un ouvrage sur JUnit et, par conséquent, nous n’allons pas pouvoir couvrir ici les détails de son fonctionnement. Le listing suivant reproduit un des tests unitaires avec JUnit qui est fourni avec le projet chapter6 :

package fr.simplex_software.aws.lambda.functions.tests; 
import fr.simplex_software.eip.money_transfer.jaxb.*; 
import org.junit.jupiter.api.*; 
import javax.xml.bind.*; 
import java.io.*; 
import java.math.*; 
import static org.junit.jupiter.api.Assertions.*; 
public class TestJAXB 
{ 
  @Test 
  public void testUnmarshaller() throws JAXBException 
  { 
    JAXBContext jaxbContext = 
JAXBContext.newInstance(MoneyTransfers.class); 
    Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 
    MoneyTransfers mt = (MoneyTransfers) jaxbUnmarshaller.unmarshal 
(new File("src/main/resources/xsd/money-xfer.xml")); 
    assertNotNull(mt); 
    assertTrue(mt.getMoneyTransfers().size() > 0); 
    assertEquals(mt.getMoneyTransfers().get(0).getAmount(), 
new BigDecimal("1000.00")); 
  } 
} 

Un test unitaire JUnit est une classe Java publique où les méthodes, publiques elles aussi, n’ont pas d’arguments d’entrée et ne renvoient pas de résultat. Elles sont annotées avec l’annotation JUnit @Test.

La classe de test ci-dessus est utilisée pour valider les modèles de données de notre service de paiement bancaire. Un unmarshaller JAXB est instancié et un fichier XML contenant des ordres de virements y est injecté. Le but du test étant de vérifier qu’un modèle de données valide est créé...

Les tests d’intégration

Contrairement aux tests unitaires qui s’effectuent séparément pour chaque composant, les tests d’intégration doivent s’effectuer en tenant compte de l’interaction entre tous les composants impliqués, mais sans que pour autant nous ayons à utiliser un cloud réel, auquel se connecter (et, éventuellement, payer la facture associée). L’utilitaire SAM permet de tester localement des fonctions Lambda, sans connexion cloud et sans compte réel AWS, avec ou sans API Gateway. Ainsi, la commande sam local start-api démarre une instance d’API Gateway qui tourne localement, permettant de tester des requêtes HTTP. Par exemple :

 Allez dans le répertoire du projet chapter5 et exécutez la commande suivante :

git checkout testing 

 Cette commande vous positionne sur la branche testing de votre repository.

 Exécutez maintenant le commande suivante :

nicolas@BEL20:~/AWSLambda/projects/aws-lambda/chapter6$ sam local start-api 
Mounting CreateMoneyTransferOrderFunction at http://127.0.0.1:3000/orders [POST] 
Mounting RemoveMoneyTransferOrderFunction at http://127.0.0.1:3000/orders [DELETE] 
Mounting UpdateMoneyTransferOrderFunction at http://127.0.0.1:3000/orders [PUT] 
Mounting GetMoneyTransferOrderFunction at http://127.0.0.1:3000/orders [GET] 
You can now browse to the above endpoints to invoke your functions. You do not need 
to restart/reload SAM CLI while working on your functions, changes will be reflected 
instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM 
template 
2020-08-31 18:18:59  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit) 

 L’utilitaire SAM inspecte le fichier template.yaml et voit qu’il contient une configuration API Gateway avec les fonctions Lambda associées. Il crée donc un point d’entrée HTTP à http://127.0.0.1:3000/orders où on peut poser des requêtes HTTP afin de les tester.

 Comme on le voit dans le listing ci-dessus, les requêtes acceptées sont GET, POST, PUT et DELETE.

 Ouvrez la classe de test LambdaIT :

package fr.simplex_software.aws.lambda.s3.functions.tests; 
import fr.simplex_software.aws.lambda.common.*; 
import org.jboss.resteasy.client.jaxrs.engines.*; ...

Les tests e2e

Les tests e2e sont les tests effectués en condition réelle à 100 %, en utilisant un compte AWS valide et en s’y connectant pour créer des piles CloudFormation avec leurs éléments d’infrastructure nécessaires comme les containers S3, les files d’attente, les tables DynamoDB, etc. C’est la démarche que nous avions adoptée lors des tests effectués pour notre mini-projet des chapitres précédents, à la différence près que ces tests étaient manuels. Or, pour que les tests e2e soient vraiment efficaces, il faut qu’ils soient automatisés.

Le projet chapter7 contient un exemple de test e2e.

 Allez dans le répertoire du projet chapter7 et exécutez la commande suivante :

git checkout testing 

 Cette commande vous positionne sur la branche testing de votre repository.

 Ouvrez le fichier deploy-all.sh :

#!/bin/bash 
RANDOM=$$ 
BUCKET_NAME=bucketname-$RANDOM 
STAGE_NAME=dev 
AWS_REGION=$(aws configure list | grep region | awk '{print $2}') 
aws s3 mb s3://$BUCKET_NAME 
echo $BUCKET_NAME > bucket-name.txt 
aws s3 cp openapi.yaml s3://$BUCKET_NAME/openapi.yaml 
sam deploy --template-file ../chapter6/template.yaml --s3-bucket $BUCKET_NAME  
--stack-name chapter6-stack --capabilities CAPABILITY_IAM -parameter-overrides ...