Metadatos y enlaces de pruebas de Vitest
probara da al reporter más información sobre una prueba, desde el cuerpo de la prueba, sus hooks
beforeEach y afterEach, o onTestFinished. Impórtalo del paquete del reporter:
import { probara } from '@probara/vitest-reporter';import { test } from 'vitest';
test('pays with a card', () => { probara.title('Pays with a saved card').suite(['Payments', 'Cards']).tags('smoke');});No hay nada que configurar: el reporter añade lo que necesitan los helpers a cada proyecto de Vitest, en los pools threads y forks y en modo navegador.
| Helper | Qué hace | Llamadas repetidas |
|---|---|---|
id(id | ids) | Vincula casos existentes (vincular) | Se suman |
title(text) | Título del caso que crea el informe | Gana la última |
suite(title | titles) | Ruta de suites del caso que crea el informe | Gana la última |
comment(text) | Un comentario, al principio de las notas del resultado, antes del error | Gana la última |
ignore() | Deja fuera este intento: no se reporta | — |
tags(...names) | Etiquetas del caso que crea el informe | Se suman, cada una una vez |
fields(record) | Campos del caso que crea el informe: campos del sistema, campos personalizados, description | Se combinan por nombre |
parameters(record) | Parámetros del resultado, que se muestran con él | Se combinan por nombre |
link(url, name?), issue(id) | Enlaces del resultado (enlaces e incidencias) | Se suman |
attach({ name, path | body, ... }) | Adjunta un archivo; espéralo con await (adjuntos) | Cada una adjunta |
step(title, body?, options?) | Un paso del resultado, y del caso nuevo (pasos) | Cada una es un paso |
Los helpers que no devuelven otra cosa devuelven probara, así que las llamadas se encadenan. Cada
una se aplica solo al intento en curso: un reintento empieza vacío. Los nombres, los argumentos y
las reglas son los del reporter de Jest;
diferencias con la API de Jest recoge lo que cambia Vitest.
Solo casos creados
Sección titulada «Solo casos creados»title, suite, tags, fields y los pasos del caso describen el caso que crea un informe,
la primera vez que se reporta una prueba. Un caso existente nunca cambia: Probara conserva lo que
escribieron las personas. La clave de automatización tampoco cambia nunca
(claves), así que un
título nuevo sigue encontrando el mismo caso.
import { probara } from '@probara/vitest-reporter';import { test } from 'vitest';
test('pays', () => { probara .title('Pays with a saved card') .suite(['Payments', 'Cards']) .tags('smoke', 'payments') .fields({ description: 'A returning customer pays with the card saved in their profile.', severity: 'critical', priority: 'high', 'Risk area': 'Checkout', });});[ { "automationKey": "tests/payments.test.ts > pays", "title": "Pays with a saved card", "suitePath": ["Payments", "Cards"], "case": { "description": "A returning customer pays with the card saved in their profile.", "tags": ["smoke", "payments"], "fields": { "severity": "critical", "priority": "high", "Risk area": "Checkout" } } }]fields() recibe nombres y valores (los números y los booleanos se convierten en cadenas):
| Nombre | Qué define |
|---|---|
description | La descripción del caso |
severity, priority, type, layer, behavior, status, is_flaky | Los campos del sistema, por el nombre de una opción (high) |
preconditions, postconditions | Los campos de texto del sistema |
Cualquier otro nombre, como 'Risk area' | El campo personalizado con ese nombre |
Probara resuelve los nombres y las opciones al crear el caso. Un campo o una opción que no conoce se omite y se registra como advertencia; el resultado se registra igualmente. Un campo con un valor vacío se omite sin aviso.
Título y suite
Sección titulada «Título y suite»El título de un caso creado es el título de la prueba (sin los IDs de caso), salvo que title()
indique otro. Su suite es el archivo de prueba (tests/payments.test.ts) o, con
keyIncludesFile: false, el describe más externo, salvo que suite() indique una:
suite('Payments') o suite(['Payments', 'Cards']) para suites anidadas, que se crean según haga
falta bajo suiteUlid.
Etiquetas de Vitest
Sección titulada «Etiquetas de Vitest»Las etiquetas de una prueba (Vitest 4.1 y posteriores) se suman a las etiquetas del caso que crea el
informe, después de las de probara.tags(), cada una una vez. Vitest rechaza una etiqueta que su
configuración no declara, así que declara cada una en test.tags:
// vitest.config.mtsimport { defineConfig } from 'vitest/config';
export default defineConfig({ test: { tags: [{ name: 'smoke' }], reporters: ['default', '@probara/vitest-reporter'], },});import { probara } from '@probara/vitest-reporter';import { test } from 'vitest';
test('finds a product', { tags: ['smoke'] }, () => { probara.tags('search');});[ { "automationKey": "tests/search.test.ts > finds a product", "case": { "tags": ["search", "smoke"] } }]Como las etiquetas de probara.tags(), solo van a un caso creado: nunca a un resultado, nunca a la
clave de automatización, así que añadir una etiqueta a una prueba nunca la mueve a otro caso.
Comentario
Sección titulada «Comentario»comment() escribe una línea al principio de las notas del resultado, antes del error y su traza:
import { probara } from '@probara/vitest-reporter';import { test } from 'vitest';
test('searches the catalog', () => { probara.comment('Ran against the staging catalog');});[ { "automationKey": "tests/search.test.ts > searches the catalog", "notes": "Ran against the staging catalog" }]Cuando el intento falla, sus errores siguen al comentario en las mismas notas, sin los colores de la
terminal: el comentario nunca oculta un error. Los mensajes del propio context.annotate() de
Vitest no se envían como notas: comment() es la forma de escribir una.
Parámetros
Sección titulada «Parámetros»parameters() registra los valores con los que se ejecutó un intento, que se muestran con su
resultado, como el usuario o el conjunto de datos de una prueba guiada por datos. Nunca forman
parte de la clave: la prueba es un solo caso sean cuales sean sus parámetros. Cuando el caso declara un parámetro con el mismo nombre, el resultado se registra en el caso de ejecución con esos valores. Un parámetro que el caso no declara se queda en el resultado solo para mostrarlo. El proyecto de Vitest, attempt y repeat son contexto: se muestran en el resultado y nunca se convierten en un parámetro de un caso que un reporte crea.
import { probara } from '@probara/vitest-reporter';import { test } from 'vitest';
test.each(['admin', 'viewer'])('opens the dashboard as %s', (role) => { probara.parameters({ role, seats: 5 });});[ { "automationKey": "tests/users.test.ts > opens the dashboard as admin", "parameters": { "role": "admin", "seats": "5" } }, { "automationKey": "tests/users.test.ts > opens the dashboard as viewer", "parameters": { "role": "viewer", "seats": "5" } }]- Las filas de
test.eachytest.forson pruebas propias, con la clave del título que Vitest les da: mantén un marcador en el título (%s,$role), para que cada fila sea un caso. Vitest no guarda los valores de una fila en ningún otro sitio, así queparameters()es la forma de enviarlos. describe.each: llama a los helpers en cada prueba o en subeforeEach; una llamada en el cuerpo deldescribese ejecuta mientras no corre ninguna prueba.- Dos pruebas con el mismo nombre completo comparten una clave, es decir, un caso: cada resultado conserva lo que dijeron sus propios helpers.
- Los parámetros propios del reporter:
attemptyrepeatdistinguen las ejecuciones de una prueba reintentada o repetida. Son contexto: se muestran en el resultado y nunca se convierten en un parámetro de un caso que un reporte crea. (reintentos y repeticiones), yprojectnombra el proyecto de Vitest de un resultado cuando la configuración tiene más de uno. Unprojecttuyo gana al de Vitest;attemptyrepeatganan a los tuyos.
Ignorar un intento
Sección titulada «Ignorar un intento»ignore() deja fuera el intento en curso: sigue ejecutándose, y Vitest lo reporta, pero Probara no
lo recibe. El recuento del registro dice cuántos se dejaron fuera.
import { probara } from '@probara/vitest-reporter';import { test } from 'vitest';
test('tries the new checkout', () => { probara.ignore();});
test('pays', () => {});$ npx vitest run[probara] Sending 1 result of 1 test (1 passed, 0 failed, 0 skipped, 0 blocked); 1 ignored with probara.ignore()[probara] Recorded 1 result (1 new case, 0 unmatched) in R-1 (closed): https://app.probara.net/projects/SHOP/runs/R-1Enlaces e incidencias
Sección titulada «Enlaces e incidencias»Un resultado puede llevar enlaces, que se muestran con él en Probara: el build que lo ejecutó, la
página que probó, las incidencias de tu gestor a las que se refiere. probara.link() añade un
enlace; probara.issue() nombra una incidencia, que issueUrlTemplate convierte en un enlace.
probara.link()
Sección titulada «probara.link()»probara.link(url, name?) recibe una URL absoluta http o https y un nombre opcional, que se
muestra en lugar de la URL:
import { probara } from '@probara/vitest-reporter';import { test } from 'vitest';
test('searches the catalog', () => { probara .link('https://shop.example.com/search?q=boots', 'Search page') .link('https://ci.example.com/builds/1042');});[ { "automationKey": "tests/search.test.ts > searches the catalog", "links": [ { "url": "https://shop.example.com/search?q=boots", "name": "Search page" }, { "url": "https://ci.example.com/builds/1042" } ] }]probara.issue() e issueUrlTemplate
Sección titulada «probara.issue() e issueUrlTemplate»probara.issue(id) nombra una incidencia de tu gestor por su ID. Con issueUrlTemplate
(PROBARA_ISSUE_URL_TEMPLATE), una URL con %s donde va el ID, se convierte en un enlace del
resultado, con el ID como nombre:
reporters: [ 'default', ['@probara/vitest-reporter', { issueUrlTemplate: 'https://jira.example.com/browse/%s' }],],import { probara } from '@probara/vitest-reporter';import { test } from 'vitest';
test('rounds the total', () => { probara.issue('PAY-7').issue('PAY 12');});[ { "automationKey": "tests/checkout.test.ts > rounds the total", "links": [ { "url": "https://jira.example.com/browse/PAY-7", "name": "PAY-7" }, { "url": "https://jira.example.com/browse/PAY%2012", "name": "PAY 12" } ] }]- El ID entra en la plantilla codificado para URL (
PAY 12se convierte enPAY%2012), en lugar del primer%s. - La plantilla es una URL
httpohttpscon%s; cualquier otro valor desactiva el envío con un error que nombraissueUrlTemplate. - Sin plantilla, las incidencias se omiten, y una advertencia lo indica: el resultado se registra sin ellas.
import { probara } from '@probara/vitest-reporter';import { test } from 'vitest';
test('rounds the total', () => { probara.issue('PAY-7');});$ npx vitest run[probara] Dropped the issues of probara.issue(): no issueUrlTemplate turns their ids into links (first seen in the run; repeats are logged at debug)[probara] Sending 1 result of 1 test (1 passed, 0 failed, 0 skipped, 0 blocked)[probara] Recorded 1 result (1 new case, 0 unmatched) in R-1 (closed): https://app.probara.net/projects/SHOP/runs/R-1Reglas de los enlaces
Sección titulada «Reglas de los enlaces»| Regla | Qué pasa |
|---|---|
| Enlaces e incidencias de un intento | Se envían en el orden de las llamadas, todos juntos |
Una URL que no es una URL http/https absoluta | Se omite, con una advertencia |
| Una URL de más de 2048 caracteres | Se omite, con una advertencia |
| Un nombre de más de 255 caracteres | Se recorta a 255 caracteres, con una advertencia |
| Más de 20 enlaces en un resultado | Se envían los 20 primeros, con una advertencia |
| Un reintento | Empieza sin enlaces: cada intento envía los suyos |
Los enlaces pertenecen al resultado, no al caso: un caso existente nunca cambia, y cada resultado conserva los enlaces que añadió su intento. Para vincular el propio caso a una incidencia de Jira, consulta Trazabilidad con Jira.
Dónde llamar a los helpers
Sección titulada «Dónde llamar a los helpers»| Dónde | Qué pasa |
|---|---|
El cuerpo de la prueba, beforeEach, afterEach, onTestFinished | Se aplica al intento en curso |
| Una función auxiliar o un módulo que llama la prueba | Lo mismo: los helpers encuentran por sí solos la prueba en curso |
Una prueba test.concurrent | Se aplica a esa prueba |
El ámbito del módulo, el cuerpo de un describe, beforeAll, afterAll | Se ignora, con una advertencia: ahí no corre una sola prueba |
Un helper nunca lanza errores dentro de la prueba. Una llamada mientras no corre ninguna prueba es una advertencia por helper y archivo de prueba, que el archivo de prueba imprime en la salida de Vitest; un argumento incorrecto (aquí, una etiqueta vacía) es una advertencia del registro del reporter para la ejecución. En ambos casos, lo incorrecto se ignora y la prueba continúa:
import { probara } from '@probara/vitest-reporter';import { beforeAll, test } from 'vitest';
beforeAll(() => { probara.tags('orders');});
test('lists the orders', () => { probara.tags('orders', '');});$ npx vitest run[probara] probara.tags() only works while a test runs (in a test, or a beforeEach or afterEach hook)[probara] probara.tags() ignores blank tags (first seen in the run; repeats are logged at debug)[probara] Sending 1 result of 1 test (1 passed, 0 failed, 0 skipped, 0 blocked)[probara] Recorded 1 result (1 new case, 0 unmatched) in R-1 (closed): https://app.probara.net/projects/SHOP/runs/R-1Diferencias con la API de Jest
Sección titulada «Diferencias con la API de Jest»probara.* tiene los nombres, los argumentos, las reglas de combinación y los mensajes del
reporter de Jest. Vitest cambia lo siguiente:
| En el reporter de Vitest | Por qué |
|---|---|
No va nada en la configuración aparte del reporter: ni setupFilesAfterEnv, ni siquiera para captureOutput o runCasesOnly | Vitest permite que un reporter añada su archivo de setup y su runner a cada proyecto antes de la ejecución |
Espera probara.attach() con await. En Node el archivo se copia en la llamada, como en Jest; en modo navegador la copia termina después, y una que termina cuando su prueba ya acabó no se adjunta, con una advertencia que dice Await probara.attach() before the test ends | En un navegador, el lado Node de Vitest lee el archivo después de que la llamada vuelve |
Una llamada de test.concurrent va a su propia prueba a través del runner del reporter. Donde ese runner no puede ejecutarse (modo navegador, un runner propio que Node no puede importar, como un archivo .jsx), se descarta con una advertencia | La prueba en curso del propio Vitest es una por worker, así que puede nombrar la prueba concurrente equivocada: una llamada se descarta antes que registrarse en otra prueba |
Una llamada fuera de una prueba avisa una vez por helper y archivo de prueba, en la salida del archivo de prueba (stderr | tests/orders.test.ts), no en el registro del reporter | La llamada se ejecuta en un worker de Vitest, que no puede escribir en el registro del reporter del proceso principal |
Un argumento incorrecto en una prueba avisa una vez por ejecución, (first seen in the run; ...) | La advertencia viaja con el resultado de la prueba, y el reporter registra cada una una sola vez |
| Las etiquetas de Vitest (4.1 y posteriores) se suman a las etiquetas de un caso creado | Jest no tiene etiquetas de prueba |
Una fila de test.each o test.for toma la clave del título que formatea Vitest, que Vitest 4 y 5 escriben distinto para los valores de tipo objeto | La clave es el nombre que da a la prueba la salida JUnit de Vitest, y ese nombre sale del formato del propio Vitest |
| Dos pruebas con el mismo nombre completo conservan cada una sus propias llamadas a los helpers (el reporter de Jest las deja fuera, con una advertencia) | Vitest guarda las llamadas en los metadatos propios de cada prueba, así que no hay que distinguir dos nombres |
Un shard ejecutado con --reporter=blob solo en la línea de comandos no registra ninguna llamada a los helpers: nombra el reporter junto a él (el reporter va junto a blob) | --reporter sustituye los reporters de la configuración, así que el reporter nunca arranca y no añade ningún archivo de setup |
| Con el envío desactivado, los helpers siguen registrando, y no se envía nada | El reporter añade su archivo de setup sea cual sea la configuración de envío, así que las pruebas se ejecutan igual con y sin token |
En modo navegador los helpers funcionan en el navegador, y probara.attach({ path }) solo copia un archivo que Vite sirve | Un navegador no puede leer un archivo: lo lee el lado Node de Vitest, con las reglas de server.fs de Vite |
Cómo viajan los metadatos
Sección titulada «Cómo viajan los metadatos»Vitest ejecuta las pruebas en workers y el reporter en su proceso principal. Cada llamada
probara.* se escribe en la entrada del intento en curso dentro de los metadatos propios de la
prueba (task.meta.probara), que Vitest envía al reporter con el resultado de la prueba; el
reporter los lee cuando termina la ejecución. probara.attach() copia su archivo en ese momento a
una carpeta dentro del attachmentsDir de Vitest. El blob de Vitest guarda los metadatos de cada
prueba, así que el blob de un shard lleva las llamadas hasta vitest --merge-reports. Sin el
reporter entre los reporters de la ejecución, cada helper no hace nada (y probara.step() sigue
ejecutando su cuerpo), así que las pruebas siguen pasando donde el reporter no está registrado.
Límites conocidos:
task.meta.probaraes del reporter. El código de prueba puede verlo (context.task.meta.probara), pero su forma no es una API, y escribir en él cambia lo que se envía: guarda tus propios metadatos bajo otra clave.- Un
runnerpropio que Node no puede importar (.jsx,.tsx, o.tsen un Node sin eliminación de tipos) se deja tal cual, con una advertencia que lo nombra: sus intentos se siguen registrando, pero las llamadas de sus pruebastest.concurrentse descartan, con una advertencia.
Relacionado: Pasos y adjuntos · Vincular · Migrar desde Qase · Fuente: metadata.md, links.md