Pourquoi Tester Vue avec Cypress ?
Tester Vue.js est essentiel pour les développeurs web modernes qui cherchent à garantir la qualité et la fiabilité de leurs applications. Environ 80% des erreurs dans les applications web sont liées aux bugs d'interface utilisateur. Cypress offre une solution complète et intuitive pour tester votre application Vue.js de bout en bout, en simulant des interactions réelles avec le navigateur.
Un cas d'utilisation concret est l'équipe de développement qui souhaite s'assurer que les nouveaux fonctionnalités ajoutées à leur application ne cassent pas les fonctionnalités existantes. Par exemple, une équipe de développement pourrait tester si un nouveau bouton de formulaire soumet correctement les données et affiche les messages d'erreur appropriés.
Prerequis
Avant de commencer, vous devrez avoir les éléments suivants :
- Node.js (version recommandée 14.0 ou plus tard)
- Vue CLI (pour créer un nouveau projet Vue)
Installation des Outils
Installez Node.js à partir du site officiel (https://nodejs.org/) en téléchargeant la version LTS.
Une fois Node.js installé, installez Vue CLI via npm :
npm install -g @vue/cli
Concepts fondamentaux
1. Cypress
Cypress est un framework d'automatisation de tests E2E (End-to-End) conçu pour les applications web. Il permet de tester le comportement des utilisateurs en simulant des interactions réelles avec le navigateur.
Schéma Mental :
+-------------------+
| Cypress |
| |
| 1. Lance le |
| navigateur |
| 2. Simule les |
| interactions |
| utilisateur |
| 3. Vérifie les |
| résultats |
+-------------------+
Code Exemple :
// Importer Cypress
import { describe, it } from 'cypress';
describe('Test d\'un bouton', () => {
it('Devrait cliquer sur un bouton et vérifier le résultat', () => {
cy.visit('/'); // Visiter l'URL de la page
cy.get('#monBouton').click(); // Cliquez sur le bouton
cy.get('#message').should('contain', 'Action effectuée avec succès'); // Vérifiez le message
});
});
2. Commandes Cypress
Cypress fournit une API riche de commandes pour interagir avec votre application.
Schéma Mental :
+-------------------+
| Commandes Cypress |
| |
| 1. cy.visit(url) |
| - Visiter une URL|
| 2. cy.get(selector)|
| - Sélectionner un élément|
| 3. cy.click() |
| - Clic sur un élément|
| 4. cy.type(text) |
| - Saisir du texte |
| 5. cy.should(value)|
| - Vérifier une condition|
+-------------------+
Code Exemple :
// Importer Cypress
import { describe, it } from 'cypress';
describe('Test d\'une saisie utilisateur', () => {
it('Devrait saisir du texte dans un champ et vérifier le résultat', () => {
cy.visit('/'); // Visiter l'URL de la page
cy.get('#monChamp').type('Mon texte'); // Saisir du texte
cy.get('#message').should('contain', 'Texte saisi : Mon texte'); // Vérifiez le message
});
});
3. Fixtures
Les fixtures permettent de charger des données fictives pour les tests.
Schéma Mental :
+-------------------+
| Fixtures |
| |
| 1. Créez un fichier|
| JSON (ex: users.json)|
| 2. Utilisez cy.fixture()|
| - Charger le fichier|
+-------------------+
Code Exemple :
// users.json
[
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" }
]
// Test utilisant la fixture
import { describe, it } from 'cypress';
describe('Test avec des fixtures', () => {
it('Devrait afficher les noms des utilisateurs', () => {
cy.visit('/'); // Visiter l'URL de la page
cy.fixture('users').then(users => {
users.forEach(user => {
cy.get(`#user-${user.id}`).should('contain', user.name);
});
});
});
});
4. Mocks et Stubs
Les mocks et stubs permettent de simuler des comportements spécifiques pour les services ou les composants.
Schéma Mental :
+-------------------+
| Mocks / Stubs |
| |
| 1. cy.intercept(url, response)|
| - Simuler une requête HTTP|
| 2. Stub un service |
| - Remplacer une méthode de service par une fonction mockée|
+-------------------+
Code Exemple :
// Test avec un mock pour simuler une requête HTTP
import { describe, it } from 'cypress';
describe('Test avec un mock', () => {
it('Devrait afficher les données simulées', () => {
cy.intercept('/api/users', {
body: [
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" }
]
});
cy.visit('/'); // Visiter l'URL de la page
cy.get('#user-1').should('contain', 'Alice');
cy.get('#user-2').should('contain', 'Bob');
});
});
5. Composants Cypress
Cypress fournit des composants pour créer des tests réutilisables.
Schéma Mental :
+-------------------+
| Composants Cypress|
| |
| 1. cy.wrap(subject)|
| - Créer un objet wrappeur|
| 2. cy.then(callback)|
| - Exécuter une fonction avec le sujet|
+-------------------+
Code Exemple :
// Test utilisant un composant Cypress
import { describe, it } from 'cypress';
describe('Test avec un composant', () => {
it('Devrait afficher les données du composant', () => {
cy.visit('/'); // Visiter l'URL de la page
cy.get('#monComposant').then($component => {
const data = $component.data();
expect(data.message).to.equal('Bienvenue');
});
});
});
Mise en pratique : Projet fil rouge
Nous allons créer un gestionnaire de tâches simple pour mettre en pratique les concepts Cypress.
Étape 1 : Créer le projet Vue.js
vue create todo-app
cd todo-app
npm install cypress --save-dev
npx cypress open
Étape 2 : Configurer le projet
Créez un fichier cypress.json dans le répertoire racine du projet :
{
"baseUrl": "http://localhost:8080"
}
Étape 3 : Créer les composants et routes
src/components/TodoItem.vue
<template>
<div class="todo-item">
<span>item.text</span>
<button @click="deleteTodo">Supprimer</button>
</div>
</template>
<script>
export default {
props: ['item'],
methods: {
deleteTodo() {
this.$emit('delete', this.item.id);
}
}
};
</script>
src/components/TodoList.vue
<template>
<div class="todo-list">
<h1>Gestionnaire de tâches</h1>
<input v-model="newTodo" @keyup.enter="addTodo" placeholder="Ajouter une tâche" />
<ul>
<li v-for="item in todos" :key="item.id">
<todo-item :item="item" @delete="removeTodo(item.id)" />
</li>
</ul>
</div>
</template>
<script>
import TodoItem from './TodoItem.vue';
export default {
components: { TodoItem },
data() {
return {
todos: [],
newTodo: ''
};
},
methods: {
addTodo() {
if (this.newTodo.trim()) {
this.todos.push({ id: Date.now(), text: this.newTodo });
this.newTodo = '';
}
},
removeTodo(id) {
this.todos = this.todos.filter(todo => todo.id !== id);
}
}
};
</script>
src/App.vue
<template>
<div id="app">
<todo-list />
</div>
</template>
<script>
import TodoList from './components/TodoList.vue';
export default {
name: 'App',
components: { TodoList }
};
</script>
Étape 4 : Créer les tests Cypress
cypress/integration/todo.spec.js
describe('Gestionnaire de tâches', () => {
it('Devrait ajouter une tâche et la supprimer', () => {
cy.visit('/');
// Ajouter une tâche
cy.get('#newTodo').type('Faire les courses{enter}');
cy.get('.todo-item').should('contain', 'Faire les courses');
// Supprimer la tâche
cy.get('.todo-item button').click();
cy.get('.todo-item').should('not.contain', 'Faire les courses');
});
});
Erreurs fréquentes et debugging
Erreur 1 : Element not found
// Code incorrect
cy.get('#nonExistant');
// Code correct
cy.get('#monElement').should('exist');
Erreur 2 : Unexpected token
// Code incorrect
const data = { name: 'Alice' };
cy.wrap(data).its('name');
// Code correct
cy.wrap({ name: 'Alice' }).its('name');
Erreur 3 : Command failed with status code 127
## Code incorrect
npx cypress open
## Code correct
npm run serve
npx cypress open
Pour aller plus loin
- Tests Asynchrones : Apprenez à gérer les tests asynchrones avec Cypress (https://docs.cypress.io/guides/core-concepts/async.html).
- Plugins Cypress : Explorez les plugins Cypress pour étendre ses fonctionnalités (https://docs.cypress.io/plugins/introduction.html).
- Tests UI personnalisés : Apprenez à créer des tests UI personnalisés avec Cypress et Vue.js.
Défi pratique
Créez un test qui vérifie que l'ajout d'une tâche ne fonctionne pas si le champ est vide.