Primeiras aulas do curso Testes em Python: trabalhando com dublês de testes

Testes em Python: trabalhando com dublês de testes

Para quê dublês de testes - Introdução

Olá, sou Roberta Takenaka, instrutora do curso “Dublês de Testes com Python”.

Neste curso nós vamos trabalhar com um projeto chamado “Coleção”, que nós vamos obter dados de livros da internet e vamos armazená-los no banco de dados.

Nós vamos fazer isso em etapas. Primeiro nós vamos baixar os dados e colocar em arquivos, no sistema de arquivos e depois nós vamos carregá-los no banco de dados.

Em cada uma dessas etapas, nós podemos ter alguns problemas: aplicação, ter que lidar com problemas de acesso a internet, seja porque nós estamos off-line ou porque o serviço ficou fora do ar.

Nós podemos ter problemas também com os arquivos de permissão, de problemas de escrita, de leitura e também a mesma coisa pode acontecer com operações de banco de dados, então nós temos que lidar com esses tipos de coisas nas aplicações.

Então, nos testes nós temos que simular essas situações para que a nossa aplicação seja robusta, então como que nós fazemos isso? Nós usamos os dublês de testes para simular as operações reais, os objetos reais, e então causar essas situações de falta de internet ou problemas de permissão, de escrita, de leitura e tudo mais.

Então, o que são esses dublês? Eles são esses substitutos. Quais são os tipos de dublês que nós temos? O Dummy, Stub, Spy, Mock e Fake. Eu vou explicar tudo isso.

E quando usar? Então, cada um destes tipos vai simular alguma condição e eles vão nos ajudar a fazer os testes, então temos horas que nós vamos precisar de um fornecedor de entradas indiretas, um que vai ser o capturador de saídas indiretas, um que vai ser programado para ter um comportamento esperado e outro que é a implementação alternativa e simplificada.

E nós também vamos ver quais são os cuidados ao usar os dublês, então vamos começar?

Para quê dublês de testes - -TDD-

Aqui eu criei esse arquivo “setup”, que é só para dizer para ele qual que é o nome do meu projeto e onde estão os pacotes que pertencem a esse projeto. Só isso.

E aqui nós vamos começar a criar duas pastas: uma que eu vou dar o nome de “colecao” e a outra: “testes”.

Deixe-me explicar mais aqui, então eu tenho a pasta do meu projeto, dentro do meu projeto eu vou ter “colecao”, dentro de coleção eu vou criar o modo “livros.py” e dentro de “tests” eu vou criar um módulo chamado “test_livros.py” eu vou ter aquele “setup.py” que eu já mostrei antes.

ntão aqui na pasta “tests”, vamos criar “test_livros.py” e em “colecao” “livros.py”, então eu vou começar por “tests”.

Outra coisa: nós vamos usar nesse projeto, um framework de teste chamado Pytests, o que é interessante desse Pytest é que se você por exemplo - conhece já Unittest - o Pytest também consegue interpretar os seus testes com o Unittest, então eu achei que seria interessante nós também vermos o Pytest.

Então aqui eu vou começar com o meu primeiro teste, que chama “test”.

Então o que eu quero fazer? Eu quero consultar essa [PI] e verificar o retorno dele, então: “def test_consultar_livros_retorna_resultado_formato_string() :” - então o que que eu quero ver? Quando nós estamos fazendo teste, nós queremos fazer o seguinte: nós queremos verificar o resultado do que eu executei e ver se é igual ao que eu estou esperando.

Então o que que é o esperado? Eu disse que o esperado para mim é que ele seja do formato string e o resultado - o que é o resultado? É o “resultado = consultar livros()”.

Vamos por um livro aqui, da autora: “Agatha Christie”. Eu disse que na verdade eu quero comparar o tipo do resultado, que ele seja string.

Então vamos ver aqui o que acontece se eu rodar esse teste, muito bem, nós tivemos um erro - que era o que estava esperado - e o que que ele diz aqui? “consultar_livros” não está definido. “consultar_livros” não está definido porque eu não fiz a importação dele.

Onde “consultar_livros” deveria estar? Dentro de “colecao”, que é aquela pasta que eu criei, e deveria estar dentro do módulo “livros.py”, então eu vou fazer assim: “from colecao.livros import (consultar_livros”.

Então eu volto a executar meus testes. Agora tive outro erro, então vamos ler aqui, o que tem nesse erro. Não foi possível importar consultar “livros” - então por quê? Nós não definimos “consultar_livros” dentro de “livros.py”. “livros.py” esta vazio, então vamos criar aqui “consultar_livros”.

Vamos executar de novo. Outra mensagem: objeto não é “callable”. O que é? Não é executável, por quê? Eu não defini ele aqui, como se fosse uma função. Eu defini ele aqui, como se fosse uma variável qualquer, então vamos converter ele para função.

E aqui, é o menor jeito de descrever uma função. Vou mandar de novo, não salvou. O que acontece? Eu passei um parâmetro, só que quando eu construí a função “consultar_livros”, estava sem parâmetro, então tenho que colocar parâmetro. Muito bem, vou rodar de novo. Evoluímos mais um pouco.

Então o aqui ele está falando assim: o retorno que foi do resultado, ele está diferente do que eu disse que seria a string, por quê? Ali eu também não retornei nada, quando não retorno nada o padrão é ”None”, então vamos retornar alguma coisa.

Agora ele passou. Passou, mas nós sabemos que a função “consultar_livros” ainda não está completa.

Mas o que nós vimos aqui? Quando nós fazemos “TDD” - que nós fazemos o teste primeiro e vamos arrumando o nosso programa - nós temos que lidar com algumas mensagens e nós temos que entender quais são essas mensagens, para nós conseguirmos ir ajustando nosso programa conforme os testes.

Então era isso que eu queria mostrar para vocês. Agora na sequência nós vamos completar “consultar_livros”.

Para quê dublês de testes - Projetando Consultar Livros

Como seria o conteúdo de “consultar_livros”? Então vamos imaginar que eu tenho o autor. Vou passar para o “consultar_livros”, o autor, titulo e texto livre e como resultado, eu quero o resultado em formato string. Como que eu chego nisso?

Então, nós sabemos que em algum momento nós vamos ter que fazer a requisição à internet com esses parâmetros. Passando autor, título e texto livre.

Então, qual seriam os componentes deste “consultar_livros”? Então, que tal: “preparar_dados_para_requisicao” - onde nós recebemos autor, título e o texto livre e nós convertemos para um dicionário, onde esse dicionário vai fazer parte da requisição “https”, e eu vou ter, obviamente, qual URL que eu vou acessar.

Então somando essas duas coisas, que é o “https://buscarlivros” - que seria a URL - mais os dados que eu vou passar de autor, título ou texto livre.

Então eu vou ter a URL - realmente aquela que nós vamos acessar para obter os dados - e então eu vou fazer a requisição para o site para obter os resultados, então é esse passo a passo que nós vamos fazer!

Uma outra função de nós termos os dublês de teste, é também para quando não temos algum trecho do nosso código pronto, então vamos ver como é isso.

Então eu vou fazer um “test” aqui, que eu vou dizer assim: “def test_consultar-livros” - é aquela primeira função. Nós vimos que nós vamos ter dentro de “consultar_livros” chamada para três funções, que é preparar os dados, obter a URL e por fim fazer a requisição.

Então eu vou fazer um teste aqui, que eu quero dizer assim: “def test_consultar_livros_chama_preparar_dados_para_requisicao_uma_vez_e_com_os_mesmos_parametros_de_consultar_livros():”.

Então aqui, quer dizer que eu vou chamar “consultar_livros” - por exemplo: “("Agatha Christie")” e “preparar_dados_para_requisicao” - porque esse parâmetro tem que ser o mesmo que esse quando eu fizer a chamada.

E aqui eu vou usar um dublê para o “preparar_dados_para_a_requisicao”, então o que que eu escrevi aqui, “preparar_dados_para_requisicao” vai ser um atributo no meu módulo “livros.py”, que está dentro de coleção.

Então, o que que acontece aqui? O que eu estou dizendo? Que quando eu chamar “consultar_livros” - o “preparar_dados_para_requisicao” é um dublê - vou substituir ele por um dublê porque “preparar_dados_de_requisicao” nem existe ainda e eu vou dizer: “assert_called_once_with” - com esse parâmetro aqui.

Então de novo, eu vou dizer que o “preparar_dados_de_requisicao” vai ser substituído por um dublê e quando eu executar o “consultar_livros”, eu estou testando aqui se ele vai ser chamado com o mesmo dado que eu passei em “consultar_livros”, então vamos ver como fica isso.

Aqui ele diz que o “patch” não está definido. Vamos lá! Esse “patch” aqui ele faz parte da biblioteca do “unitest” – ou melhor, da biblioteca de “unitest.mock”, então eu vou fazer isso. O que esse patch faz? Justamente, ele diz para mim que eu vou substituir esse “preparar_dados_de_requisicao” por um dublê. É isso que ele está me dizendo e é isso que ele faz.

Então vamos executar o teste de novo. Escrevi errado “unittest”, faltou uma tecla “t” a mais aqui.

O que ele me disse aqui? Que “colecao_llivros” não tem o atributo “preparar_dados_de_requisicao”, então vamos criar no “livros.py” e vamos criar: “def prepara_dados_para_requisicao():”. Vamos lá!

Então, o que que ele está falando aqui? Esperado e chamar uma vez. Ele foi chamado nenhuma vez, zero vezes. De fato, nós não chamamos “preparar_dados_para_requisicao” ali.

Então agora eu coloquei “preparar_dados_para_requisicao”, chamei ele dentro de “consultar_livros” e vamos executar aqui de novo. Aqui ele diz esperado, “preparar_dados_de_requisicao('Agatha Christie')”.

O que foi o real? “preparar_dados_para_requisicao”, então o que que esta faltando nós colocarmos? Escrever o autor ali.

Então esse parâmetro aqui, eu passei para “preparar_dados_para_requisicao”. Vamos executar de novo: “preparar_dados_para_requisicao” - leva uma posição “0”, mas um foi passado.

O que acontece? Quando nós fizemos “preparar_dados_para_requisicao”, nós não passamos nenhum parâmetro, então vamos acrescentar um parâmetro aqui e assim vai. Agora ele passou!

Então, o que nós aprendemos agora? Quando nós estamos aqui nos “tests_livros.py” e usarmos um dublê - vou diminuir aqui um pouquinho só para vocês conseguirem ver - tem o teste aqui e eu consegui usar um dublê para fazer com que ele tomasse o lugar de um código que ainda nem existia.

Vou aumentar aqui, então é mais uma funcionalidade, mais um uso de dublês de testes.

Sobre o curso Testes em Python: trabalhando com dublês de testes

O curso Testes em Python: trabalhando com dublês de testes possui 276 minutos de vídeos, em um total de 60 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!

  • 1241 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

Premium

  • 1241 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$75
à vista R$900
Matricule-se

Premium Plus

  • 1241 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$100
à vista R$1.200
Matricule-se

Max

  • 1241 cursos

    Cursos de programação, UX, agilidade, data science, transformação digital, mobile, front-end, marketing e infra.

  • Certificado de participação

    Certificado de que assistiu o curso e finalizou as atividades

  • App para Android e iPhone/iPad

    Estude até mesmo offline através das nossas apps Android e iOS em smartphones e tablets

  • Projeto avaliado pelos instrutores

    Projeto práticos para entrega e avaliação dos professores da Alura com certificado de aprovação diferenciado

  • Acesso à Alura Start

    Cursos de introdução a tecnologia através de games, apps e ciência

  • Acesso à Alura Língua

    Reforço online de inglês e espanhol para aprimorar seu conhecimento

12X
R$120
à vista R$1.440
Matricule-se
Procurando planos para empresas?

Acesso por 1 ano

Estude 24h/dia onde e quando quiser

Novos cursos todas as semanas