Fermer

mai 5, 2025

Vue Basics: Testing with Vitest

Vue Basics: Testing with Vitest


Les tests sont essentiels pour la fiabilité de nos applications. Voir les éléments essentiels du test des applications Vue à l’aide de Vitest et @ Vue / Test-Utils.

Imaginez remplir un long formulaire sur un site Web, enfin arriver à la fin et cliquer sur le bouton Soumettre tout en commençant à célébrer le travail accompli. Cependant, rien ne se passe. Vous décidez d’ouvrir les Devtools, seulement pour voir un tas d’erreurs apparaître lorsque vous appuyez à nouveau sur le bouton Soumettre.

Une situation comme celle-ci peut être très décourageante et les utilisateurs abandonnent souvent les sites Web après ces épreuves. Heureusement, en tant que développeurs, il y a des choses que nous pouvons faire pour réduire les chances de quelque chose comme ça se passe. L’un d’eux est les tests. Dans cet article, nous couvrirons comment configurer et exécuter des tests avec Virest dans une application VUE.

Pourquoi les tests sont-ils importants?

Une suite de tests automatisée peut être cruciale pour le succès d’une application, car elle peut améliorer la fiabilité de l’application, réduire la survenue de bogues et augmenter la vitesse de la fourniture de nouvelles fonctionnalités et des mises à jour des fonctionnalités existantes.

Avec les tests automatisés, les développeurs peuvent être plus confiants que le code qu’ils ont écrit est sans bug et ne rompra pas les fonctionnalités existantes. Il existe trois principaux types de tests qui peuvent être utilisés pour les applications VUE:

1. Test unitaire
Vérifiez le comportement des petites fonctions, des composants et des composants isolément. Par exemple, un test unitaire pourrait vérifier si un composant Tabs fonctionne correctement et modifie l’onglet Active sur un clic.

2. Test d’intégration
Affirmer plusieurs composants et unités fonctionnent ensemble en cohésion.

3. Test de bout en bout (E2E)
Simuler un réel utilisateur et tester l’intégralité de la fonctionnalité de l’ouverture du navigateur, visiter l’URL et interagir avec le site Web pour vérifier que le frontend fonctionne de manière transparente avec le serveur et les utilisateurs peuvent accomplir des tâches spécifiques.

Il y a des avantages et des inconvénients à chacun. Bien que les tests d’unité et d’intégration puissent s’exécuter plus rapidement, car la plupart du temps, ils sont testés isolément sans avoir besoin de demandes d’API et interagissant avec tous les services, les tests de bout en bout peuvent fournir le plus de confiance, car ils testent que l’ensemble du système de l’interface utilisateur à la base de données fonctionne comme prévu.

Qu’est-ce qui est le plus vitre?

Pendant de nombreuses années, Est était le cadre de test de choix pour les applications JavaScript en raison de ses fonctionnalités robustes, de sa communauté mature et du système de plugin et de la compatibilité avec de nombreux cadres et bibliothèques.

Cependant, la plaisanterie peut être assez lente dans des applications plus grandes qui pourraient comprendre des centaines, voire des milliers de fichiers et de tests. De plus, cela ne fonctionne pas non plus bien avec des outils modernes tels que Vite qui reposent sur les modules ES, car Jest utilise des modules CommonJS.

C’est là que Engrenage Entré en jeu. Vitest est un cadre de test moderne qui flamboie rapidement par rapport à la plaisanterie et à de nombreuses autres solutions. Il a une prise en charge prête à l’emploi pour les modules ES, TypeScript, JSX et a une API compatible en plaisantant, ce qui signifie que la migration de la plaisanterie est très simple.

Il dispose également d’autres fonctionnalités intéressantes, telles que le mode navigateur, les tests à source ou les tests de type. Vous pouvez en savoir plus sur toutes les fonctionnalités du documentation.

Configuration du projet avec Vue, Vite et Vitest

La meilleure façon d’apprendre à coder est par la pratique, alors configurons un nouveau projet VUE avec Vite. Après la configuration, nous créerons un composant Vue simple, puis écrivons des tests unitaires avec Vitest pour tester que le composant fonctionne comme prévu. Vous pouvez également trouver le code complet de cet article dans Ce référentiel GitHub.

Pour échafauner un nouveau projet VUE, ouvrez le terminal et exécutez la commande suivante:

# npm 7+, extra double-dash is needed:
$ npm create vite@latest vue-vitest-basics -- --template vue

Cette commande créera un nouveau projet dans le vue-vitest-basics dossier. Une fois l’installation terminée, transformez le répertoire en vue-vitest-basics et installer vitest, @vue/test-utils et jsdom.

$ cd vue-vitest-basics
$ npm install -D vitest @vue/test-utils jsdom

Si vous vous demandez pourquoi nous devons installer @vue/test-utilsvoici la raison. Varest lui-même est un coureur de test, mais son framewor-agnostique. Par conséquent, il ne sait pas hors de la boîte comment gérer les composants Vue. Pour cela, nous avons besoin d’une bibliothèque distincte. @vue/test-utils est la bibliothèque de test officielle fournie par l’équipe VUE.JS. Bien qu’il existe d’autres solutions possibles, comme Bibliothèque de tests Vuedans cet article, nous nous concentrerons sur l’utilisation @vue/test-utils.

Une autre bibliothèque que nous devons inclure est jsdom. Par défaut, Vitest exécute des tests dans l’environnement du nœud. Cependant, les composants Vue doivent être montés dans un environnement de type navigateur. Étant donné que nous exécuterons nos tests unitaires dans Node, nous devons configurer Veest pour simuler l’environnement du navigateur. Nous pouvons le faire en mettant à jour le vite.config.js fichier et ajout test.environment config.

vite.config.js

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";


export default defineConfig({
  plugins: [vue()],
  test: {
    environment: "jsdom",
  },
});

Enfin, vous pouvez démarrer l’environnement de développement en exécutant la commande ci-dessous.

$ npm run dev

Vous pouvez visiter http://localhost:5173 dans votre navigateur pour voir la page de départ.

Une autre chose que nous devons faire dans le cadre de la configuration est de mettre à jour le package.json déposer. Ajouter un nouveau test script qui fonctionnera le plus vitre.

package.json

"scripts": {
  
  "test": "vitest"
}

Nous n’avons pas encore de fichiers de test, mais nous y arriverons dans un instant. Vous pouvez déjà exécuter la commande de test dans le terminal pour démarrer le plus vitre.

Construire un composant d’onglets simples

Créons un simple Tabs Composant qui rendra les boutons d’onglet en fonction des accessoires fournis. Le Tabs Le composant acceptera deux accessoires: tabs et modelValue. Le premier sera un éventail de chaînes pour chaque onglet qui devrait être affichée, tandis que la première représentera l’onglet actuellement actif. Voici le code du composant.

src / composants / onglets.vue

<script setup>
const props = defineProps({
  tabs: {
    type: Array,
    default: () => [],
  },
  modelValue: {
    type: String,
  },
});

const emit = defineEmits(["update:modelValue"]);
</script>

<template>
  <div>
    <ul :class="$style.tab_list" role="tablist">
      <li
        v-for="tab of tabs"
        :key="tab"
        role="presentation"
      >
        <button
          type="button"
          :class="[
            $style.tab_button,
            tab === props.modelValue && $style.active,
          ]"
          role="tab"
          :id="`tab-${tab}`"
          :aria-selected="tab === props.modelValue"
          @click="emit('update:modelValue', tab)"
        >
          {{ tab }}
        </button>
      </li>
    </ul>
  </div>
</template>
<style module>
.tab_list {
  list-style: none;
  display: flex;
  align-items: center;
  gap: 1rem;
  border-bottom: 1px solid #ccc;
  padding: 0;
}

.tab_button {
  background: none;
  border: none;
  padding: 0.5rem 1rem;
  cursor: pointer;
  color: #007bff;
}

.active {
  border-bottom: 2px solid #007bff;
  background-color: green;
  color: white;
}
</style>

Le Tabs boucles de composant à travers le tabs Array fourni via des accessoires et rend un bouton pour chaque onglet. Chaque fois qu’un onglet est actif, le active le style est appliqué et le aria-selected attribuer les modifications à "true".

Maintenant, nous pouvons mettre à jour le App.vue composant, rendre le Tabs Composant, et voyez à quoi il ressemble dans le navigateur.

src / app.vue

<script setup>
import Tabs from "./components/Tabs.vue";
const tabs = ["Home", "Profile", "About", "Settings"];
const activeTab = defineModel("activeTab");
</script>

<template>
  <div>
    <Tabs :tabs="tabs" v-model="activeTab" />
  </div>
</template>

Vous devriez voir dans le navigateur quatre onglets pour la maison, le profil, les paramètres et les paramètres.

Onglets

Chaque fois qu’un onglet est cliqué, ses styles doivent changer pour refléter cela.

Onglet Active

Maintenant que nous avons un composant de travail, écrivons des tests unitaires pour vérifier sa fonctionnalité.

Test unité de la composante des onglets avec la plus

Le Tabs La composante est assez simple dans sa fonctionnalité, mais il y a quelques choses que nous pouvons tester pour vérifier que cela fonctionne comme prévu:

  1. Le composant rend le nombre correct d’onglets, comme prévu via des accessoires.
  2. Un onglet correct est défini comme actif en fonction de la modelValue soutenir.
  3. Le composant émet un événement lorsqu’un onglet est cliqué et met à jour l’onglet actif en conséquence chaque fois que le modelValue changements d’hélice.
  4. Aucun boutons n’est rendu si le tabs Prop ne contient aucun élément.

En écrivant des tests pour les scénarios susmentionnés, nous couvrirons comment:

  • MONTANT ET RENDRE VUE COMPOSANTS
  • Interroger les éléments et vérifier leur contenu et leurs attributs
  • Incendier, intercepter et vérifier les événements
  • Mettre à jour les accessoires programmatiques

Commençons par créer un nouveau fichier appelé Tabs.spec.js dans le src / composants Répertoire et rédaction du premier test.

src / composants / tabs.spec.js

import { mount } from "@vue/test-utils";
import { describe, it, expect } from "vitest";
import Tabs from "./Tabs.vue";

const tabs = ["Home", "Profile", "About", "Settings"];

describe("Tabs.vue", () => {
  it("renders correct number of tabs", () => {
    const wrapper = mount(Tabs, {
      props: {
        tabs,
      },
    });

    const buttons = wrapper.findAll("button");

    expect(buttons).toHaveLength(4);
    for (const [index, tab] of Object.entries(tabs)) {
      expect(buttons[index].text()).toBe(tab);
    }
  });
});

Le describe La fonction collecte et regroupe tous les tests définis à l’intérieur, tandis que it sépare les tests. Notre premier test vérifie si le Tabs Le composant rend le nombre correct d’onglets. Comme je l’ai mentionné précédemment, Varest ne sait pas comment gérer directement les composants Vue, c’est donc là que mount de @vue/test-utils La bibliothèque entre en jeu. Le Tabs le composant reçoit le tabs tableau comme un accessoire avec quatre éléments –Home, Profile, About et Settings. Une fois le composant monté, nous trouvons tous les boutons et vérifions que leur contenu texte correspond aux éléments du tabs tableau.

Premier test passé

Maintenant que nous avons le premier test de passage, nous pouvons en ajouter quelques autres. Vérifions si le composant émet un événement de mise à jour lorsqu’un onglet est cliqué et s’il met à jour l’onglet actif en conséquence.

src / composants / tabs.spec.js


describe("Tabs.vue", () => {
  
 
  it("emits update:modelValue on tab click", async () => {
    const wrapper = mount(Tabs, {
      props: {
        tabs: tabs,
        modelValue: tabs[0],
      },
    });
    const buttons = wrapper.findAll("button");
    expect(buttons[0].attributes("aria-selected")).toBe("true");
    expect(buttons[1].attributes("aria-selected")).toBe("false");
    await buttons[1].trigger("click");

    expect(wrapper.emitted("update:modelValue")).toBeTruthy();
    expect(wrapper.emitted("update:modelValue")[0]).toEqual([tabs[1]]);

    await wrapper.setProps({
      modelValue: tabs[1],
    });

    expect(buttons[1].attributes("aria-selected")).toBe("true");
  });
})

Dans le nouveau test, nous définissons le premier onglet comme actif en passant le "Home" texte au modelValue soutenir. Une fois le composant monté, nous vérifions qu’il est actif en vérifiant l’état du aria-selected attribut.

Nous allons tester si l’onglet actif changera en cliquant dans le premier onglet le deuxième, nous vérifions donc également que le deuxième onglet est à l’état inactif. Ensuite, l’événement de clic est déclenché sur le deuxième onglet en exécutant le trigger('click') Méthode sur le bouton du deuxième onglet. Notez que le trigger méthodes doit être attendu, car sinon le test procédera à l’exécution d’autres lignes de code avant que Vue ne puisse mettre à jour l’état et renvoyer les modifications qui se sont produites à la suite du clic. Cela pourrait entraîner des conditions de course et des résultats de test inattendus.

Après la promesse retournée par le trigger la méthode est résolue, nous vérifions le Tabs composant a émis le update:modelValue événement et vérifiez l’argument qui lui est transmis correspond au texte du deuxième onglet.

Ensuite, nous changeons le modelValue Prop pour correspondre au deuxième onglet. La raison pour laquelle nous le faisons est parce que le Tabs Le composant ici est testé isolément, et l’état d’onglet actif est en fait contrôlé par le composant parent qui le rend.

Dans nos tests, le Tabs Le composant n’a pas de parent et nous sommes responsables de passer les accessoires. C’est pourquoi nous changeons le modelValue accessoire par programme. Similaire au trigger méthode, setProps Renvoie une promesse qui doit être attendue.

Enfin, nous vérifions que le deuxième bouton est maintenant actif en affirmant le aria-selected L’attribut est «vrai».

Voici le code de quelques tests supplémentaires qui vérifient si le Tabs Le composant gère correctement les attributs et les valeurs vides.


describe("Tabs.vue", () => {
  
  
  it("sets correct role and id attributes", () => {
    const wrapper = mount(Tabs, {
      props: {
        tabs,
      },
    });
    const button = wrapper.find("button");
    expect(button.attributes("role")).toBe("tab");
    expect(button.attributes("id")).toBe(`tab-${tabs[0]}`);
  });

  it("handles empty tabs array", () => {
    const wrapper = mount(Tabs, {
      props: {
        tabs: [],
      },
    });
    const lis = wrapper.findAll("li");
    expect(lis).toHaveLength(0);
  });

  it("does not set aria-selected if modelValue not in tabs", () => {
    const wrapper = mount(Tabs, {
      props: {
        tabs: tabs,
        modelValue: "Features",
      },
    });
    const buttons = wrapper.findAll("button");
    buttons.forEach(button => {
      expect(button.attributes("aria-selected")).toBe("false");
    });
  });

  it("handles missing modelValue", () => {
    const wrapper = mount(Tabs, {
      props: {
        tabs: tabs,
      },
    });
    const buttons = wrapper.findAll("button");
    buttons.forEach(button => {
      expect(button.attributes("aria-selected")).toBe("false");
    });
  });
})

Conclusion

Dans cet article, nous avons exploré les éléments essentiels du test des applications VUe utilisant Virest et @ vue / test-utils. En configurant un environnement de test avec des tests unitaires VITE et fabrication pour un composant d’onglets simples, nous avons démontré comment vérifier le comportement des composants, gérer les accessoires, gérer les événements et vérifier la fiabilité dans diverses conditions.

Les tests sont une pierre angulaire de la construction d’applications Vue robustes et fiables; Il attrape tôt les problèmes potentiels et renforce la confiance dans votre code. Pour approfondir vos compétences de test, envisagez d’expérimenter des scénarios plus avancés, tels que les composants de test avec des créneaux, la gestion des opérations asynchrones ou l’intégration à des solutions de gestion de l’État comme PINIA.




Source link