JavaScript Assertivo Testes e qualidade de código em todas as camadas da aplicação

Gabriel Ramos

*Você terá acesso às futuras atualizações do livro.

Introdução: Todo mundo na mesma página

Este livro é para qualquer pessoa que queira se aprofundar em testes ou melhorar seus fundamentos no assunto.

É necessário um conhecimento prévio de JavaScript, porém, se você tem familiaridade com qualquer outra linguagem, não sentirá dificuldades em consumir este conteúdo.

Requisitos e configuração de ambiente local

Para facilitar o entendimento dos assuntos abordados aqui, é interessante que tenhamos um certo ambiente e algumas ferramentas instaladas em nossos computadores. Tudo o que você precisará para acessar e executar os exemplos e instalar os pacotes é basicamente:

- Um navegador de sua escolha;

- Uma IDE ou editor de texto (os projetos serão realizados no Visual Studio Code: https://code.visualstudio.com/);

- O NodeJS (https://nodejs.org/) para executar os códigos necessários e o NPM (https://www.npmjs.com/) para instalar os pacotes e dependências utilizadas, assim como um conhecimento básico dessas duas ferramentas;

- Conhecimento básico de utilização de terminais;

- Conhecimento básico sobre Git (https://git-scm.com/) e versionamento, apenas porque os trechos de códigos serão disponibilizados por meio do GitHub (https://javascriptassertivo.com.br/) e, embora possam ser baixados como ZIP, trabalhar com os repositórios deixará os projetos mais reais.

Embora o livro aborde JavaScript, o foco será o desenvolvimento de testes e não as funcionalidades da linguagem por si só.

Sobre o projeto e as aplicações desenvolvidas

Realizaremos os testes em cima de um grande projeto com um objetivo único: permitir operações de CRUD (ou seja, criar, ler, atualizar e deletar) para usuários em um arquivo simulando uma base de dados.

Além disso, ao longo dos capítulos, trabalharemos com várias camadas diferentes de aplicações, para que possamos abordar diversas peculiaridades e aspectos dos mais variados tipos de testes.

Inicialmente começaremos os testes por uma aplicação que só é executada através de linha de comando (mais conhecida como CLI). Colocaremos em prática e aprenderemos de forma sólida vários conceitos de testes unitários testando essa ferramenta.

Após isso, vamos desenvolver os testes de uma aplicação back-end utilizando Node e Express que expõe uma API para justamente aplicar as operações de CRUD da CLI, que foi citada anteriormente. Nesta etapa, realizaremos os testes unitários e integrados dessa camada da aplicação e finalizaremos com alguns testes de carga.

Depois, vamos focar nos testes da nossa aplicação front-end, que será responsável por entregar uma interface de usuário que se comunicará com a aplicação back-end desenvolvida anteriormente. Testaremos alguns códigos genéricos de navegadores e também especificidades de um framework muito utilizado hoje em dia, o React. Também realizaremos testes unitários e de integração e finalizaremos aplicando os testes de regressão visual em nossos componentes de interface.

Por fim, mas não menos importante, realizaremos nosso teste de ponta a ponta (ou end-to-end/e2e), onde vamos simular um usuário utilizando um navegador, que vai interagir com nossa aplicação front-end e simular um fluxo completo, conforme o esperado.

Como nosso objetivo é aprender e fundamentar exclusivamente os testes, não focaremos na construção das aplicações em si, apenas passaremos pelas partes necessárias para que elas funcionem e também pelas configurações de testes de cada projeto. Claro que, conforme vamos progredindo e desenvolvendo esses testes, conheceremos as aplicações e entenderemos as responsabilidades de cada pedaço delas para que possamos realizar os testes de forma clara, sempre mantendo estes como nosso objetivo principal.

Prefácio por Willian Justen

Toda operação é sujeita a falhas, desde a criação de uma aplicação web até uma fábrica de criação de peças para carros. E essas falhas podem custar desde algumas dezenas de milhares de reais até milhões! Na programação, nós demos o apelido carinhoso de "bug" para essas falhas. E assim como a área de desenvolvimento é bem diversa, esses erros também podem ser, e serão, bem diferentes, seja um botão que não executa nenhuma ação ao ser clicado ou um relatório gerado com valores errados, causando uma completa confusão para os seus clientes.

Alguns dados interessantes para entendermos as dimensões dos problemas que bugs podem causar:

- Em outubro de 2018 e março de 2019 aconteceram dois acidentes fatais envolvendo o modelo de avião Boeing 737 Max. Depois de uma extensa análise, foi descoberto que ambos os acidentes foram causados por uma falha em um software chamado Mcas, que impediu que os pilotos pudessem alterar o ângulo de inclinação da aeronave.

- Entre 2018 e 2019, a Nissan precisou fazer um recall de mais de 1 milhão de carros, pois o software da câmera de ré não resetava as configurações toda vez que o usuário iniciava a ré.

- Em outubro de 1999, uma nave espacial da NASA estimada em 125 milhões de dólares foi perdida no espaço devido a um erro de conversão de dados! O software utilizou os dados com o sistema de medidas americano em vez do sistema métrico, deixando a espaçonave fora de órbita.

Você talvez esteja pensando: "Mas por que isso me importa? Eu não trabalho na NASA!". Mas todos esses dados foram apresentados apenas para mostrar como falhas em software podem causar enormes danos. E não, essas coisas não acontecem somente em empresas enormes, mas até no e-commerce do Seu Zé da papelaria da esquina.

Pensando nessas falhas, nós precisamos estar preparados para eliminá-las antes mesmo de chegarem ao usuário final. Sendo assim, a melhor forma é testar sua aplicação e testar bastante. O problema é que testar todas as possibilidades nos toma tempo e, quanto maior a aplicação vai ficando, mais coisas podem ficar para trás e, assim, mais falhas podem ir aparecendo sem que nós possamos perceber. Outro grande problema do teste manual é que nós humanos também somos muito suscetíveis a falhas, ou seja, além das possíveis falhas de software, teremos que somar as falhas humanas.

Diante dessas dificuldades e problemas é que nasceram os testes automatizados de software, que são códigos testando outros códigos. Parece ser muito complicada essa metalinguagem e é um pouco difícil de se entender os conceitos mesmo, mas não se sinta mal se algumas coisas não se encaixarem automaticamente na sua cabeça. O que posso dizer seguramente é que este livro ajudará muito nos seus primeiros passos com os testes e, mesmo que você já tenha escrito testes antes, este livro vai ajudar você a escrevê-los melhor e a ter uma visão mais ampla em diferentes situações.

Eu estou na área há muitos anos e tenho orgulho de dizer que fui um dos primeiros a falar mais sobre testes de software no Brasil, principalmente na área de front-end, tendo já escrito sobre o assunto no meu blog, palestrado sobre o tema em diversos eventos e criado um dos poucos cursos de JavaScript focado em testes desde o início. Recebi com muita alegria o convite do Gabriel para escrever este prefácio, pois, além de ser sobre um tema que amo, já sabia de antemão que seria um livro rico em detalhes e muito bem escrito, como tudo o que ele se dispõe a fazer. Mas posso dizer que ele superou minhas expectativas e espero que surpreenda você também.

Durante a leitura, você vai aprender que existem diferentes tipos de testes, desde os que testam pequenos pedaços da aplicação, conhecidos como testes unitários, até testes que juntam diferentes pedaços do software e analisam se eles continuam funcionando em harmonia, que são os testes de integração. Além desses, você também verá alguns não tão falados, mas não menos importantes, como os testes de carga. E não se engane, apesar de técnico, o livro também abre espaço para a prática, onde cada assunto discutido é acompanhado da criação de pequenas e diferentes aplicações, permitindo que você experimente e aprenda praticando junto do livro.

Tenha uma boa leitura e que suas próximas aplicações sejam mais seguras, confiáveis e com a qualidade que só os testes automatizados podem nos dar!

Sobre o autor

Gabriel Ramos é pintor de pixel, ou desenvolvedor, como algumas pessoas preferem chamar, mentor na Laboratória e instrutor na Caelum.

Já passou por empresas de diversos tamanhos e segmentos: de e-commerces e companhias mais consolidadas a startups unicórnios com produtos emergentes. Na grande maioria das experiências, teve contato com tudo o que envolve o ecossistema JavaScript, desde aplicações front-end a ferramentas e back-end em NodeJS.

Hoje possui uma graduação mais tradicional, mas trabalhou por anos sem uma formação superior e, embora acredite que bases acadêmicas conseguem suprir algumas deficiências de conhecimentos computacionais (principalmente teóricas), é um forte defensor das diversas formas de aprendizagem e tem como princípio que o estudo, acima de tudo, deve ser encorajado, independente de sua forma.

Mantém um blog pessoal https://gabrieluizramos.com.br/ no qual fala sobre diversos assuntos de tecnologia e, fora isso, também é apaixonado por fotografia, hobby que mantém com muito carinho disponibilizando suas fotos para uso gratuitamente.

Sumário

  • Parte 1: Fundamentos de testes
  • 1 Uma conversa (nem tão) séria sobre testes
    • 1.1 Alguns dos (vários) motivos pelos quais você deveria fazer testes
    • 1.2 Como você testa suas aplicações?
    • 1.3 A famosa pirâmide de testes
    • 1.4 Esses detalhes são apenas conceitos
  • 2 Análise estática de código com ESLint
    • 2.1 Um passo para trás, dois passos para frente
    • 2.2 Instalação
    • 2.3 Configuração
    • 2.4 Arquivo de configuração, regras e plugins
    • 2.5 Alguns passos extras com análise estática
  • 3 Simulando um framework de testes
    • 3.1 O que é, do que se alimentam e como se executam testes?
    • 3.2 Criando novas abstrações e iniciando nosso miniframework
    • 3.3 Conhecendo asserções ao criar novos utilitários
    • 3.4 Trabalhando com assert nativo no NodeJS
  • 4 Diga olá ao Jest!
    • 4.1 Instalação e primeiros passos
    • 4.2 Configurações iniciais e conhecendo a CLI
    • 4.3 Primeiro teste
    • 4.4 Executando tarefas repetitivas com Hooks
    • 4.5 Como ler o relatório de testes
    • 4.6 Cobertura e a corrida pelo 100%
    • 4.7 Indo além nas configurações
  • Parte 2: Aplicando testes unitários em uma CLI
  • 5 Testando código síncrono
    • 5.1 Como criar uma CLI em NodeJS
    • 5.2 Estrutura do projeto, instalação e configuração
    • 5.3 Mão na massa: testando os utilitários de logging
    • 5.4 Testando o utilitário de argumentos
  • 6 Testando código assíncrono
    • 6.1 Hora das funções assíncronas: testando a camada que salva os dados
    • 6.2 Um pouco mais de assincronia: garantindo cenários de falha
    • 6.3 Lembrete importante quando trabalhamos com testes assíncronos
  • 7 Ajustando configurações e testando middlewares
    • 7.1 Facilitando acesso aos arquivos do projeto
    • 7.2 Entendendo cadeia de responsabilidades ao testar middlewares
  • Parte 3: Testando aplicações back-end
  • 8 Testes unitários com Node e Express
    • 8.1 Estrutura do projeto, instalação e configuração
    • 8.2 Ajustando a configuração inicial
    • 8.3 Testando controller de Autenticação
    • 8.4 Aplicando factories para a criação dos objetos dos testes
    • 8.5 Testando middlewares
    • 8.6 Testando services
    • 8.7 Próxima parada: integração
  • 9 Testes de integração na API de usuários
    • 9.1 Configurações iniciais e factory para cliente HTTP
    • 9.2 Testando as rotas da API
    • 9.3 Testando endpoint de login
    • 9.4 Próxima parada: testes de carga
  • 10 Testes de carga
    • 10.1 Configurando o Artillery
    • 10.2 Executando os testes de carga
    • 10.3 Cansei de testar APIs, não vamos ter nada visual?
  • Parte 4: Testando aplicações front-end
  • 11 Testes unitários nos componentes da aplicação
    • 11.1 Estrutura do projeto, instalação e configuração
    • 11.2 Testando componentes puramente visuais
    • 11.3 Testando utilitários de clientes
    • 11.4 Testando estado global
    • 11.5 Próxima parada: testes de integração no front-end
  • 12 Testes de integração nas telas da aplicação
    • 12.1 Testando a página de Dashboard
    • 12.2 Próxima parada: testes de regressão visual
  • 13 Testes de regressão visual
    • 13.1 O que são testes de regressão
    • 13.2 Conhecendo o Loki e executando os testes
    • 13.3 Grand Finale: hora de testar o funcionamento completo de nosso software
  • Parte 5: Testando de ponta a ponta
  • 14 Testes de ponta a ponta (end-to-end)
    • 14.1 Como funciona um teste E2E
    • 14.2 Conhecendo o Cypress
    • 14.3 Criando um teste inicial
    • 14.4 Criando alguns comandos com a API do Cypress
    • 14.5 Testando o cenário de login
    • 14.6 Testando as funcionalidades de dashboard
    • 14.7 Terminamos nossa jornada, mas o assunto não para por aqui
  • Part 6: Extras e conteúdos relevantes após a nossa jornada
  • 15 Próximos passos nessa jornada
    • 15.1 Ferramentas adicionais e referências
    • 15.2 Você já ouviu falar em TDD, BDD e DDD?
    • 15.3 Comentários sobre decisões e tópicos que não foram o nosso foco
    • 15.4 Obrigado por tudo e até breve
  • 16 Glossário

Dados do produto

Número de páginas:
366
ISBN:
978-65-86110-84-5
Data publicação:
10/2021

Compartilhe!

Compartilhe no Facebook Compartilhe no Twitter

*Você terá acesso às futuras atualizações do livro.