Vitest 3.2 está disponível!
2 de junho de 2025
O Vitest 3.2 foca em melhorias no Modo de Navegador e no suporte ao TypeScript. Esta versão também inclui alguns novos métodos úteis, opções de configuração e descontinua a configuração workspace
em favor de projects
.
workspace
está Depreciado
Em um esforço para simplificar a configuração, a equipe decidiu descontinuar o uso do arquivo vitest.workspace
separado e recomendar o uso apenas da opção projects
na configuração raiz. Isso também simplifica a configuração das opções globais (pois você não precisa adivinhar como adicionar relatores quando não tem uma configuração raiz).
Também decidimos depreciar o nome workspace
porque ele entra em conflito com outras ferramentas como o PNPM que fornecem suporte a monorepo através desta opção. O Vitest não executa esses projetos com CWD
separado e os trata mais como subprojetos do Vitest. Isso também nos dá mais espaço para criar uma solução melhor para monorepos sem prejudicar outros.
Esta opção será removida completamente em uma futura versão principal, substituída por projects
. Até então, o Vitest imprimirá um aviso se o recurso workspace
for usado.
import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
// "test.workspace" foi renomeado para "test.projects"
workspace: [
projects: [
{ test: { name: "Unit" } },
{ test: { name: "Integration" } },
],
},
});
API de Anotações
A nova API de anotação permite que você anote qualquer teste com uma mensagem e anexo personalizados. Essas anotações são visíveis nos relatores de UI, HTML, junit, tap e GitHub Actions. O Vitest também imprimirá a anotação relacionada na CLI se o teste falhar.

Fixtures com Escopo
As fixtures test.extend
agora podem especificar a opção scope
: file
ou worker
.
const test = baseTest.extend({
db: [
async ({}, use) => {
// ...configuração
await use(db);
await db.close();
},
{ scope: 'worker' },
],
});
A fixture de arquivo é semelhante ao uso de beforeAll
e afterAll
no nível superior do arquivo, mas não será chamada se a fixture não for utilizada em nenhum teste.
A fixture worker
é iniciada uma vez por worker, mas observe que, por padrão, o Vitest cria um worker para cada teste, então você precisa desabilitar o isolamento para se beneficiar dela.
Cores Personalizadas para Nomes de Projeto
Agora você pode definir uma cor personalizada ao utilizar projects
:
Exemplo de Configuração
export default defineConfig({
test: {
projects: [
{
test: {
name: {
label: 'unit',
color: 'red',
},
},
},
{
test: {
name: {
label: 'browser',
color: 'green',
},
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
},
],
},
})

API de Localizadores de Navegador Personalizados
Os localizadores embutidos podem não ser suficientes para atender às necessidades da sua aplicação. Em vez de recorrer ao CSS e perder a proteção de capacidade de repetição que o Vitest oferece através de sua API de localizadores, agora recomendamos estender os localizadores usando a nova API locators.extend
.
import { locators } from '@vitest/browser/context';
locators.extend({
getByCommentsCount(count: number) {
return `.comments :text("${count} comments")`;
},
});
Retorne uma string de localizador do Playwright para criar um novo localizador. Observe que a string retornada por este método terá o escopo do localizador pai, se houver um.
Agora você pode chamar getByCommentsCount
na page
ou em qualquer outro localizador diretamente:
await expect.element(page.getByCommentsCount(1)).toBeVisible();
await expect
.element(
page.getByRole('article', { name: 'Hello World' }).getByCommentsCount(1)
)
.toBeVisible();
Se este método retornar uma string, o valor de retorno será convertido em um localizador, permitindo que você continue encadeando-o:
page
.getByRole('article', { name: 'Hello World' })
.getByCommentsCount(1)
.getByText('comments');
Este método tem acesso ao contexto do localizador atual, se houver um (se o método for chamado na page
, o contexto se referirá à page
), então você pode encadear todos os métodos do localizador dentro:
import { locators } from '@vitest/browser/context';
import type { Locator } from '@vitest/browser/context';
locators.extend({
getByCommentsCount(this: Locator, count: number) {
return this.getByRole('comment').and(this.getByText(`${count} comments`));
},
});
Ter acesso ao contexto também permite que você chame métodos regulares do localizador para definir um evento de usuário personalizado:
import { locators, page } from '@vitest/browser/context';
import type { Locator } from '@vitest/browser/context';
locators.extend({
clickAndFill(this: Locator, text: string) {
await this.click();
await this.fill(text);
},
});
await page.getByRole('textbox').clickAndFill('Hello World');
Consulte a API locators.extend
para mais informações.
Gerenciamento Explícito de Recursos em vi.spyOn
e vi.fn
Em ambientes que suportam Gerenciamento Explícito de Recursos, você pode usar using
em vez de const
para chamar automaticamente mockRestore
em qualquer função mockada quando o bloco contendo for encerrado. Isso é especialmente útil para métodos espionados:
it('calls console.log', () => {
using spy = vi.spyOn(console, 'log').mockImplementation(() => {})
debug('message')
expect(spy).toHaveBeenCalled()
})
// console.log é restaurado aqui
API signal
de Teste
O Vitest agora fornece um objeto AbortSignal
para o corpo do teste. Você pode usá-lo para interromper qualquer recurso que suporte esta Web API.
O sinal é abortado quando o teste atinge o tempo limite, outro teste falha e a flag --bail
é definida como um valor diferente de zero, ou o usuário pressiona Ctrl+C no terminal.
Por exemplo, você pode interromper uma requisição fetch
quando os testes são interrompidos:
it('stop request when test times out', async ({ signal }) => {
await fetch('/heavy-resource', { signal });
}, 2000);
Remapeamento de Cobertura V8 com reconhecimento de AST
O Vitest agora utiliza o pacote ast-v8-to-istanbul
, desenvolvido por um dos mantenedores do Vitest, AriPerkkio. Isso alinha o relatório de cobertura v8 com o istanbul, mas oferece um desempenho melhor. Habilite este recurso definindo coverage.experimentalAstAwareRemapping
como true
.
Planejamos tornar este o modo de remapeamento padrão na próxima versão principal. O antigo v8-to-istanbul
será removido completamente. Sinta-se à vontade para participar da discussão em https://github.com/vitest-dev/vitest/issues/7928.
Opção watchTriggerPatterns
Quando você edita um arquivo, o Vitest é inteligente o suficiente para reexecutar apenas os testes que importam esse arquivo. Infelizmente, a análise estática do Vitest respeita apenas as declarações import
estáticas e dinâmicas. Se você estiver lendo um arquivo ou iniciando um processo separado, o Vitest ignorará as alterações nos arquivos relacionados.
Com a opção watchTriggerPatterns
, você pode configurar quais testes devem ser reexecutados, dependendo do arquivo que foi alterado. Por exemplo, para sempre reexecutar os testes de mailers
quando um modelo é alterado, adicione um padrão de gatilho:
export default defineConfig({
test: {
watchTriggerPatterns: [
{
pattern: /^src\/templates\/(.*)\.(ts|html|txt)$/,
testsToRun: (file, match) => {
return `api/tests/mailers/${match[2]}.test.ts`;
},
},
],
},
});
O Novo Tipo Matchers
Multiuso
O Vitest agora possui um tipo Matchers
que você pode estender para adicionar suporte de tipo a todos os seus matchers personalizados em um só lugar. Este tipo afeta todos esses casos de uso:
expect().to*
expect.to*
expect.extend({ to* })
Por exemplo, para ter um matcher toBeFoo
com segurança de tipo, você pode escrever algo assim:
import { expect } from 'vitest';
interface CustomMatchers<R = unknown> {
toBeFoo: (arg: string) => R;
}
declare module 'vitest' {
interface Matchers<T = any> extends CustomMatchers<T> {}
}
expect.extend({
toBeFoo(actual, arg) {
// ^?
// ... implementation
return {
pass: true,
message: () => '',
};
},
});
expect('foo').toBeFoo('foo');
expect.toBeFoo('foo');
sequence.groupOrder
A nova opção sequence.groupOrder
controla a ordem em que o projeto executa seus testes ao utilizar vários projetos.
- Projetos com o mesmo número de ordem de grupo serão executados juntos, e os grupos são executados do menor para o maior.
- Se você não definir essa opção, todos os projetos serão executados em paralelo.
- Se vários projetos usarem a mesma ordem de grupo, eles serão executados ao mesmo tempo.
Exemplo
Considere este exemplo:
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
projects: [
{
test: {
name: 'slow',
sequence: {
groupOrder: 0,
},
},
},
{
test: {
name: 'fast',
sequence: {
groupOrder: 0,
},
},
},
{
test: {
name: 'flaky',
sequence: {
groupOrder: 1,
},
},
},
],
},
});
Os testes nesses projetos serão executados na seguinte ordem:
0. slow |
| (executando em conjunto)
0. fast |
1. flaky | (executa após 'slow' e 'fast')
A lista completa de alterações está no Changelog do Vitest 3.2.