Skip to main content

Neste artigo, irei dar uma introdução ao TDD em Node.js com os testes feitos em Jest e aplicá-los na fase inicial da construção de uma aplicação com Koa.js.

Primeiramente, o que é TDD?

No TDD em Node.js, escrevemos os testes e desenvolvemos o código para que ele passe neste teste, ele se divide em três etapas:

Vermelho : o teste vai falhar, porque não temos nenhuma lógica construída só as suítes e casos de teste.

Verde: escreve o código para que passe no teste, baseada na descrição e no resultado esperado em cada um dos testes.

Roxa (refatora): melhore o código que já passou nos testes, eliminando redundâncias e duplas responsabilidades em suas funcionalidades.

TDD em Node.js

Como adotar o TDD em Node.js em um projeto?

Os testes devem ser feitos de modo unitário, testando cada funcionalidade separadamente, como são executados automaticamente, não precisamos ficar abrindo a aplicação e testar manualmente cada uma dessas funcionalidades.

Em testes manuais, deveríamos subir nossa aplicação e realizar cada caso de teste “na mão” e evidenciar cada resultado, em testes automáticos ele irá subir a aplicação, executar cada testes, exibir o resultado esperado e o que foi obtido SOZINHO.

Vantagens de adotar o TDD

  • Qualidade de código

Se um código não pode ser testado por uma máquina, talvez ele não esteja tão “limpo” e bem estruturado assim.

  • Raciocínio

Sabendo exatamente o que esperar de cada parte do seu código, você já desenvolve focado na responsabilidade de cada parte dele e inserindo o resultado que é exatamente esperado.

  • Segurança

Em casos emergenciais, é possível em alguns casos recorrer aos testes para ver o que cada funcionalidade faz e executar a manutenção de forma mais rápida, sem ter que analisar o código inteiro.

  • Trabalho em equipe

A integração de novos membros na equipe é facilitada pelo uso de testes bem documentados para conhecer o seu sistema.

  • Documentação

Fazendo os testes antes do código, sempre que for lançada uma nova funcionalidade, ela já estará documentada antes de ser laçada, pelo método “convencional”, quando se faz a documentação após a conclusão da última versão da sua aplicação, temos o grande risco de esquecer de documentar algo e não terminar esta documentação até o lançamento na nova versão.

O que vamos utilizar neste exemplo?

Node.js

Node.js — TDD em Node.js
Wikipédia

Pode ser descrito como o javascript server-side , trabalha de forma assíncrona, não bloqueante, orientado a eventos (fluxo é controlado por ações/requsições externas) e open-source.

Ideal para aplicações real-time

KOA.js

Koa. — TDD em Node.js
npm

Desenvolvido pela equipe do Express, é uma versão “menor’ e com mais funcionalidades para aplicativos web e APIs, com suas funções assíncronas, pode eliminar retornos de chamadas e facilitar o tratamento dos erros. Por não usar middlewares em várias partes do código, torna os servidores mais rápidos e com código mais limpo

JEST

Jest — TDD em Node.js
jestjs.io

Criado pelo facebook, pode ser usado em Node, Javascript puro, React, Angular, Vue e outros frameworks.

É bem completo, rápido e precisa de pouca configuração para usar, quando os testes não passam, fornece um contexto rico do porque falhou.

Dependências a serem utilizadas na escrita dos testes:

#configuração dos testes

npm install   jest --save-dev

será responsável por configurar e executar nossos testes

npm install supertest --save-dev

o supertest nos fornece uma melhor abstração e compreensão do resultado e execução dos testes. agora escrevemos os testes view rawconfiguração dos testes.md hosted with ❤ by GitHub

Crie uma pasta __tests__ nesta pasta irão nossas suítes de teste que o Jest irá executar, crie um arquivo routes.test.js com o seguinte conteúdo:

//importa os módulos e aqruivos necessários
const request = require('supertest');
const server = require('../app.js');
const sayTDD = require('../helloJest');

//o que será executado antes de todos os testes
beforeAll(async () => {
   console.log('Iniciando TDD com jest!');
});

//o que será executado após todos os testes
afterAll(() => {
   //o server close irá encerrar nossa aplicação, evitando problemas da porta já estar em uso
server.close();
console.log('servidor fechado');
});


describe('inicio dos testes', () => {
   //descrição do caso de testes
   test('acessa a rota da home e verifica o conteúdo que é exibido ', async () => {
      //qual a rota que ele deve acessar e qual requisição deve fazer
      const response = await request(server).get('/');
      //qual o status esperado 
      expect(response.status).toEqual(200);
      //se todos esses passos passarem, verifica o conteúdo exibido dentro desta rota
      expect(response.text).toContain('<h1>Você está na Home!</h1> <p> vamos começar os testes </p>');

   });

   test('acessa a rota /tdd e então será apresentada a seguinte defiição de tdd:', async () => {
      const response = await request(server).get('/TDD');
      expect(response.status).toEqual(200);
      expect(response.text).toContain('<h4>no tdd primeiro fazemos os testes e depois desenvolvemos o sistema para que ele passe nos testes</h4>');
   });

   test('acessa a rota /koa e então será apresentada a seguinte definição de Koa.js', async () => {
      const response = await request(server).get('/KOA');
      expect(response.status).toEqual(200);
      expect(response.text).toContain('<h4>O Koa é uma nova estrutura da Web criada pela equipe do Express, que pretende ser uma base menor, mais expressiva e mais robusta para aplicativos da Web e APIs</h4>');

   });
   //aqui não iremos testar uma rota e sim o retorno de uma função.
   test('irá verificar o retorno da função saytdd', () => {
      //é esperado que o retorno da função saytdd seja:
      expect(sayTDD()).toMatch('TDD é o Desenvolvimento Orientado por Testes');
   });

Testes modelados, agora vamos instalar as dependências necessárias para iniciarmos nosso desenvolvimento:

dependencias da aplicação.md hosted with ❤ by GitHub
dependencias da aplicação.md hosted with ❤ by GitHub

Criamos o arquivo app.js que será nosso servidor para que passe nos nossos testes:

//esse arquivo é o nosso servidor
const Koa = require('koa');
const Router = require('koa-router');
const logger = require('koa-logger');
//iniciamos uma nova aplicação Koa
const app = new Koa();
//iniciamos as rotas
const router = new Router();

//habilitamos o uso do Koa Logger
app.use(logger());

//faz um get na rota home, o ctx é um espécie de método acessor que pega o contexto de uma parte do código e o next informa ao 
//middleware que após terminar esa operação pode ir para a próxima requisição de forma não bloqueante
router.get('/', (ctx, next) => {
    ctx.body = '<h1>Você está na Home!</h1> <p> vamos começar os testes </p>';
});

router.get('/TDD', (ctx, next) => {
    ctx.body = '<h4>no tdd primeiro fazemos os testes e depois desenvolvemos o sistema para que ele passe nos testes</h4>';
   });

router.get('/KOA', (ctx, next) => {
    ctx.body = '<h4>O Koa é uma nova estrutura da Web criada pela equipe do Express, que pretende ser uma base menor, mais expressiva e mais robusta para aplicativos da Web e APIs</h4>';
   });
//cria as rotas
app.use(router.routes());
//permite todos os tipos de requisição,get,post,put,delete
app.use(router.allowedMethods());
//cria o servidor para rodar na porta 3000
const server = app.listen(3000);
//exporta o server para que seja possivel acessá-lo em outras partes do programa
module.exports = server;

O último caso de testes, era sobre retorno de uma função, vamos criá-la em um arquivo helloJest.js à parte do nosso server

function sayTDD(){
    //criamos a função com exatamente o retorno que foi descrito nos testes
    return 'TDD é o Desenvolvimento Orientado por Testes'
}



module.exports = sayTDD;

helloJest.js hosted with ❤ by GitHub

Antes de executarmos os testes, verifique se o seu package.json está semelhante à este:

{
  "name": "koatesting",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "jest --watchAll",
    "dev": " nodemon app.js "
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "koa": "^2.7.0",
    "koa-logger": "^3.2.0",
    "koa-router": "^7.4.0"
  },
  "devDependencies": {
    "jest": "^24.1.0",
    "supertest": "^3.4.2"
  }
}

package.json hosted with ❤ by GitHub

Algumas observações:

Node - Erro com porta em uso, execute o seguinte comando no seu prompt como administrador
README.md hosted with ❤ by GitHub

Agora é só executar npm run test dentro da pasta da aplicação e ver os testes passando com sucesso, experimente fazer algo errado mo código para ver como é apresentado o erro no teste (com o jest — watchAll, toda alteração salva já é testada automaticamente, não precisa executar este comando a cada alteração).

Segue o repositório no git, as referências e os slides que utilizei nessa talk:

http://blog.sciensa.com/tdd-test-driven-development-guia-rapido/

http://nodebr.com/o-que-e-node-js/

https://koajs.com/#introduction

https://jestjs.io/pt-BR/

http://tdd.caelum.com.br/

https://treinamento.nodebr.org/

https://github.com/koajs/logger

https://github.com/ZijianHe/koa-router

https://github.com/koajs/workshop

https://jestjs.io/

https://github.com/facebook/jest

Kamila de Fátima Santos Oliveira é Analista de Sistemas na BRQ

BRQ fale conosco
FALE CONOSCO