Criando e executando Testes de Contrato com Pact.js — Parte I

Eduardo Pacheco Celeste
beyondTest
Published in
6 min readMay 4, 2020

Passo a passo de como criar e executar testes de contrato com Jest e Pact.js na perspectiva do Consumer

pact and jest

Este é a segunda parte de uma série de artigos que falam especificamente dos testes de contrato. A primeira parte pode ser vista neste link: Introdução aos Testes de Contrato com Pact. No primeiro artigo falamos sobre a importância deste tipo de teste, suas terminologias e de maneira macro sobre o seu funcionamento.

Já neste iremos implementar um teste de contrato do zero! Iremos dividir o artigo em três partes pra não ficar uma leitura tão pesada. Nesta primeira parte iremos criar o contrato no lado do Consumer, na segunda vamos demonstrar o envio do Pact File para um broker local (assim como para o Pactflow) e na terceira realizar a validação no lado do Provider.

Apesar do artigo ter sido escrito baseado na linguagem Javascript o Pact pode ser utilizado em diversas outras linguagens, conforme dito no artigo anterior. Portanto, apenas para exemplificar, nada impede de escrevermos um teste de contrato no lado do Consumer em Node e no lado do Provider em Kotlin ou vice-versa. O que interessa no fim das contas é que ambos consigam gerar e validar o Pacto entre eles.

Pré-Requisitos

Para que todas as etapas do tutorial possam ser executadas com sucesso é necessário a instalação/configuração de alguns softwares e ter conhecimento básico em Javascript:

  • IDE de Desenvolvimento (Fica a critério de vocês a utilização da que vocês se sentirem mais confortáveis, no meu caso estou utilizando o VSCode)
  • Docker (Neste tutorial há um link que auxilia na instalação do Docker para todos os sistemas operacionais: Pact Broker via Docker Images)
  • Node e NPM (Já este artigo possui alguns links que vão auxiliar na instalação de ambos: Criando uma REST API Fake com JSON Server)

Primeira etapa: Configurando e instalando as dependências do projeto

A primeira etapa do projeto vai ser iniciá-lo com as dependências necessárias para assim criarmos nossos testes. Para isso, abra o seu terminal e crie o seu projeto (No exemplo abaixo, criamos o projeto dentro da pasta /tmp e iniciamos ele com o comando npm init -y):

$ mkdir testes-de-contrato$ cd testes-de-contrato$ npm init -y 
Wrote to /private/tmp/testes-de-contrato/package.json:
{
"name": "testes-de-contrato",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}

O output no seu terminal deve ser algo parecido com o mostrado acima. Agora vamos instalar as dependências do projeto:

$ npm i axios dotenv

E agora as dependências de desenvolvimento:

$ npm i --save-dev @sucrase/jest-plugin @pact-foundation/pact @pact-foundation/pact-node jest json-server

A ideia do artigo é o de criar um teste de contrato e por isso não vou adentrar nos detalhes do que é cada uma dessas dependências.

Pra finalizar o setup do nosso ambiente vamos criar mais um arquivo na raiz do nosso projeto e realizarmos uma última configuração no package.json. O arquivo a ser criado será chamado de .env (que será falado e utilizado na sequência). Já no package.json iremos adicionar uma nova configuração conforme mostrado no snippet abaixo:

package.json

Isto irá nos permitir trabalhar com o Jest utilizando o ECMAScript 6. Para mais informações sobre o ES6, deem um olhada neste artigo: link

Segunda etapa: Criando o teste no lado do Consumer

Agora vamos realizar a criação do nosso teste de contrato na perspectiva do Consumidor. Para isto vamos criar dois diretórios: primeiro o diretório src (iremos falar dele em breve) e o segundo o __tests__ dentro do nosso projeto. E dentro deste segundo diretório, criaremos as pastas contract e consumer. Na pasta consumer iremos criar um arquivo chamado: consumer.spec.js

Caso a estrutura das pastas/arquivos esteja igual a minha, a sua IDE deverá estar parecido com a imagem abaixo:

Agora vamos criar nosso teste! Dentro do arquivo consumer.spec.js devemos inserir o seguinte código:

Explicando em blocos cada parte do código acima:

  • Da linha de 1 a 7 realizamos alguns imports necessários para a execução do teste (Mais detalhes abaixo).
  • Da linha 9 até a 18 realizamos a configuração do Mock do nosso Provider. Ou seja, quando executamos o teste, o Pact inicializa um servidor de mock interno e estas são as configurações básicas para a sua execução. Note que definimos um nome para o nosso Consumer e outro para o nosso Provider. Além disso a porta na qual o servidor irá rodar (e isto através de variáveis de ambiente) e dois diretórios que serão criados a cada execução: o primeiro é o diretório de logs (que auxiliam na identificação de erros durante a execução do teste) e o segundo é o diretório onde os Pact Files irão ser gerados.
  • O bloco da linha 20 até a 45 é um hook que inicializa o servidor mock e adiciona uma Interação para a execução do teste. Em outras palavras a interação nada mais é do que uma receita que servirá de base pra validarmos o pacto. Por exemplo, com base no cenário acima, definimos que a rota /characters é do tipo GET e irá retornar uma lista de objetos. Essa lista deverá possuir três campos, sendo que os campos id e age serão do tipo inteiro e o campo name deverá ser algo como o definido no exemplo. Além disso, o mínimo esperado na listagem é de cinco registros e o código da resposta deverá ser igual a 200.
  • A linha 47 e a 49 são responsáveis por encerrar o servidor de Mock e consequentemente criar as pastas logs e pacts onde (caso não ocorrer nenhum erro) irão conter os dados do Pact File. Em caso de erro um arquivo será gerado na pasta logs contendo algumas informações.
  • Por fim, da linha 51 a 59 é onde executamos o nosso teste. Neste caso precisamos criar o método fetchCharacters pois ele ainda não existe. Iremos criar esse método dentro da pasta src (que foi criada anteriormente na raiz do projeto). O restante do teste é bem simples, ele aguarda a resposta do servidor de Mock e faz alguns assertions na resposta e no status code.

Terceira etapa: Criando o método fetchCharacters e gerando o Pact File

Conforme falamos anteriormente, precisamos criar o método fetchCharacters e ele será criado dentro do arquivo src/service/api.js:

O conteúdo deste arquivo é bem simples. Realizamos o import da biblioteca axios (responsável por realizar as requisições HTTP) e através das variáveis de ambiente, criamos a variável baseUrl. Note que a variável de ambiente é a mesma utilizada anteriormente lá na configuração do servidor mock.

A último passo desta etapa é criamos a variável de ambiente MOCK_SERVER_PORT. Para isso, é só irmos até o arquivo .env criado anteriormente na raiz do projeto e definirmos o valor da nossa porta do servidor mock (no exemplo abaixo definimos e iremos utilizar a porta 3377):

.env

E com isso temos tudo o que é preciso pra gerarmos nosso Pact File 😮

Pra gerarmos o Pacto também é uma tarefa simples. Basta irmos no nosso arquivo package.json e dentro do objeto scripts inserir o seguinte comando:

package.json

Agora basta irmos no nosso terminal (e estarmos na raiz do projeto) e executarmos o comando:

$ npm run test:consumer

Com este comando as pastas logs e pacts serão criadas na raiz do projeto e poderemos ver o Pact File gerado :)

Próximos passos

Agora vamos enviar o pacto gerado para o nosso Broker. A continuação desse artigo pode ser visualizada através deste link: Criando e executando Testes de Contrato com Pact.js — Parte II

--

--