loading...
Cover image for Jest, Babel e TypeScript: Configurando testes para seu projeto

Jest, Babel e TypeScript: Configurando testes para seu projeto

oieduardorabelo profile image Eduardo Rabelo ・4 min read

Devido a grande quantidade de ferramentas e configurações, fica difícil entender o "como" e achar exemplos de "onde" devemos configurar nossas ferramentas de desenvolvimento web.

Nesse eterna evolução da nossa área, vamos focar em três ferramentas principais que você pode encontrar hoje em dia: Jest, Babel e TypeScript.

Vamos focar em 2 categorias aqui:

  • Um projeto com Babel e adicionando TypeScript, onde teremos testes em JavaScript e TypeScript
  • Um projeto TypeScript, onde teremos testes em TypeScript

Vamos começar pelo projeto de TypeScript.

Jest e TypeScript

A um tempo atrás, eu escrevi um artigo de como rodar testes em Node.js com TypeScript, o princípio é o mesmo! Como esse projeto contém apenas TypeScript, não precisamos ir muito além nas ferramentas extras.

Vamos adicionar TypeScript e Jest:

mkdir jest-typescript

cd $_

npm init -y

npm install --save-dev \
    jest@25.1.0 \
    typescript@3.7.5

npm install --save-dev \
    ts-jest@25.2.0 \ 
    @types/jest@25.1.2
  • Instalamos as versões atuais de Jest e TypeScript
  • Com ts-jest, teremos suporte a source map e type checking ao rodar nossos testes
  • E instalamos o @types/jest@25.1.2 para termos os tipos de definição do Jest, tais como expect, test, it etc

Outra funcionalidade bacana do ts-jest é sua CLI para criar uma configuração inicial:

npx ts-jest config:init

Com isso, teremos um jest.config.js na nossa pasta da seguinte forma:

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
};

Você pode alterar testEnvironment para jsdom.

Fazemos o mesmo para o TypeScript:

npx tsc --init

E teremos nosso tsconfig.js:

{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",

    "strict": true,

    "esModuleInterop": true,

    "forceConsistentCasingInFileNames": true
  }
}

Nota: Não há nenhuma personalização nessa configuração do TypeScript. Eu apenas removi os comentários.

Agora, podemos criar nosso arquivo de teste:

cat hello.test.ts

E atualizar o package.json:

    ...
  "scripts": {
    "test": "jest --no-cache"
  }
  ...

Escrevemos nosso teste em hello.test.ts:

interface Hello {
  name: string
}

let me : Hello = {
  name: 'me'
}

it('works', () => {
  expect(me.name).toBe('me');
})

E teremos um resultado como:

> /jest-typescript
> jest --no-cache

 PASS  ./hello.test.ts
  ✓ works (2ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        1.481s
Ran all test suites.

Agora, podemos focar na integração do Babel com TypeScript.

Jest, Babel e TypeScript

Para esse exemplo, iremos criar uma nova pasta jest-babel-typescript e instalarmos nossas dependências:

mkdir jest-babel-typescript
cd $_

npm init -y

npm install --save-dev \
    jest@25.1.0 \
    babel-jest@25.1.0 \
    @babel/core@7.8.4 \
    @babel/preset-env@7.8.4 \

npm install --save-dev \
    @babel/preset-typescript@7.8.3 \
    @types/jest@25.1.2
  • Instalamos as versões atuais de Jest e Babel
  • E por último, instalamos o @babel/preset-typescript, permitindo que o Babel entenda a sintaxe TypeScript. Você leu certo, não precisamos instalar o pacote TypeScript typescript@*.
  • O @types/jest@25.1.2 para termos os tipos de definição do Jest, tais como expect, test, it etc

Como mencionado acima, não precisamos instalar o TypeScript typescript@*, pois o Babel com @babel/preset-typescript entende a sintaxe TypeScript. O que NÃO ACONTECE AQUI é o type checking, pois o preset simplesmente converte a sintaxe TypeScript para JavaScript.

Se você quiser utilizar o type checking, você precisa instalar o TypeScript typescript@* e ter um comando como "typecheck": "tsc --noEmit" em seu package.json, com um arquivo tsconfig.json em sua pasta.

Iremos criar 4 arquivos:

  • multi.js e multi.test.ts: Nosso código em um arquivo JavaScript e seu teste em um arquivo TypeScript
  • sum.ts e sum.test.js: Nosso código em um arquivo TypeScript e seu teste em um arquivo JavaScript

No multi.js:

export function multi(a, b) {
  return a * b;
}

E em multi.test.ts:

import { multi } from "./multi";

test("1 * 2", () => {
  expect(multi(1, 2)).toBe(2);
});

Em sum.ts:

export function sum(a: number, b: number): number {
  return a + b;
}

E em sum.test.js:

import { sum } from "./sum";

test("1 + 2", () => {
  expect(sum(1, 2)).toBe(3);
});

Atualizamos nosso package.json:

    ...
  "scripts": {
    "test": "jest --no-cache"
  }
  ...

E teremos um resultado como:

> @ test /jest-babel-typescript
> jest --no-cache

 PASS  ./multi.test.ts
 PASS  ./sum.test.js

Test Suites: 2 passed, 2 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        1.816s
Ran all test suites.

Finalizando

Apesar do exemplo acima não conter configurações complexas, como path alias (e.g. import P from '@services/api') ou webpack, a mensagem é de que é possível integrar todas essas opções.

Podemos desenhar 2 cenários aqui:

1. Eu tenho um projeto em Babel e quero MIGRAR para TypeScript.

Coloque o @babel/preset-typescript no seu projeto e todos os @types/ que você precisar, isso será necessário para fazer o Babel entender a sintaxe TypeScript e incluir definições das suas dependências. Migre sua base de código para *.ts(x).

No final, faça a instalação do typescript@* e use tsc --init para criar uma configuração base. Remova o Babel e suas configurações e utilize tsc como novo compilador.

2. Eu tenho um projeto em Babel mas quero TYPE CHECKING do TypeScript

Coloque o @babel/preset-typescript no seu projeto e todos os @types/ que você precisar, isso será necessário para fazer o Babel entender a sintaxe TypeScript e incluir definições das suas dependências.

Faça a instalação do typescript@*, e tenha um tsconfig.json com "noEmit": true e "allowJs": true, utilize o comando tsc para fazer o type checking.

Nota: O tsconfig.json pode ser necessário no caso 1 e 2 desde o começo, caso você tenha path alias em Babel, você também precisa criar path alias para o TypeScript.

Cada projeto de um objetivo diferente, mas isso não quer dizer que não podemos configurar as mesmas ferramentas de base.

Quer compartilhar algo ou deixar uma pergunta? Use os comentários! 👋

Tenha umm bom código! 🥳

Discussion

pic
Editor guide