Ir para o conteúdo principal

Jest 28: Redução de peso e melhorias de compatibilidade 🫶

· 9 min de leitura"
Simen Bekkhus
Simen Bekkhus
Tradução Beta Não Oficial

Esta página foi traduzida por PageTurner AI (beta). Não é oficialmente endossada pelo projeto. Encontrou um erro? Reportar problema →

O Jest 28 finalmente chegou, trazendo recursos há muito solicitados como suporte para fragmentação (sharding) de testes em múltiplas máquinas, exports em pacotes e a capacidade de personalizar o comportamento de temporizadores falsos (fake timers). Estes são apenas alguns destaques pessoais, e exploraremos mais neste post.

Além disso, conforme anunciado no post do Jest 27 no ano passado, removemos pacotes não utilizados por padrão da instalação padrão. Como resultado, o tamanho da instalação reduziu cerca de 1/3.

Mudanças de quebra

A lista de mudanças de quebra é extensa (e pode ser vista no changelog), mas para facilitar a migração, também criamos um guia para você seguir. Esperamos que isso torne a atualização o mais tranquila possível!

As principais mudanças de quebra que podem impactar sua migração são a remoção do suporte para Node 10 e 15 (mas não o Node 12, que terá seu fim de vida em alguns dias) e algumas opções de configuração renomeadas.

Importante destacar que ambos os módulos removidos (jest-environment-jsdom e jest-jasmine2) ainda são mantidos ativamente e testados da mesma forma, portanto a única mudança de quebra é que você precisará instalá-los explicitamente.

O guia deve tornar a migração trivial, mas note que se você usar diretamente qualquer pacote que compõe o Jest (como jest-worker ou pretty-format), em vez de apenas executar jest, será necessário verificar o changelog para identificar mudanças de quebra.

Funcionalidades

Agora vamos falar sobre as novidades do Jest 28, que são muito mais empolgantes! E são várias, então prepare-se.

Fragmentação de execução de testes

O Jest agora inclui uma nova opção CLI --shard, contribuída por Mario Nebl. Ela permite executar partes dos seus testes em máquinas diferentes, atendendo a uma das solicitações mais antigas do Jest.

A própria suíte de testes do Jest no CI reduziu de cerca de 10 minutos para 3 no Ubuntu, e no Windows de 20 minutos para 7.

exports no package.json

O Jest já oferecia suporte mínimo a exports na versão 27.3. Porém, apenas para o ponto de entrada principal (.), e somente se nenhum campo main estivesse presente no package.json. Com o Jest 28, estamos felizes em oferecer suporte completo!

Relacionado: no Jest 27, fornecíamos as condições require ou import. No Jest 28, o jest-environment-node agora fornece automaticamente as condições node e node-addons, enquanto o jest-environment-jsdom fornece a condição browser.

Este era um dos maiores problemas de compatibilidade do Jest, e esperamos que esteja finalmente resolvido.

Temporizadores falsos

O Jest 26 introduziu os temporizadores falsos "modernos", que usam @sinonjs/fake-timers internamente, e o Jest 27 os tornou padrão. No Jest 28, estamos expondo mais da implementação subjacente através de APIs de configuração e tempo de execução. Agradecemos imensamente a Tom Mrazauskas por contribuir com este recurso!

Isso permite que você não precise simular o process.nextTick, o que melhora a compatibilidade com Promises falsas, ou habilite o advanceTimers que avança temporizadores automaticamente.

Consulte a configuração fakeTimers para detalhes.

Reporter do GitHub Actions

O Jest agora inclui um reporter para uso no GitHub Actions, que utiliza anotações para exibir erros de teste diretamente no código.

Captura de tela de erro de teste no GitHub Actions

Você pode ativar esse reporter passando github-actions na opção de configuração reporters.

Um enorme agradecimento a Bernie Reiter e outros colaboradores por permanecerem conosco e finalmente implementarem esse recurso.

testEnvironmentOptions inline

Agora você pode passar testEnvironmentOptions diretamente no arquivo, similar à configuração do ambiente de teste. Isso é útil se você quiser, por exemplo, alterar a URL em um único arquivo.

/**
* @jest-environment jsdom
* @jest-environment-options {"url": "https://jestjs.io/"}
*/

test('use jsdom and set the URL in this test file', () => {
expect(window.location.href).toBe('https://jestjs.io/');
});

Todos os globais do Node.js

Se você está usando a nova implementação de fetch no Node v18, talvez tenha notado que essa função não estava disponível no Jest. Esse era um problema antigo onde precisávamos copiar manualmente os globais para o ambiente de teste. Com o Jest 28, isso foi resolvido: agora inspecionamos o ambiente global onde o Jest está sendo executado e copiamos quaisquer globais ausentes no ambiente de teste.

Módulos ECMAScript

Pouco mudou no suporte do Jest para ESM nativo desde o Jest 27. Continuamos aguardando a estabilização no Node, e esperamos que essa situação melhore em breve!

No entanto, conseguimos adicionar alguns novos recursos no Jest 28.

URLs data:

Tommaso Bossi contribuiu com suporte para URLs data, permitindo que você defina JavaScript inline para execução sem usar eval.

import.meta.jest

Embora você já pudesse acessar o jest via import {jest} from '@jest/globals', recebemos feedback de que isso é menos ergonômico que a variável global jest disponível em CJS. Por isso, o Jest 28 inclui import.meta.jest para facilitar o acesso.

Diversos

Esses foram muitos recursos e meus destaques pessoais. Mas ainda temos mais que vou apresentar rapidamente:

Resolvedores assíncronos

Ian VanSchooten contribuiu com suporte para resolvedores assíncronos, permitindo que ferramentas como Vite tenham integrações melhores com o Jest.

Arquivos de setup assíncronos

Se você precisa realizar trabalhos assíncronos usando setupFiles, agora pode exportar uma async function que o Jest executará e aguardará antes de carregar os testes.

Nota: esse recurso está disponível apenas para CJS. Para ESM, recomendamos usar await de nível superior.

Usando globalThis

Internamente, o Jest vinha usando global para se referir ao ambiente global. Porém, como isso só existe no Node e não em navegadores (window), isso causava incompatibilidade ao tentar usar os módulos do Jest em outros ambientes.

O Jest 28 agora usa globalThis, que funciona em todos os ambientes.

JSDOM 19

Como mencionado, o Jest não inclui mais jest-environment-jsdom na instalação padrão, mas ele continua sendo mantido ativamente. Como parte disso, o Jest 28 atualizou do jsdom@16 para o jsdom@19.

TypeScript

Se você usa Jest com TypeScript, seja nos seus testes ou ao escrever plugins como runners personalizados, o Jest 28 traz melhorias extensivas em nossas tipagens. Aqui está uma lista não exaustiva das mudanças:

expect

Ao usar os tipos próprios do expect (diretamente ou via import {expect} from '@jest/globals'), agora finalmente é possível adicionar matchers personalizados. Veja nosso exemplo para saber como fazer.

Plugins personalizados

Se você escreve um runner, reporter de testes, resolver ou algo similar, agora exportamos mais tipos que devem ajudar na tipagem correta. Este é um trabalho contínuo - se você desenvolve plugins para Jest e os tipos não são tão úteis quanto poderiam ser, por favor abra uma issue!

jest-runner-tsd

O jest-runner-tsd é um runner personalizado para testes de tipos. É o que o Jest usa internamente para testar nossas tipagens, e esperamos que outros também possam usá-lo! Como o nome sugere, ele é baseado no tsd, usando internamente o fork tsd-lite.


Todas essas melhorias e correções foram contribuídas por Tom Mrazauskas. Muito obrigado, Tom! 👏

Por fim, a versão mínima suportada do TypeScript agora é a 4.3.

jest-light-runner

A última novidade que queremos destacar é um runner muito interessante criado por Nicolò Ribaudo: o jest-light-runner. Ele mantém quase toda a DX (Developer Experience) pela qual o Jest é conhecido, mas acelera drasticamente os testes com uma abstração mais leve sobre o Node. Os testes do Babel ficaram quase duas vezes mais rápidos após a migração. Apesar de algumas limitações, este runner torna o Jest ainda mais atraente para quem testa módulos Node menores. Obrigado, Nicolò!

Futuro

Embora o Jest 28 tenha levado quase um ano após o 27, o Jest 29 chegará mais rápido - provavelmente em poucos meses. A principal mudança planejada (além de remover suporte para versões antigas do Node) é definir snapshotFormat como padrão para {escapeString: false, printBasicPrototype: false}, tornando os snapshots mais legíveis e copiáveis.

Claro que será possível sobrescrever essa configuração se preferir, mas você já pode usar essas opções hoje mesmo se não quiser esperar!

Agradecimentos

O Jest 28 contém contribuições de mais de 60 pessoas, sendo que mais de dois terços são colaboradores pela primeira vez. Muito obrigado a todos os colaboradores, veteranos e novatos. Sem vocês, o projeto não seria nem de perto tão bom quanto é! Gostaria de agradecer especialmente a Tom Mrazauskas e Feng Yu por todas suas contribuições, desde código até triagem de issues e depuração, que fizeram do Jest 28 o que ele é. Obrigado! 🙏

Obrigado por ler e bons testes! 🃏