# Vincular pruebas de Vitest con casos

> Cómo vincula @probara/vitest-reporter cada prueba de Vitest con un caso de prueba de Probara — IDs de caso en los títulos, probara.id(), claves de automatización, filas de test.each y los casos que crea.

Cada resultado va a un caso de prueba de Probara. Una prueba que nombra su caso queda vinculada a él;
una prueba que no nombra ninguno se asocia por su clave de automatización, y su caso se crea la
primera vez que se reporta. Vincula las pruebas cuando sus casos ya existen en Probara (escritos a
mano o importados).

## Dos formas de nombrar un caso

| Forma                                                 | Ejemplo                                           | Cuándo                                                   |
| ----------------------------------------------------- | ------------------------------------------------- | -------------------------------------------------------- |
| Un ID de caso en el título de una prueba o `describe` | `test('SHOP-12 pays with a card', ...)`           | La forma habitual; funciona también con pruebas omitidas |
| `probara.id()` en la prueba                           | `probara.id('SHOP-14')`, `probara.id(['A', 'B'])` | IDs que solo se conocen mientras corre la prueba         |

```ts
// tests/checkout.test.ts
import { probara } from '@probara/vitest-reporter';
import { describe, test } from 'vitest';

describe('checkout', () => {
  test('SHOP-12 pays with a card', () => {});

  describe('SHOP-13 vouchers', () => {
    test('pays with a voucher', () => {});
  });

  test('pays with a gift card', () => {
    probara.id('SHOP-14');
  });

  test('shows the total', () => {
    // No case named: matched by its key, created the first time.
  });
});
```

Probara recibe un resultado por prueba, cada uno con su caso, y la clave que tendría sin los IDs:

```json
[
  {
    "caseDisplayId": "SHOP-12",
    "automationKey": "tests/checkout.test.ts > checkout > pays with a card"
  },
  {
    "caseDisplayId": "SHOP-13",
    "automationKey": "tests/checkout.test.ts > checkout > vouchers > pays with a voucher"
  },
  {
    "caseDisplayId": "SHOP-14",
    "automationKey": "tests/checkout.test.ts > checkout > pays with a gift card"
  },
  { "automationKey": "tests/checkout.test.ts > checkout > shows the total" }
]
```

- **Los IDs del título** son los IDs del proyecto al que se reporta (y de los proyectos que lista
  [`projects`](https://docs.probara.net/es/developers/ci-integrations/vitest/sharding/#varios-proyectos-de-probara)) en el
  título de un `describe` o de una prueba, como `SHOP-12` o `SHOP_12`, en cualquier parte, también
  entre corchetes (`[SHOP-12]`) o después de `@`. Un ID en un `describe` vincula todas las pruebas
  que contiene. Se quitan de la clave, así que añadir uno nunca cambia una clave. Un ID de un
  proyecto que el reporter no conoce queda en el título y en la clave, como texto.
- **`probara.id()`** recibe un ID o una lista, y vincula el intento en curso. Una prueba que se
  omite antes de ejecutarse (`test.skip`, un `describe` omitido, `test.todo`) nunca ejecuta su
  cuerpo: vincúlala con un ID en el título. La
  [selección de pruebas](https://docs.probara.net/es/developers/ci-integrations/vitest/run-selection/) tampoco ve
  `probara.id()`: decide antes de que la prueba se ejecute.

Los IDs son el ID visible del caso: el ID del Proyecto, un guion y el número que muestra Probara
(`SHOP-12`). Un ID que Probara no conoce no se registra: el registro lo cuenta como unmatched
([solución de problemas](https://docs.probara.net/es/developers/ci-integrations/vitest/troubleshooting/#resultados-no-registrados-unmatched)).

## Varios casos

Cuentan todas las fuentes: primero `probara.id()` (en el orden de las llamadas) y después los IDs
de los títulos, cada ID una vez. Una prueba vinculada a varios casos se envía una vez por caso, con
la misma clave, y sus archivos se suben a cada resultado:

```ts
// tests/login.test.ts
import { probara } from '@probara/vitest-reporter';
import { test } from 'vitest';

test('SHOP-21 logs in', () => {
  probara.id('SHOP-20');
});
```

```json
[
  { "caseDisplayId": "SHOP-20", "automationKey": "tests/login.test.ts > logs in" },
  { "caseDisplayId": "SHOP-21", "automationKey": "tests/login.test.ts > logs in" }
]
```

## Claves de automatización

Una prueba que no nombra ningún caso se asocia por su clave de automatización: la misma clave
encuentra el mismo caso en cada ejecución, y una clave nueva crea un caso nuevo. La clave es la que
[`probara import junit`](#las-mismas-claves-que-probara-import-junit) da a la prueba en la salida
JUnit de Vitest:

| Parte   | De dónde sale                                                                                                                 | Ejemplo                  |
| ------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| Archivo | El archivo de prueba, relativo a la raíz de Vitest (`root`, por defecto el directorio en el que se ejecuta `vitest`)          | `tests/checkout.test.ts` |
| Nombre  | Los títulos de los `describe` y el de la prueba, cada uno un segmento, como los nombra la salida JUnit de Vitest; sin los IDs | `checkout > pays`        |

Así, `tests/checkout.test.ts > checkout > pays` es la clave de `test('pays')` dentro de
`describe('checkout')`. El algoritmo de la clave es la
[clave de automatización v1](https://github.com/cynch-me/probara-sdk/blob/main/packages/core/README.md#the-automation-key-v1)
de `@probara/core`, congelada y compartida por todas las herramientas de Probara.

| Cambia la clave, así que crea un caso nuevo                                 | No cambia la clave                                                                |
| --------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| Renombrar una prueba, un `describe` o un archivo                            | Añadir o quitar un ID de caso                                                     |
| Mover un archivo                                                            | `probara.title()` y `probara.suite()` (solo nombran un caso creado)               |
| Ejecutar `vitest` con otra raíz (define `rootDir` para conservar las rutas) | `probara.parameters()` y las etiquetas de Vitest                                  |
| Cambiar `keyIncludesFile`                                                   | El proyecto de Vitest que ejecuta la prueba, un reintento o una repetición, el CI |

### Sin el archivo

`keyIncludesFile: false` (`PROBARA_KEY_INCLUDES_FILE=false`) omite el archivo en todas las claves:
`checkout > pays`. Úsalo cuando tus casos ya tengan claves sin el archivo, creadas a mano o por otra
herramienta, para que cada prueba conserve su caso. Una prueba recibe entonces la misma clave que
otra con los mismos bloques `describe` y el mismo título en otro archivo.

```ts
reporters: ['default', ['@probara/vitest-reporter', { keyIncludesFile: false }]],
```

```json
[
  { "automationKey": "cart > adds an item", "caseDisplayId": "SHOP-12" },
  { "automationKey": "cart > removes an item" },
  { "automationKey": "login > logs in with a valid password" }
]
```

Cambiar `keyIncludesFile` cambia todas las claves: las pruebas que no nombran ningún caso en sus
títulos crean entonces casos nuevos. Un caso que crea el informe va a una suite con el nombre del
archivo de prueba o, con `keyIncludesFile: false`, con el de su `describe` más externo, si lo tiene.
La salida JUnit de Vitest siempre nombra el archivo, así que las claves de `probara import junit`
sobre ella son las del valor por defecto, `keyIncludesFile: true`.

### Nombres tal como los escribe Vitest

El nombre es el que da a la prueba la salida JUnit de Vitest, así que una clave nunca depende de
cuál de las dos herramientas reportó la prueba:

- **Las filas de `test.each` y `test.for`** son pruebas propias, con sus valores en el nombre
  (`%s`, `%i`, `$name`): cada fila es un caso. Las filas que reciben el mismo nombre (sin marcador
  en el título) comparten una clave y se registran en el mismo caso. Vitest 5 escribe un valor de
  tipo objeto (`%o`, `$user`) de forma distinta a Vitest 3 y 4, así que las claves de esas filas
  cambian al actualizar a esa versión
  ([de Vitest 4 a 5](https://docs.probara.net/es/developers/ci-integrations/vitest/migrating/#de-vitest-4-a-5)).
- **`>`** (`>` con un espacio a cada lado) en un título lo divide en dos segmentos, como lo leen la
  salida JUnit de Vitest y la importación: la clave es la misma cadena en ambos casos.
- **Los proyectos de Vitest** no añaden nada a la clave, igual que con la importación JUnit: un
  archivo de prueba que ejecutan dos proyectos se reporta una vez por proyecto, con la misma clave,
  y cada resultado con su parámetro `project`
  ([proyectos de Vitest](https://docs.probara.net/es/developers/ci-integrations/vitest/sharding/#proyectos-de-vitest)).

```ts
// tests/prices.test.ts
import { describe, test } from 'vitest';

describe('prices', () => {
  test.each([
    ['EUR', '€'],
    ['USD', '$'],
  ])('shows %s as %s', () => {});

  test('discount > applies to the total', () => {});
});
```

```json
[
  { "automationKey": "tests/prices.test.ts > prices > shows EUR as €" },
  { "automationKey": "tests/prices.test.ts > prices > shows USD as $" },
  { "automationKey": "tests/prices.test.ts > prices > discount > applies to the total" }
]
```

## Casos que faltan

Una prueba cuya clave no coincide con ningún caso crea uno, con el nombre de la prueba (sin los
IDs), bajo `suiteUlid` (la raíz del proyecto por defecto), en una suite con el nombre de su archivo
de prueba; con `keyIncludesFile: false`, con el de su `describe` más externo, si lo tiene. Con
`createMissingCases: false` (`PROBARA_CREATE_MISSING_CASES=false`), una prueba así no registra nada
y se registra como unmatched: solo los casos existentes reciben resultados.
[`probara.title()` y `probara.suite()`](https://docs.probara.net/es/developers/ci-integrations/vitest/metadata/#título-y-suite)
eligen el nombre y la suite de un caso creado.

## Las mismas claves que `probara import junit`

Un proyecto que enviaba la salida JUnit de Vitest con `probara import junit` puede pasar al reporter
y conservar todos sus casos: el reporter construye las mismas claves y lee los mismos IDs del
título, en Vitest 3, 4 y 5.

| Salida JUnit de Vitest                                 | Ajuste del reporter                       |
| ------------------------------------------------------ | ----------------------------------------- |
| `--reporter=junit`, con o sin `addFileAttribute: true` | Nada: `keyIncludesFile` está activado     |
| Escrita con otro `ancestorSeparator` (Vitest 5)        | Claves distintas: vincula por IDs de caso |

Sigue ejecutando `vitest` con la misma raíz que antes: el archivo de una clave es relativo a ella.
El reporter envía más que la importación: cada intento de una prueba reintentada, los pasos, los
archivos, los enlaces y los parámetros de los helpers `probara.*`, y los vínculos de
`probara.id()`. La
[guía de migración desde JUnit](https://docs.probara.net/es/developers/ci-integrations/vitest/migrating/#desde-la-importación-junit)
tiene los pasos, cómo comparar las claves antes de cambiar y qué registra distinto el reporter; el
lado de la importación está en
[Vitest JUnit](https://github.com/cynch-me/probara-sdk/blob/main/packages/cli/docs/junit.md#vitest).

Relacionado: [Metadatos y enlaces](https://docs.probara.net/es/developers/ci-integrations/vitest/metadata/) ·
[Sharding y proyectos](https://docs.probara.net/es/developers/ci-integrations/vitest/sharding/) ·
[Actualizar el reporter](https://docs.probara.net/es/developers/ci-integrations/vitest/migrating/#actualizar-el-reporter) ·
Fuente:
[linking.md](https://github.com/cynch-me/probara-sdk/blob/main/packages/vitest-reporter/docs/linking.md)
