Logomotion: Qualification
This commit is contained in:
parent
74a2e26f18
commit
1baa61d2e8
|
@ -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
|
||||
|
||||
|
@ -19,6 +19,8 @@ William Petit - S.C.O.P. Cadoles
|
|||
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## La pyramide des tests applicatifs
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue