Ambiente de Teste
O Vitest oferece a opção environment
para executar código em um ambiente específico. Você pode ajustar o comportamento do ambiente usando a opção environmentOptions
.
Por padrão, os seguintes ambientes estão disponíveis:
node
é o ambiente padrão.jsdom
emula o ambiente do navegador, fornecendo a API do navegador. Ele utiliza o pacotejsdom
.happy-dom
emula o ambiente do navegador, fornecendo a API do navegador. É considerado mais rápido que ojsdom
, mas pode não incluir todas as APIs. Ele utiliza o pacotehappy-dom
.edge-runtime
emula o edge-runtime da Vercel. Ele utiliza o pacote@edge-runtime/vm
.
INFO
Ao utilizar os ambientes jsdom
ou happy-dom
, o Vitest segue as mesmas regras do Vite para importação de CSS e assets. Se a importação de uma dependência externa falhar com o erro unknown extension .css
, você precisará incluir manualmente toda a cadeia de importação, adicionando todos os pacotes a server.deps.external
. Por exemplo, se o erro ocorrer em package-3
nesta cadeia de importação: código-fonte -> package-1 -> package-2 -> package-3
, você precisará adicionar todos os três pacotes a server.deps.external
.
A partir do Vitest 2.0.4, a resolução de require
para CSS e assets dentro de dependências externas é automática.
WARNING
"Ambientes" existem apenas ao executar testes no Node.js.
browser
não é considerado um ambiente no Vitest. Se você deseja executar parte de seus testes no Modo Browser, pode criar um projeto de workspace.
Ambientes para Arquivos Específicos
Ao definir a opção environment
em sua configuração, ela será aplicada a todos os arquivos de teste em seu projeto. Para um controle mais granular, você pode usar comentários de controle para especificar o ambiente para arquivos específicos. Comentários de controle são aqueles que começam com @vitest-environment
e são seguidos pelo nome do ambiente:
// @vitest-environment jsdom
import { expect, test } from 'vitest';
test('test', () => {
expect(typeof window).not.toBe('undefined');
});
Alternativamente, você pode definir a opção environmentMatchGlobs
, especificando o ambiente com base em padrões glob.
Ambiente Personalizado
Você pode criar seu próprio pacote para estender o ambiente do Vitest. Para isso, crie um pacote com o nome vitest-environment-${nome}
ou especifique um caminho para um arquivo JS/TS válido. Este pacote deve exportar um objeto no formato Environment
:
import type { Environment } from 'vitest';
export default <Environment>{
name: 'custom',
transformMode: 'ssr',
// opcional - apenas se você suportar o pool "experimental-vm"
async setupVM() {
const vm = await import('node:vm');
const context = vm.createContext();
return {
getVmContext() {
return context;
},
teardown() {
// chamado depois que todos os testes com este ambiente tiverem sido executados
},
};
},
setup() {
// configuração personalizada
return {
teardown() {
// chamado depois que todos os testes com este ambiente tiverem sido executados
},
};
},
};
WARNING
O Vitest exige a opção transformMode
no objeto de ambiente. Ela deve ser igual a ssr
ou web
. Este valor determina como os plugins transformarão o código-fonte. Se for definido como ssr
, os hooks do plugin receberão ssr: true
ao transformar ou resolver arquivos. Caso contrário, ssr
é definido como false
.
Você também tem acesso aos ambientes padrão do Vitest através da entrada vitest/environments
:
import { builtinEnvironments, populateGlobal } from 'vitest/environments';
console.log(builtinEnvironments); // { jsdom, happy-dom, node, edge-runtime }
O Vitest também fornece o utilitário populateGlobal
, que pode ser usado para injetar propriedades de um objeto no namespace global:
interface PopulateOptions {
// se funções não-classe devem ser vinculadas ao namespace global
bindFunctions?: boolean;
}
interface PopulateResult {
// uma lista de todas as chaves que foram copiadas, mesmo que o valor não exista no objeto original
keys: Set<string>;
// um mapa dos valores originais do objeto que podem ter sido sobrescritos pelas chaves
// você pode retornar esses valores dentro da função `teardown`
originals: Map<string | symbol, any>;
}
export function populateGlobal(
global: any,
original: any,
options: PopulateOptions
): PopulateResult;