Jest 30: Mais Rápido, Mais Leve, Melhor
Esta página foi traduzida por PageTurner AI (beta). Não é oficialmente endossada pelo projeto. Encontrou um erro? Reportar problema →
Hoje temos o prazer de anunciar o lançamento do Jest 30. Esta versão traz uma quantidade significativa de mudanças, correções e melhorias. Embora seja um dos maiores lançamentos principais do Jest até hoje, reconhecemos que três anos para uma versão major é muito tempo. No futuro, planejamos fazer lançamentos principais mais frequentes para manter o Jest excelente na próxima década.
Se você quer pular as novidades e começar a usar, execute npm install jest@^30.0.0 e siga o guia de migração: Atualizando do Jest 29 para o 30.
O que há de novo?
O Jest 30 é visivelmente mais rápido, consome menos memória e traz toneladas de novos recursos. Primeiro, vamos ver as breaking changes:
Mudanças que Quebram Compatibilidade
-
Jest 30 remove suporte para Node 14, 16, 19 e 21.
-
jest-environment-jsdomfoi atualizado do jsdom 21 para o 26. -
A versão mínima compatível do TypeScript agora é a 5.4.
-
Vários aliases do
expectforam removidos. Oeslint-plugin-jestpossui um autofixer que você pode executar para atualizar automaticamente seu código. -
Propriedades não enumeráveis de objetos agora são excluídas por padrão de matchers como
toEqual. -
Jest agora suporta arquivos
.mtse.ctspor padrão. -
--testPathPatternfoi renomeado para--testPathPatterns. -
Jest agora trata corretamente promises que são inicialmente rejeitadas e posteriormente capturadas, evitando falsos positivos em testes.
-
Fizemos várias melhorias na impressão de snapshots do Jest, o que pode exigir que você atualize seus snapshots. O Google descontinuou links
goo.glque usávamos em snapshots. Também não gostamos, mas você precisará atualizar todos os snapshots. -
O Jest agora é empacotado em um único arquivo por pacote. Isso melhora o desempenho, mas pode quebrar ferramentas que acessam internals do Jest.
Estes são apenas alguns destaques. A lista completa de breaking changes pode ser encontrada no CHANGELOG e no guia de migração do Jest 30.
Melhorias de Desempenho e Memória
O Jest 30 oferece ganhos reais de desempenho graças a várias otimizações, especialmente em resolução de módulos, uso de memória e isolamento de testes. Ao adotar o novo unrs-resolver, a resolução de módulos no Jest tornou-se mais rica em recursos, compatível com padrões e mais rápida. Agradecemos a @JounQin pela migração. Dependendo do seu projeto, você pode observar execuções de testes significativamente mais rápidas e consumo reduzido de memória. Por exemplo, um grande app TypeScript com cliente e servidor observou testes 37% mais rápidos e 77% menos uso de memória em parte do código:
| Jest 29 | Jest 30 | |
|---|---|---|
| Server tests | ~1350s / 7.8 GB max | ~850s / 1.8 GB max |
| Client tests | ~49s / 1.0 GB max | ~44s / 0.8 GB max |
O Jest é rápido, mas devido ao seu isolamento de testes, código lento do usuário frequentemente amplia problemas de performance e leva a testes lentos. Quando testes deixam handles abertos como timers não finalizados ou conexões com outros serviços, isso pode fazer o Jest travar ou ficar lento. O Jest 30 melhorou na detecção e relato desses problemas, ajudando você a identificar e corrigir testes lentos ou problemáticos mais facilmente. Por exemplo, testes na Happo foram acelerados em 50%, caindo de 14 para 9 minutos após limpar handles abertos e atualizar para o Jest 30.
Se você utiliza arquivos que consolidam as exportações de múltiplos módulos em um único arquivo (chamados "barrel files"), recomendamos usar ferramentas como babel-jest-boost, babel-plugin-transform-barrels ou no-barrel-file para evitar carregar grandes blocos de código da aplicação em cada arquivo de teste. Isso pode gerar ganhos de performance de até 100x.
Limpeza de globais entre arquivos de teste
O Jest garante isolamento entre arquivos de teste executando cada teste em um contexto VM separado, fornecendo um ambiente global novo para cada arquivo. Porém, se seu código não limpar variáveis globais após cada arquivo de teste, isso pode causar vazamentos de memória e tornar a execução mais lenta. O Jest 30 introduz um novo recurso que alerta sobre globais não limpos corretamente após a execução dos testes.
No futuro, o Jest limpará automaticamente as variáveis globais após cada execução de teste. Se você não receber alertas sobre globais não limpos no Jest 30, já pode ativar totalmente esse recurso definindo o modo de limpeza para "on" - isso trará economia significativa de memória e melhorias de performance:
export default {
testEnvironmentOptions: {
globalsCleanup: 'on',
},
};
O padrão no Jest é globalsCleanup: 'soft'. Para desativar o recurso, defina como off. Se precisar proteger objetos globais específicos (como utilitários compartilhados ou caches), marque-os como protegidos usando jest-util:
import {protectProperties} from 'jest-util';
protectProperties(globalThis['my-property']);
Agradecemos ao @eyalroth pela implementação deste recurso!
Novos Recursos
Melhor suporte a ECMAScript Modules e TypeScript
Foi adicionado suporte a import.meta.* e file:// ao usar ESM nativo com Jest. Além disso, agora você pode escrever arquivos de configuração do Jest em TypeScript, e arquivos .mts/.cts têm suporte nativo sem configuração extra. Se usar o recurso nativo do Node para remover tipos TypeScript, não carregamos mais o transformer, acelerando a execução.
Spies e a palavra-chave using
Agora você pode usar a nova sintaxe de gerenciamento explícito de recursos do JavaScript (using) com spies do Jest. Em ambientes compatíveis, using jest.spyOn(obj, 'method') restaurará automaticamente o spy ao final do bloco, eliminando a limpeza manual.
test('logs a warning', () => {
using spy = jest.spyOn(console, 'warn');
doSomeThingWarnWorthy();
expect(spy).toHaveBeenCalled();
});
expect.arrayOf
O Jest 30 introduz um novo matcher assimétrico, expect.arrayOf, que valida cada elemento de um array contra uma condição ou tipo. Por exemplo, para verificar um array de números:
expect(someArray).toEqual(expect.arrayOf(expect.any(Number)));
Novo placeholder no test.each: %$
Em testes data-driven com test.each, agora você pode usar o placeholder %$ nos títulos para inserir o número sequencial do caso de teste. Exemplo:
test.each(cases)('Case %$ works as expected', () => {});
Isso substituirá %$ pelo número do caso de teste.
jest.advanceTimersToNextFrame()
@sinonjs/fake-timers foi atualizado para v13, adicionando jest.advanceTimersToNextFrame(). Essa nova função avança todos os callbacks pendentes de requestAnimationFrame para o próximo frame, facilitando testes de animações ou códigos que dependem de requestAnimationFrame sem precisar estimar durações em milissegundos.
Retentativas de teste configuráveis
O Jest 30 aprimora jest.retryTimes() com novas opções que dão controle sobre como as retentativas são tratadas. Você pode especificar um atraso ou repetir imediatamente um teste falho, em vez de esperar até toda a suíte de testes terminar:
// Retry failed tests up to 3 times, waiting 1 second between attempts:
jest.retryTimes(3, {waitBeforeRetry: 1000});
// Immediately retry without waiting for other tests to finish:
jest.retryTimes(3, {retryImmediately: true});
jest.unstable_unmockModule()
O Jest 30 adiciona a nova API experimental jest.unstable_unmockModule() para controle refinado ao desativar mocks de módulos (especialmente com ESM nativo).
jest.onGenerateMock(callback)
Um novo método onGenerateMock foi adicionado. Ele registra uma função de callback invocada sempre que o Jest gera um mock para um módulo, permitindo modificar o mock antes de retorná-lo ao ambiente de teste:
jest.onGenerateMock((modulePath, moduleMock) => {
if (modulePath.includes('Database')) {
moduleMock.connect = jest.fn().mockImplementation(() => {
console.log('Connected to mock DB');
});
}
return moduleMock;
});
Outras Melhorias
Serialização personalizada de objetos
Os utilitários de matcher do Jest agora suportam definir uma propriedade estática SERIALIZABLE_PROPERTIES em objetos personalizados. Isso permite controlar quais propriedades são incluídas em snapshots e mensagens de erro, tornando a saída mais focada.
Suporte a configuração assíncrona
Arquivos de teste listados em setupFilesAfterEnv agora podem exportar funções assíncronas ou usar await no nível superior, similar ao setupFiles.
E muito mais...
Confira o CHANGELOG completo para todas mudanças, melhorias e novos recursos.
Problemas conhecidos
O jsdom fez alterações para maior conformidade com especificações. Isso pode quebrar alguns casos de uso, principalmente mocks de window.location em testes. O Jest agora inclui @jest/environment-jsdom-abstract para facilitar a criação de ambientes personalizados baseados em jsdom. Se você está apenas procurando corrigir o jsdom, pode aplicar este patch do jsdom ao seu projeto. Futuramente, podemos oferecer uma alternativa ao jsdom mais adequada para testes.
Próximos passos
O Jest é o framework de testes JavaScript mais popular há uma década, usado por milhões em projetos desde pequenas bibliotecas até os maiores códigos do mundo. Com melhorias constantes, acumulamos dívidas técnicas como qualquer projeto de software duradouro. Suportamos recursos pouco usados e minimizamos breaking changes para evitar impactos. Algumas funcionalidades deveriam ser possíveis sem fazer parte do core, enquanto outras incentivam práticas questionáveis. Com membros da equipe saindo ao longo do tempo, o ritmo de lançamentos diminuiu. Nossa estratégia:
-
Desempenho/Dívida técnica: Tornar o core mais enxuto e performático, removendo recursos subutilizados e focando no essencial.
-
Ciclos de lançamento consistentes: Adotar ciclos de lançamento e políticas de depreciação mais previsíveis.
-
Transparência: Construir tudo abertamente, compartilhar planos publicamente e criar mais oportunidades de contribuição.
-
Seja Ousado: Como equipe do Jest, precisamos ser mais audaciosos. Diversos fatores impedem o Jest de alcançar seu pleno potencial. É hora de agir.
A boa notícia é que o Jest sempre esteve bem estruturado para cumprir esses princípios, desde que construímos o framework como um sistema modular com clara separação de responsabilidades. Agora é hora de executar. Mais detalhes em breve!
Agradecimentos
Esta versão não teria sido possível sem o trabalho árduo da nossa comunidade. Obrigado.
@SimenB, @mrazauskas, @Connormiha, @liuxingbaoyu, @k-rajat19, @G-Rath, @charpeni, @dubzzz, @stekycz, @yinm, @lencioni, @phawxby, @lukeapage, @robhogan, @fisker, @k-rajat19, @connectdotz, @alesmenzel, @rickhanlonii, @mbelsky, @brunocabral88, @brandon-leapyear, @nicolo-ribaudo, @dj-stormtrooper, @eryue0220
Um agradecimento especial a todos que fizeram sua primeira contribuição para o Jest nesta versão. Obrigado por tornar o Jest melhor para todos!
@eyalroth, @KhaledElmorsy, @mohammednumaan, @bensternthal, @BondarenkoAlex, @phryneas, @jayvdb, @brandonchinn178, @latin-1, @rmartine-ias, @fa93hws, @Dunqing, @gustav0d, @noritaka1166, @andreibereczki, @Dreamsorcerer, @satanTime, @icholy, @ecraig12345, @cgm-16, @sebastiancarlos, @dancer1325, @loganrosen, @zakingslayerv22, @dev-intj, @tez3998, @anbnyc, @pengqiseven, @thypon, @co63oc, @danielrentz, @jonasongg, @andrew-the-drawer, @phryneas, @hyperupcall, @tonyd33, @madcapnmckay, @dongwa, @gagan-bhullar-tech, @ikonst, @ZuBB, @jzaefferer, @brandonnorsworthy, @henny1105, @DmitryMakhnev, @askoufis, @RahulARanger, @Jon-Biz, @fynsta, @KonnorRogers, @BondarenkoAlex, @mouadhbb, @kemuridama, @Avi-E-Koenig, @davidroeca, @akwodkiewicz, @mukul-turing, @dnicolson, @colinacassidy, @ofekm97, @haze, @Vadimchesh, @peterdenham, @ShuZhong, @manoraj, @nicolo-ribaudo, @georgekaran, @MathieuFedrigo, @hkdobrev, @Germandrummer92, @CheadleCheadle, @notaphplover, @danbeam, @arescrimson, @yepitschunked, @JimminiKin, @DerTimonius, @vkml, @ginabethrussell, @jeremiah-snee-openx, @WillianAgostini, @casey-lentz, @faizanu94, @someone635, @rafaelrabelos, @RayBrokeSomething, @DaniAcu, @mattkubej, @tr1ckydev, @shresthasurav, @the-ress, @Mutesa-Cedric, @nolddor, @alexreardon, @Peeja, @verycosy, @mknight-atl, @maro1993, @Eric-Tyrrell22






