diff --git a/qualification/presentation/slides.md b/qualification/presentation/slides.md index ac09541..d916f34 100644 --- a/qualification/presentation/slides.md +++ b/qualification/presentation/slides.md @@ -1,4 +1,4 @@ - + # Qualification et intégration continue @@ -17,7 +17,9 @@ William Petit - S.C.O.P. Cadoles ## Les tests applicatifs -Les tests applicatifs ont pour objectif de valider le bon fonctionnement de l'application d'un point de vue métier, c'est à dire de vérifier que celle ci répond aux attentes et aux contraintes du client d'un point de vue fonctionnel. +Les tests applicatifs ont pour objectif de valider le bon fonctionnement de l'application d'un point de vue métier, c'est à dire de vérifier que celle ci répond aux attentes et aux contraintes du client d'un point de vue fonctionnel. + +Ils permettent également et surtout aux développeurs de **détecter les régressions** dans le cycle de développement. --- @@ -35,6 +37,8 @@ Les tests applicatifs ont pour objectif de valider le bon fonctionnement de l'ap Tester le bon fonctionnement des plus petites unités logiques/fonctionnelles de l'application: les fonctions/méthodes d'objets. +**Exemple** Vérifier qu'une méthode de calcul du prix taxé d'un produit retourne la valeur attendue en fonction des paramètres passés. + --- ## Cycle de vie @@ -49,7 +53,7 @@ Tester le bon fonctionnement des plus petites unités logiques/fonctionnelles de ## Caractéristiques clés - Ils sont nombreux. -- Ils sont mis en place dès le début de l'implémentation, voir avant. +- Ils sont mis en place dès le début de l'implémentation, voir avant (voir "Test Driven Development"). - Ils sont rapides à exécuter. - Ils permettent de détecter rapidement les régressions. - Ils permettent de rassurer le développeur qui doit apporter des évolutions à une base de code existante. @@ -60,13 +64,42 @@ Tester le bon fonctionnement des plus petites unités logiques/fonctionnelles de ## Exemple: Tests unitaires en Javascript (Mocha) -TODO +```javascript +// Fichier test/my-test-suite.js + +const assert = require('assert'); + +// Déclaration de la suite de tests +describe('My suite', function() { + + // Test synchrone + it('should not fail', function() { + assert.equal(true, 1); // true == 1 en javascript + }); + + // Test asynchrone + it('should do something async', function() { + + return doSomethingAsync() + .then(result => { + assert.ok(result); // On vérifie que le résultat n'est pas null + }) + .catch(err => { + assert.ifError(err); // On vérifie qu'aucune erreur n'est remontée + }) + ; + + }); + +}); +``` --- -## Exemple: Tests unitaires en PHP (Symfony3) +## Et le style dans tout ça ? -TODO +- Javascript: https://eslint.org/ +- PHP: https://github.com/phpro/grumphp --- @@ -76,9 +109,10 @@ Soit un numéro de carte bancaire donné, implémenter un test pour la fonction **Ressources** +- [Mocha - Librairie de test](https://mochajs.org/) +- [Module `assert`](https://nodejs.org/api/assert.html) - [La formule de Luhn](https://fr.wikipedia.org/wiki/Formule_de_Luhn) - --- ## Tests d'intégration @@ -87,7 +121,9 @@ Soit un numéro de carte bancaire donné, implémenter un test pour la fonction ## Objectifs -Tester la bonne communication des différents "modules" composant une application. +Tester la bonne communication et interaction des différents "modules" composant une application. + +**Exemple** Vérifier que qu'une transaction est correctement enregistrée dans la base de données lorsque le module de paiement est utilisé. --- @@ -113,9 +149,18 @@ Les tests d'intégration peuvent être un bon témoin/validateur de l'état de r --- -## Exemple: Test de la soumission d'un formulaire (Symfony3) +## Exemple: Test d'une API REST avec Symfony3 -TODO +1. Implémenter une API JSON/REST basique avec Symfony3 permettant d'enregistrer/lister dans une base de données (sqlite3) une "annonce" avec les propriétés suivantes: + - Titre + - Description + - Type + - Prix +2. Implémenter avec la librairie standard de Symfony3 les tests suivants: + - Ajout d'une nouvelle annonce et vérification du bon enregistrement de la nouvelle annonce via un appel sur l'URL d'affichage des annonces + +**Ressources** +- [Symfony3 - Working with the Test client](http://symfony.com/doc/current/testing.html#working-with-the-test-client) --- @@ -142,7 +187,7 @@ Tester le bon fonctionnement de l'application d'un point de vue utilisateur. ## Cycle de vie -Les tests fonctionnels devraient être implémentés une fois que l'itération a été validée par le client. +Les tests fonctionnels devraient être implémentés une fois que l'itération a atteint une certaine stabilité en terme d'interface utilisateur. Ils ne devraient être modifiés que lorsque le client demande une évolution de l'interface utilisateur et/ou des cinématiques d'action. @@ -150,13 +195,13 @@ Ils ne devraient être modifiés que lorsque le client demande une évolution de ## Exemple: Tests fonctionnels Web avec NightmareJS -TODO +Voir l'exemple `tests-fonctionnels` --- -## Exercice: Tester une procédure d'authentification d'un utilisateur +## Exercice: Simuler un utilisateur avec le client web KiwiIRC -TODO +Via NightmareJS et avec le client [KiwiIRC](https://kiwiirc.com/nextclient/), se connecter au serveur `irc.freenode.net`, rejoindre le canal `#cadoles` en tapant la commande `/join ` puis envoyer un message sur le canal nouvellement rejoint. --- @@ -194,7 +239,9 @@ Les tests de charge devraient être exécutés régulièrement afin de vérifier --- -## Exemple: Utilisation d'Apache Benchmark pour vérifier le temps de réponse d'une application Web +## Exemple: Utilisation de Siege pour vérifier les temps de réponse d'une application Web + +https://www.joedog.org/siege-home/ --- @@ -229,21 +276,30 @@ Ils doivent être réactualisés lors de tout changement d'infrastructure et de ## Exemple: Vérification de sécurité pour les dépendances PHP -TODO https://github.com/sensiolabs/security-checker +https://github.com/sensiolabs/security-checker --- -## Exemple: Tests d'attaques automatisées sur les applications Web avec w3af +## Exemple: Audit automatisé sur les applications Web avec w3af -TODO https://tools.kali.org/web-applications/w3af +https://github.com/andresriancho/w3af/ --- -## Les serveurs d'intégration continue +## Le cycle (simplifié) d'intégration continue + +![center 60%](./img/cycle_dintgration_continue.png?1) --- -## Technologies de conteneurisation +## Automatisation, virtualisation et conteneurisation + +--- + +## Principes généraux sur les conteneurs + +- Les conteneurs sont un mécanisme de virtualisation basée sur l'isolation des processus au niveau du système d'exploitation. +- Ils bénéficient d'une très faible perte de performances brutes par rapport à de la virtualisation classique utilisation des mécanismes d'émulation. --- @@ -251,12 +307,151 @@ TODO https://tools.kali.org/web-applications/w3af --- +## Manipuler des images de conteneur + +--- + +## Exécuter un conteneur + +--- + +## Gérer les conteneurs + +--- + +## Partager des répertoires + +--- + +## Configurer le réseau d'un conteneur + +--- + +## Construire une image + +--- + +## Publier une image sur le Hub + +--- + +## Utiliser `docker-compose` + +--- + +## Le fichier `docker-compose.yml` + +```yaml +version: '2' # Version du fichier docker-compose +services: # Déclaration des services + faketools: # Service 'faketools' + build: # Création de l'image du conteneur depuis un dossier du projet + context: . + dockerfile: containers/faketools/Dockerfile + args: # Déclaration d'arguments de construction de l'image + HTTP_PROXY: ${HTTP_PROXY} + HTTPS_PROXY: ${HTTPS_PROXY} + http_proxy: ${http_proxy} + https_proxy: ${https_proxy} + ports: # Déclaration des ports à exposer sur la machine hôte + - "8080:8080" + - "8081:8081" + - "2525:2525" + - "3389:3389" + - "8443:8443" + - "2222:22" + volumes: # Déclaration des montages de volumes + - ./data:/faketools/data + environment: # Déclaration de variables d'environnement + HTTP_PROXY: ${HTTP_PROXY} + HTTPS_PROXY: ${HTTPS_PROXY} + http_proxy: ${http_proxy} + https_proxy: ${https_proxy} + +``` + +--- + +## Exercice + +Créer un environnement de développement `docker-compose` à partir de l'image `ubuntu:xenial` pour une application Symfony3 et une base de données MySQL avec l'image `mysql:latest`. + +Le répertoire des sources locales devra être partagé avec le conteneur d'application et le port du conteneur exposé sur la machine hôte. + +--- + +## Les serveurs d'intégration continue + +https://docs.gitlab.com/ce/ci/ +https://jenkins.io/ +https://drone.io/ + +--- + ## Exemple: Gitlab et Gitlab Runner --- +## Le fichier `.gitlab-ci.yml` + +```yaml +# Déclaration de variables utilisables dans le fichier +variables: + MY_VAR: Hello World + +# Nom de l'image Docker à utiliser pour les différentes phases du pipeline +image: + +# Listes de commandes à exécuter dans le conteneur +# avant le lancement des différents jobs +before_script: + - echo ${MY_VAR} + +# Déclaration des phases du pipeline +stages: + - test + - dist + +# Déclaration d'un job +unit-tests: + stage: test # Ce job est attaché à la phase "test" + script: # Commandes à exécuter dans le conteneur + - ./script/test + +# Déclaration d'un autre job +dist: + stage: dist # Ce job est attaché à la phase "dist" + only: # Ce job ne doit s'exécuter que lorsque la branche est "master" + refs: + - master + script: + - ./script/dist + artifacts: # Artefacts à conserver à l'issue de la phase + paths: + - dist/*.tar.gz +``` + +--- + +## Exécuter un pipeline en local + +
+gitlab-runner exec docker [job]
+
+ +> La fonctionnalité est dépréciée depuis la version 10.0. Voir la discussion https://gitlab.com/gitlab-org/gitlab-runner/issues/2797 pour le futur remplacement. + +--- + ## Exercice: Mise en application générale +Sélectionner une application existante (ou laissez le formateur vous proposer un sujet) et: + +1. Mettre en place l'exécution des tests unitaires sur le projet et écrire une première suite de tests. +2. Mettre en place les tests d'intégration sur le projet et écrire une première suite de tests. +3. Mettre en place les tests fonctionnels et écrire une première suite de tests. +4. Concevoir un "pipeline" d'intégration continue avec Gitlab et Gitlab Runner et tester une activation complète du pipeline. + --- # Licence