Alura > Cursos de Programação > Cursos de Python > Conteúdos de Python > Primeiras aulas do curso Django REST Framework: trabalhando com testes unitários e de integração

Django REST Framework: trabalhando com testes unitários e de integração

Conhecendo os tipos de teste - Apresentação

Olá, boas-vindas a este curso de Django Rest Framework, com a Laís Urano, instrutora na Escola de Programação da Alura.

Audiodescrição: Laís se considera uma mulher parda, de olhos e cabelos castanhos, cacheados, que veste uma camisa marrom e está nos estúdios da Alura. Ao fundo, há uma estante com objetos diversos e uma parede iluminada com luzes na coloração verde e azul.

Para quem é este curso?

Este conteúdo é para você que deseja aprimorar seus conhecimentos na criação de APIs com o Django Rest Framework e realizar testes em Python.

É necessário ter conhecimento em Python e também no framework Django. Além disso, este curso é uma continuação direta dos três cursos da formação de Django Rest Framework, portanto, aconselhamos que você se familiarize com o projeto.

O que vamos aprender?

Vamos aprender a testar sua API e identificar os tipos de teste. Faremos um script de teste para modelo, serializer, autenticação e também testaremos as requisições HTTP. Além disso, vamos aprender como trabalhar com o protótipo do banco de dados do nosso ambiente de teste e veremos tudo isso em um projeto de uma API de escola. Vamos lá?

Conhecendo os tipos de teste - Tipos de testes

Nos cursos anteriores desta formação, desenvolvemos uma API de uma escola que incluía os modelos de curso, estudante e matrículas. Durante todo esse processo, adicionamos pontos importantes, como:

Também trabalhamos com o front-end e o deploy. Durante esse processo, tivemos que realizar alguns testes na nossa API. Como temos autenticação, no momento que iniciamos o nosso servidor e entramos na nossa rota, temos que receber uma mensagem de alerta, solicitando o nome de usuário e a senha.

Se cancelarmos, recebemos a informação de que as credenciais de autenticação não foram fornecidas, portanto, não temos acesso à nossa API.

Se, por acaso, acessarmos, podemos lidar com algumas limitações e validações da nossa API. Por exemplo, se acessarmos a rota de estudantes e enviarmos um POST com vários dados aleatórios para nome, e-mail, CPF, data de nascimento e celular, receberemos um unbadged request (requisição não sucedida), que mostra a primeira validação, na ordem de validações, que está incorreta.

Os testes manuais

Em todo esse processo, estamos realizando testes, e mais especificamente, realizamos testes manuais, em que estamos trabalhando e desenvolvendo naquele momento.

Esse tipo de teste é executado por seres humanos. Podemos verificar um cenário real, simulando digitar um dado errado, por exemplo, um CPF inválido.

No entanto, além de ser um trabalho repetitivo, pois toda vez que mudamos um detalhe no nosso sistema, precisamos conferir e verificar manualmente essa informação, é um trabalho que pode ter erros, pois somos seres humanos e podemos simplesmente esquecer de validar ou testar algo da nossa aplicação. E pelo fato de ser um processo repetitivo e que demanda mais tempo, tem um custo de produção mais elevado.

Os testes automatizados

Diante dessa situação, podemos trabalhar com outros tipos de teste, como o teste automatizado, que é feito pela máquina. São testes feitos por softwares que têm scripts predeterminados, que desenvolvemos e escrevemos, para indicar os cenários de teste que devem ser realizados.

Por ser um script de teste, temos a facilidade de repetir aquele script várias vezes, testar vários cenários e ter menor possibilidade de esquecer algum dos cenários de teste que precisamos testar.

Por serem mais rápidos e eficientes, e poderem ser repetidos, temos um controle e uma consistência melhor dos nossos dados e dos resultados que precisamos ter. Lembrando que esses testes podem ser realizados por diversas pessoas desenvolvedoras, ou uma pessoa responsável apenas para essa parte de testes.

A Pirâmide de Testes

Atualmente, temos diversas formas de representar os testes, e uma delas é através da pirâmide de testes, que pode variar de acordo com a pessoa desenvolvedora, empresa e equipe que está trabalhando com ela.

Uma forma bem conhecida é a que visualizamos com os testes unitários na base, os testes de integração no meio e os testes de end-to-end, ou de ponta a ponta, no topo.

Testes unitários

Os testes unitários são focados em partes individuais do nosso sistema, como funções, métodos e classes, e são testados de maneira isolada e longe de outras partes do sistema. No nosso modelo de estudante, podemos testar vários dados para a pessoa estudante, acrescentando nomes inválidos e assim por diante.

Geralmente, são testados diversos cenários de entrada para uma parte do sistema. Esses testes são mais rápidos de desenvolver e executar, e têm um custo de produção menor.

Testes de Integração

Os testes de integração verificam como diferentes componentes do sistema funcionam em conjunto. Em vez de focar em pontos individuais do sistema, é focado na integração entre esses pontos e se eles estão mostrando o resultado corretamente.

Na nossa API, só conseguimos acessar as rotas e fazer operações de GET ou POST se fizermos a autenticação, por exemplo. Esses testes apresentam um tempo de desenvolvimento e execução um pouco maior quando comparado aos testes unitários, por isso eles também apresentam um custo mais elevado.

Testes end-to-end

Os testes end-to-end verificam o fluxo do sistema completo, como se já estivéssemos com o resultado final. É o mais próximo do ambiente de produção. Na nossa API, é como se já estivéssemos com uma pessoa colaboradora da escola trabalhando com o sistema.

Por ser um teste mais avançado e com o sistema já pronto, praticamente, é um teste que apresenta um custo muito elevado e um tempo de produção, execução e desenvolvimento bem maior.

Verificando a pirâmide de teste, precisamos ter uma base sólida nos testes unitários para garantir o melhor funcionamento do nosso sistema, enquanto os testes de integração e o end-to-end já estão focando em um sistema mais desenvolvido.

É importante que desenvolvamos cada um desses pontos, para que, quando estivermos aumentando a quantidade de testes e o nível de teste, tenhamos resultados apropriados.

Além do nível de teste de mais básico para unitário e subindo de integração para end-to-end, estamos vendo também uma elevação do custo, em que o unitário é mais barato quando comparado aos outros dois, e também o nível de velocidade de desenvolvimento e execução, em que os unitários vão ser mais rápidos e os de integração e end-to-end vão perder em relação ao tempo.

Agora que entendemos sobre esses testes automatizados e também os tipos deles, podemos partir para desenvolvê-los, focando principalmente nos testes unitários e de integração. Vamos lá?

Conhecendo os tipos de teste - Testando a API no ThunderClient

Agora que compreendemos o que são testes automatizados e quais tipos podemos desenvolver, podemos começar a testar nossa aplicação.

Estamos com o Thunder client aberto no VS Code. O Thunder client é uma extensão que já utilizamos anteriormente nesta formação e será usado para testar requisições.

No caso, temos uma requisição GET para nossa rota de estudantes. Quando pressionamos "Send" para enviar a requisição, ele mostra uma mensagem de que as credenciais de autenticação não foram fornecidas. Também é mostrado um status code de 401 não autorizado. Esses são os pontos que precisamos verificar quando estamos tentando testar nossa aplicação.

Fazendo testes com o Thunder client

Na aba central da interface, temos os menus "Query", "Headers", "Auth", "Body" e "Tests". Vamos clicar na aba de Tests, que exibe outras duas abas: Tests e Scripts.

Logo abaixo, temos os possíveis testes que podemos adicionar nesta aplicação. Vamos clicar no menu suspenso "select" e adicionar o ResponseCode. A ação é que ele terá que ser igual, ou seja, equal ao valor de 401.

Vamos enviar novamente essa requisição clicando em "Send". Quando enviamos, aparece um número 1 ao lado desta aba de Results, do lado direito da interface. Clicando nele, ele mostra que os testes passaram e que, realmente, o ResponseCode foi 401.

No entanto, no cenário que estamos testando, nossa API precisa ser autenticada. Vamos clicar no menu "Auth" e inserir a nossa autenticação clicando no submenu "Basic".

Vamos digitar o usuário como "Laís" e a senha como "Laís" também, que é a que definimos. Mas você precisa colocar a senha e o usuário do seu superusuário neste momento. Vamos enviar novamente clicando em "Send".

Quando enviamos essa requisição, o teste de resultado indica que falhou e que, na verdade, o resultado foi um status de "200 OK", apontando que conseguimos fazer essa requisição.

Neste caso, vamos alterar nosso ResponseCode e colocar igual a 200 e reenviar o teste. Temos um 200 Code indicando que passou no teste.

Outros testes que podemos fazer neste momento é verificar qual é o corpo da resposta, que, neste caso, queremos que seja um JSON. Para isso, vamos selecionar "ResponseBody" no primeiro menu suspenso, "isJSON" no segundo e digitar "200" no campo "value".

Acrescentaremos também o tipo de Content Type, que vai ser equal à "application/json", que era o que estávamos solicitando. Vamos enviar essa requisição novamente. Temos a resposta de que os três testes passaram nesta situação.

No entanto, quando precisamos testar os cenários da nossa aplicação, não queremos testar apenas aqueles que vão passar e que vão dar certo.

Precisamos testar aqueles que não vão dar certo. Neste momento, deveríamos ter um ResponseCode igual a 401. Porque, se retirássemos nossa autenticação, e enviássemos o teste, ele passaria e seria aprovado.

Testamos o cenário, o corpo continuou sendo um JSON, o conteúdo também, que é a aplicação JSON, mas o Response Code 401 passou, enquanto o 200 foi reprovado.

Se fizéssemos o processo contrário, que é manter nossa aplicação autenticada e enviar, ele passa nos três primeiros testes ("200", Response Body e Content Type) passaram no teste, só que o último (Response Code) não passou. E isso não é apropriado.

Não podemos utilizar apenas esses testes para verificar nossa aplicação. Precisamos produzir um script de teste onde podemos colocar o que bem entendermos.

Aqui mesmo, no Thunder client, podemos acessar o menu "Tests > Scripting", onde podemos escrever esse código. Se voltarmos para "Tests", ele indica um link na parte inferior da interface para aprendermos mais sobre testes e scriptings para usos avançados. Vamos clicar nesta documentação para poder acessar.

Criando um código de scripting

O que precisamos observar, neste primeiro momento, é que ele informa como você pode desenvolver um código de scripting para testes utilizando o Thunderclient, só que a linguagem que eles utilizam é o JavaScript.

Nesta página de scripting, ele informa que precisamos utilizar a linguagem do JavaScript. Não queremos precisar aprender outra linguagem para introduzir scripts de teste na nossa aplicação, que é feita em Python. Precisamos escrever nossos próprios scripts.

Vamos voltar para o VS Code e, no lugar de continuar utilizando essa ferramenta que é o Thunderclient, que, inclusive, você poderia estar utilizando outras, como o Postman, que também conseguiria fazer esses testes, vamos desenvolver testes para esses cenários mais avançados.

Vamos abrir o menu "Explorer", já com a nossa aplicação aberta, vamos fechar a aba de requisição do Thunderclient e, na pasta "escola", temos um arquivo de testes em Python chamado "tests.py". Se clicarmos nele, perceberemos que ele só tem a base, que é a importação do django.test e o comentário para criar os testes.

Mas, como queremos criar vários cenários para várias possibilidades, vamos clicar no botão com o ícone de pasta chamado "New Folder", que é uma nova pasta, e essa pasta será criada dentro de "escola". Vamos dar o nome de "tests".

E, para informar que é um módulo Python, onde vamos poder acessar isso, vamos ter que criar um arquivo __init__.py, que é o que temos em todas as pastas que estamos utilizando.

Nesta pasta (escola > tests > __init__.py), vamos desenvolver os arquivos de scripts para teste. Mas, antes de fazer isso, como não estamos mais utilizando esse arquivo de testes.py, vamos apagá-lo para não dar nenhum possível conflito. E é isso, estamos prontos para desenvolver nossos testes.

Sobre o curso Django REST Framework: trabalhando com testes unitários e de integração

O curso Django REST Framework: trabalhando com testes unitários e de integração possui 119 minutos de vídeos, em um total de 38 atividades. Gostou? Conheça nossos outros cursos de Python em Programação, ou leia nossos artigos de Programação.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Python acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas