Olá! Vamos hoje aprender uma coisa muito, muito importante, fundamental computação, são os testes automatizados. E vamos ver porque é que eles são tão importantes. Por que é que a gente deve testar os programas que a gente desenvolve, o código que a gente escreve. E basicamente porque serem humanos erram. Então, quando a gente escreve código é muito comum cometermos erros porque seres humanos cometem erros, e à medida que os nossos programas vão crescendo eles vão contendo cada vez mais erros, se nós não tomamos atitudes para coibir esses erros e os testes são a melhor forma de evitar esses erros. Então, a gente vê por aí que muitas vezes os programas contém erros. Quando a gente baixa aplicativo às vezes compra programa tem erros, e a gente fica muito bravo. Nós como clientes de software ficamos muito bravos quando a gente encontra erro. Então, quando a gente desenvolve software a gente tem que fazer o máximo de esforço possível para ter software livre de erros. Os erros podem ser de sintaxe. Mas esses são erros simples que o próprio compilador interpretador detecta e quando a gente está desenvolvendo ele já mostra erro, os erros mais difíceis são aqueles erros de lógica, que o programa compila, ele executa mas só de vez quando, esse erro se manifesta e causa algum comportamento errado do programa. Então, esses erros de lógica, o que é que a gente quer pegar principalmente com os nossos testes. Então, software robusto deve conter o mínimo possível de erros e é isso que a gente deve buscar, desenvolver softwares de alta qualidade com o mínimo possível de erros. Alguns casos os bugs podem causar catástrofes. Já houve casos aí na história de foguetes que explodiram no espaço porque tinham bug num software, ou aconteceu de uma sonda chegar a Marte, pousar Marte e não funcionar direito Marte porque a coisa não deu certo. Tem outras áreas do conhecimento humano, por exemplo, o software que controla grandes usinas também tiveram bugs que causaram grandes prejuízos financeiros e muitas vezes até perdas de vidas humanas. Esses são casos raros mas extremos, onde se deve investir muito aí na qualidade do software mas, na maior parte dos casos os bugs vão causar desconforto do usuário. Algo que o usuário gostaria de fazer de jeito e aquilo não funciona, causa desconforto e pode causar até prejuízo financeiro para o usuário. Particular, se você está desenvolvendo software para vender para usuários, para vender para outra empresa, esse bugs podem fazer com que o cliente abandone seu produto, deixe de comprar da sua empresa, da sua startup. Então, a gente deve sempre buscar aí desenvolver software de qualidade e sem erros. Então, a gente quer evitar essas bombas escondidas aí no nosso software que algum momento explodem quando a gente menos espera. Então, como evitar que essas bombas existam? Com bons testes. Agora, como é que a gente deve testar? Jeito são testes manuais, não é? Você escreve o programa e depois você mesmo vai testando o programa diferentes casos ou tem algumas empresas que, trabalham de jeito mais antigo, então, tem uma equipe de desenvolvedores depois uma equipe de testadores, e testadores vão testar todo o código que os desenvolvedores fizeram. Fazer testes desta forma, de uma forma manual, é uma coisa cansativa. Você não vai ter vontade de repetir toda a bateria de testes, toda vez que tem alguma mudança no software. Você vai acabar testando apenas alguns casos porque testar na mão dá muito trabalho. E você vai testar apenas algumas vezes, você vai testar sei lá apenas uma vez por semana. Você não vai testar toda vez que alguma coisa muda num programa, e daí os erros vão ser introduzidos e você vai acabar não detectando. Então, eu diria que essa aqui não é o jeito mais moderno, mais sofisticado, mais inteligente de fazer testes. Então, se você trabalha numa empresa que usa testes manuais você tem que batalhar dentro da sua empresa para mudar isso e pensar automatizar a execução dos seus testes. Para isso, você precisa escrever testes automatizados. Ou seja, você vai escrever código que vai testar o seu código. Então, a ideia é que você deveria ter uma bateria de testes que cobre o máximo possível do seu código. Cobre no sentido de todas as linhas de código que você escreveu no seu programa Python deveriam ser testadas pela sua bateria de testes. É o primeiro objetivo que a gente busca, é cobrir todas as linhas de código, depois, tem outros objetivos mais ambiciosos ainda, por exemplo, cobrir todos os possíveis caminhos dentro do seu programa. Mas o ideal é a gente testar principalmente os casos potencialmente mais problemáticos, e a gente tem que refletir pouco sobre quais são os casos que podem dar erro e esses são os primeiros que a gente deve testar e, depois que você tem essa bateria de testes você tem que executar essa bateria de testes rotineiramente várias vezes ao dia. Enquanto você está programando, você tem aquela bateria de programa maior, 100, 200, 1000 testes e você roda aquilo toda hora, toda hora, a cada duas horas. Ou alguns casos a cada vez que você faz uma grande mudança você roda o teste lá para ver se não quebrou nenhum pedaço do seu código. Esse é o jeito que bons grupos de desenvolvimento de software trabalham, é o jeito que boas empresas, empresas sérias trabalham relação a testes. Então, automatizar, colocar as engrenagens para trabalhar ao seu favor, é isso que a gente deve buscar. Para fazer isso de uma forma mais sistemática, mais efetiva, a gente acaba usando muitas vezes arcabouço de testes automatizados que é uma ferramenta que já vem nas diferentes linguagens de programação, que nos ajudam a escrever e executar esses testes de uma forma mais fácil. Aqui, nesse nosso curso, a gente vai aprender a usar o Pytest, que é arcabouço aí de testes automatizados muto bons para o Python. Então, para vocês instalarem no computador de vocês o pytest, basta você visitar docs.pytest.org e de lá vocês vão poder baixar o software e implementar. Deixa eu abrir aqui rapidamente olha, essa aqui é a pagina do pytest, se você clicar aqui e tem install a gente consegue ver aqui os comandos que você pode usar para instalar. No meu computador usando esse easy_install aqui depois, aqui para você verificar se a versão correta foi instalada. Depois aqui tem pequeno exemplinho de código de teste que você pode executar para ver se funciona. Eu vou copiar isso aqui, vamos abrir arquivo aqui, olha vou colar aqui. Então, o que é que faz nesse nosso pequeno exemplinho aqui do pytest. Primeiro eu estou definindo uma função que chama func que ela recebe parametro x, e ela devolve x mais. Então, pronto então esse aqui é o código que eu quero testar, uma função mais simples que você conseguir imaginar e depois a gente tem método de teste. Então esse test_answer aqui o fato dele começar com a palavra test está indicando para o pytest que ele é método de teste aí. E daí, que que a gente está testando? Esse assert. Verifique se func de três é igual a cinco, ou seja, se eu chamar a função func passando três como parâmetro, se isso dá cinco. Vamos salvar isso aqui e agora eu vou executar. Para executar basta a gente dizer pytest, ou pytest e o nome do arquivo. Então, deixa eu abrir aqui, eu vou escrever py.teste e nome do arquivo é o tes_sample.py. Eu vou executar isso aqui e ele me deu, aqui deu uma mensagem de erro. Falou test answers teve failures, ele falou teve teste que falhou aqui. Esse foi o tempo que demorou para executar os testes, e o que que ele está falando? Ele está falando, onde falhou foi esse aqui, assert func de três igual a cinco poque o func de três deu quatro, não deu cinco, então o quatro igual a cinco falhou aqui. Então, não só ele diz que que deu errado, como ele diz que linha deu errado. Nesse caso específico o que estava errado não era o código da func. O func na verdade está certo, o que estava errado era o próprio nosso código de teste, porque func de três devia ser quatro, porque o que essa func faz ele soma. Então eu vou agora salvar aqui e executar novamente aqui o nosso teste. Vamos ver o que acontece. Pronto, agora ele deu certo, ele colecionou item, ou seja, executou teste desse arquivo aqui e teste passou e ele está mostrando vermelhinho para, desculpa verde, para mostrar que passou. Quando algum dos testes falha ele pinta de vermelho aqui. Quando todos os testes deram certo, nesse caso só tinha e deu certo, ele pinta de verde. Então, esse é exemplo mais simples possível de teste aí que a gente pode imaginar. Mas vamos voltar aqui. Então, esse pytest, quando a gente executa o pytest aqui na linha de comando deixa eu digitar aqui o pytest, se eu executo simplesmente o pytest sem nenhum parametro ele vai considerar, ele vai olhar para todos os arquivos alí no diretório, ele vai buscar todos os arquivos que tem o nome test sublinhado, alguma coisa ponto py. E ele vai considerar que isso aqui são arquivos de teste além disso, ele vai executar Dentro desse arquivo, as funções métodos do tipo teste underscore e que depois vem alguma coisa qualquer. E considera as, depois se a gente tiver classes de testes ali dentro, a gente vai ver isso mais para à frente, ele vai considerar classes que começam com teste asterisco, tá? Então mais informações sobre isso, vocês podem encontrar aqui nesse site, tem todas as informações sobre documentação do pytest, que eu sugiro que você depois que fizerem esses dois vídeos que eu estou explicando aqui como utilizar o pytest, que você também dê uma boa olhada ali, tá? Está, então vamos aqui fazer exemplo da função fatorial, deixa eu abrir aqui, uma nova função fatorial, vou abrir aqui novo arquivo e eu vou chamar, vamos fazer uma função fatorial, por exemplo, então vamos implementar fatorial de n e vai calcular o fatorial de n. Então inicialmente para, eu vou usar while que vai repetindo e vai multiplicando os números de 1 até n e depois devolve esse valor, eu vou guardar essa multiplicação numa variável fat, que eu vou inicializar com 1 que é o elemento neutro da multiplicação. E eu vou ter índice, que vou indo desde 1 até n, então o i eu também vou começar com 1. E daí a gente pode fazer while, e o meu while vai ser enquanto o i for menor que n, o que é que eu faço? Eu faço fat recebe fat vezes i e i recebe mais 1. E daí, quando eu termino de fazer isso, eu simplesmente dou return fat, tá? Então porque essa é a nossa função fatorial. Daí como é que a gente pode testar? Daí eu vou definir várias funções de teste, que começam com teste sublinhado e depois alguma explicação do que eu estou testando, então, por exemplo, vou testar o fatorial de 0 como é que eu testo isso? Eu faço assert que o fatorial de 0. Quanto é que tem que dar o fatorial de 0? Por definição tem que dar 1. Igual a 1, opa, igual a 1, está? Então esse aqui já é possível teste. Que outro possível teste? Fatorial de 1 também tem que dar 1, a mesma coisa, né? Daí eu posso testar por exemplo, fatorial de valor negativo. Que fatorial por exemplo, de menos 10 aí eu preciso definir o que é que eu gostaria que o programa devolvesse, né? O que eu gostaria era que não desse algo completamente errado, tipo o programa entrar num laço infinito, num looping infinito e travar, né? Mas vamos supor que eu quero que devolva 0, quando negativo, só para indicar que tem alguma coisa aí errada, né? E depois vamos testar uns outros casos de uns que ele realmente faz algum cálculo. Então por exemplo, fatorial de 4 tem que dar 24, que é 4 vezes 3 vezes 2. E o fatorial de 5 se não me engano é 120, né? 120, tá? Então já temos uma pequena bateria de testes, que testa vários casos diferentes, vamos executar aqui para ver o que acontece. Eu vou salvar isso aqui como fatorial, opa, fatorial eu vou chamar aqui, como eu já tenho teste fatorial. Normalmente a gente divide as funções num arquivo e os testes outro. Como estão os 2 aqui já misturados no mesmo, eu vou chamar isso aqui de teste fatorial, salvar e eu vou aqui executar o pytest, o meu teste fatorial. Vamos ver o que é que acontece. E deu alguns erros aqui, deu na verdade 3, está mostrando que 3 dos meus testes falharam e 2 deram certo, está? Particular esse exemplo vários aqui falharam. Então vamos ver o assert de, fatorial de esse aqui, teste fatorial 4 teria que ter dado 24, né? Mas ele deu 6, está falando que fatorial de 4 deu 6. Então, espera aí, o 6 é fatorial de 3, então ele está faltando, ele multiplicou 2 vezes 3 e não multiplicou 4, então eu estou mutiplicando número a menos, né? Se vocês olharem o teste fatorial 5, a mesma coisa, né? Ele tinha que ter dado 120, deu só 24, ele não multiplicou pelo 5, então está faltando multiplicar pelo n, pelo próprio número n aqui. Então, vamos ver, eu acho que eu, olhando aqui, como eu fiz while i menor que n, o i estritamente menor que n, ele não está executando quando o i fica valendo n, então ele não está multiplicando pelo n si, então, vou ter que fazer, while i menor ou igual a n, está? Então a bateria de testes me achou a encontrar casos que não estava funcionando e portanto, eu pude ir lá e consertar o caso. Então, acho que eu consertei, vamos ver, vamos executar novamente aqui, salvei ali, executar novamente aqui. Melhorou, só 1 deu errado, 4 deram certo e 1 deu errado. Ele está pintando de vermelho porque 1 ainda deu errado. Qual é que deu errado? Exatamente o fatorial de menos 10 que tinha que ter dado 0, eu realmente não tinha implementado esse aspecto do fatorial de número negativo, ter que devolver alguma coisa que faça sentido, né? Então, a gente pode começar fazendo algo do tipo, if n menor que 0, return 0 então qualquer número negativo, ele vai devolver 0 ali para indicar que não faz sentido essa conta do fatorial do número negativo. Então, vamos ver se dá certo agora, executar novamente. Pronto, agora deu que os meus 5 testes passaram, está? Então essa aqui é uma forma de a gente começar a escrever uma pequena bateria de testes, para testar que a nossa função está funcionando e é o que a gente vai fazer bastante aí ao longo desse curso, nos trabalhos que vocês fizerem é sempre muito saudável você escrever uma bateria de testes, está? Resumindo mais uma vez então, o que você deve fazer quando você escreve o seu programa é pensar cuidadosamente nos casos que o seu programa pode falhar, e daí, você vai escrever testes para esse caso que o programa pode falhar. Então você tem que pensar nos diferentes tipos de entrada que exercitam caminhos diferentes dentro do seu programa, e você vai escrever testes para esses diferentes tipos de entrada. Você tem que pensar nos casos diferentes do seu código, escrever testes para esses casos diferentes e todos os casos, testes automatizados, tá? Então não tem nada daquilo de ficar testando na mão, se você tem alguma dúvida se o programa funciona determinado caso, vai lá e escreve teste automatizado para testar aquele caso. Se você está usando o seu programa e descobre erro, bug no programa, usuário seu descobre bug no seu programa, você não vai lá e conserta o bug, você primeiro escreve teste automatizado que vai expôr aquele bug e daí sim você vai consertar o bug. Porque dessa forma, naquela na sua bateria de testes, vai ter aquele bug, uma proteção contra aquele bug apareça novamente no futuro. Está? Então é isso, testar, testar, testar. [MÚSICA] [MÚSICA] [MÚSICA] [MÚSICA]