unit-test-vue-pinia

Par github · awesome-copilot

Rédigez et révisez des tests unitaires pour des bases de code Vue 3 + TypeScript + Vitest + Pinia. À utiliser lors de la création ou de la mise à jour de tests pour les composants, les composables et les stores ; pour mocker Pinia avec `createTestingPinia` ; pour appliquer les patterns de Vue Test Utils ; et pour privilégier les assertions boîte noire plutôt que les détails d'implémentation.

npx skills add https://github.com/github/awesome-copilot --skill unit-test-vue-pinia

unit-test-vue-pinia

Utilise ce skill pour créer ou examiner des tests unitaires pour les composants Vue, les composables et les stores Pinia. Garde les tests petits, déterministes et orientés comportement.

Workflow

  1. Identifie d'abord la limite comportementale : comportement UI du composant, comportement du composable, ou comportement du store.
  2. Choisis le style de test le plus étroit qui peut prouver ce comportement.
  3. Configure Pinia avec l'option la moins puissante qui couvre toujours le scénario.
  4. Guide le test à travers des entrées publiques comme les props, les mises à jour de formulaire, les clics de bouton, les événements enfant émis et les APIs de store.
  5. Affirme les sorties et effets secondaires observables avant de considérer toute assertion au niveau de l'instance.
  6. Retourne ou examine les tests avec des noms clairs orientés comportement et note les lacunes de couverture restantes.

Core Rules

  • Teste un comportement par test.
  • Affirme d'abord le comportement observable entrée/sortie (texte rendu, événements émis, appels de callback, changements d'état du store).
  • Évite les assertions couplées à l'implémentation.
  • Accède à wrapper.vm uniquement dans les cas exceptionnels quand il n'existe aucune assertion raisonnable au niveau DOM, prop, emit ou store.
  • Préfère la configuration explicite dans beforeEach() et réinitialise les mocks à chaque test.
  • Utilise le matériel de référence enregistré dans references/pinia-patterns.md comme source locale de vérité pour les setups de test Pinia standard.

Pinia Testing Approach

Utilise references/pinia-patterns.md en premier, puis replie-toi sur le cookbook de test Pinia quand les exemples enregistrés ne couvrent pas le cas.

Motif par défaut pour les tests de composant

Utilise createTestingPinia comme plugin global lors du montage. Préfère createSpy: vi.fn comme défaut pour la cohérence et les assertions d'espion d'action plus faciles.

const wrapper = mount(ComponentUnderTest, {
    global: {
        plugins: [
            createTestingPinia({
                createSpy: vi.fn,
            }),
        ],
    },
});

Par défaut, les actions sont stubifiées et espionnées. Utilise stubActions: true (défaut) quand le test doit seulement vérifier si une action a été appelée (ou non appelée).

Setups Pinia minimaux acceptés

Les suivants sont aussi valides et ne doivent pas être signalés comme incorrects :

  • createTestingPinia({}) quand le test n'affirme pas le comportement d'espion d'action Pinia.
  • createTestingPinia({ initialState: ... }) ou createTestingPinia({ stubActions: ... }) sans createSpy, quand le test a besoin seulement de comportement d'amorçage d'état ou de stubification d'action et n'inspecte pas les espions générés.
  • setActivePinia(createTestingPinia(...)) dans les tests focalisés sur store/composable (sans monter un composant) quand le mock/amorçage de stores dépendants est nécessaire.

Utilise createSpy: vi.fn quand les assertions d'espion d'action font partie de l'intention du test.

Exécute les actions réelles seulement quand nécessaire

Utilise stubActions: false seulement quand le test doit valider le comportement et les effets secondaires réels de l'action. Ne l'active pas par défaut pour les simples assertions "was called".

const wrapper = mount(ComponentUnderTest, {
    global: {
        plugins: [
            createTestingPinia({
                createSpy: vi.fn,
                stubActions: false,
            }),
        ],
    },
});

Amorce l'état du store avec initialState

const wrapper = mount(ComponentUnderTest, {
    global: {
        plugins: [
            createTestingPinia({
                createSpy: vi.fn,
                initialState: {
                    counter: { n: 20 },
                    user: { name: "Leia Organa" },
                },
            }),
        ],
    },
});

Ajoute les plugins Pinia via createTestingPinia

const wrapper = mount(ComponentUnderTest, {
    global: {
        plugins: [
            createTestingPinia({
                createSpy: vi.fn,
                plugins: [myPiniaPlugin],
            }),
        ],
    },
});

Motif d'override getter pour les cas limites

const pinia = createTestingPinia({ createSpy: vi.fn });
const store = useCounterStore(pinia);

store.double = 999;
// @ts-expect-error test-only reset of overridden getter
store.double = undefined;

Tests unitaires purs de store

Préfère les tests purs de store avec createPinia() quand l'objectif est de valider les transitions d'état du store et le comportement d'action sans rendu de composant. Utilise createTestingPinia() seulement quand tu as besoin de stores dépendants stubifiés, de test doubles amorcés, ou d'espions d'action.

beforeEach(() => {
    setActivePinia(createPinia());
});

it("increments", () => {
    const counter = useCounterStore();
    counter.increment();
    expect(counter.n).toBe(1);
});

Vue Test Utils Approach

Suis les directives de Vue Test Utils : https://test-utils.vuejs.org/guide/

  • Monte shallow par défaut pour les tests unitaires focalisés.
  • Monte les arbres de composants complets seulement quand le comportement d'intégration est le sujet.
  • Guide le comportement à travers les props, les interactions de type utilisateur et les événements émis.
  • Préfère findComponent(...).vm.$emit(...) pour les événements enfant stub au lieu de toucher les internals du parent.
  • Utilise nextTick seulement quand les mises à jour sont asynchrones.
  • Affirme les événements émis et les payloads avec wrapper.emitted(...).
  • Accède à wrapper.vm seulement quand aucune assertion DOM, assertion d'événement émis, assertion prop ou assertion au niveau du store ne peut exprimer le comportement. Traite cela comme une exception et garde l'assertion étroitement ciblée.

Key Testing Snippets

Émettre et affirmer le payload :

await wrapper.find("button").trigger("click");
expect(wrapper.emitted("submit")?.[0]?.[0]).toBe("Mango Mission");

Mettre à jour l'input et affirmer la sortie :

await wrapper.find("input").setValue("Agent Violet");
await wrapper.find("form").trigger("submit");
expect(wrapper.emitted("save")?.[0]?.[0]).toBe("Agent Violet");

Test Writing Workflow

  1. Identifie la limite comportementale à tester.
  2. Construis des données de fixture minimales (seulement les champs nécessaires à ce comportement).
  3. Configure Pinia et les test doubles nécessaires.
  4. Déclenche le comportement à travers les entrées publiques.
  5. Affirme les sorties publiques et les effets secondaires.
  6. Refactorise les noms de test pour décrire le comportement, pas l'implémentation.

Constraints and Safety

  • Ne teste pas les détails privés/internes de l'implémentation.
  • N'abuse pas des snapshots pour le comportement UI dynamique.
  • N'affirme pas chaque champ dans les grands objets si un seul comportement importe.
  • Garde les données fausses déterministes ; évite les valeurs aléatoires.
  • Ne réclame pas qu'un setup Pinia est faux quand c'est l'un des setups minimaux acceptés ci-dessus.
  • Ne réécris pas les tests qui fonctionnent vers un montage plus profond ou des actions réelles à moins que le comportement testé ne nécessite cette surface supplémentaire.
  • Signale explicitement la couverture de test manquante, les sélecteurs fragiles et les assertions couplées à l'implémentation lors de l'examen.

Output Contract

  • Pour create ou update, retourne le code de test fini plus une courte note décrivant la stratégie Pinia sélectionnée.
  • Pour review, retourne d'abord les découvertes concrètes, puis la couverture manquante ou les risques de fragilité.
  • Quand le choix le plus sûr est ambigu, énonce l'hypothèse qui a guidé la configuration de test choisie.

References

Skills similaires