Logomotion: Qualification

This commit is contained in:
wpetit 2018-03-20 14:03:21 +01:00
parent 74a2e26f18
commit 1baa61d2e8

View File

@ -1,4 +1,4 @@
<style>pre, table { font-size: 0.6em !important; }</style>
<style>pre, table { font-size: 0.5em !important; }</style>
# 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 <canal>` 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: <image_docker>
# 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
<pre style="font-size:0.8em!important">
gitlab-runner exec docker [job]
</pre>
> 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