Рубрики
Без рубрики

Яички Em Python – Parte 1: Internução

Essa é A Primeira Parte Da Série de яичковы Em Python. Primeira parte tem por objetivo fazer uma i … Tagged с Python, яички, Iniante, Womenintech.

Essa é A Primeira Parte Da Série de яичковы Em Python.

Primeira parte tem por objetivo fazer uma inventução a atomatizados utilizando o framework nativo do python без блужданий. Aqui, Veremos alguns canceitos primordiais para escrever OS Primeiros Casos de Teste.

PRé-requisito

  • Conhecimento básico de python

Ротиро

  1. O Que Sheantes яички
  2. Teste Unitário (de Unidade)
  3. Тщеславие
  4. Пример
  5. Учитывает Адиционайс
  6. Заключение

1. O Que Sheantes яички

1.1 Motivação

Ao Escrever Nossos Programas, Precisamos validar se o resuldado que ele produz é o Correto Анкет

SE Tratando Dos Primeiros Programas Que Escrevemos, Normalmente Rodamos O Nosso Código e Passamos Diversos Valores Para Verifificar Se O Que ele retorna é o esperado. Quando Isso não acontece, Temos Que Fazer Uma Varredura Pelo Nosso Código E Tentar Condender Ocorreu. Pode Ter Sido Exibido Algum erro ou exceção ao usuário OU O Programa RETORNAR O Valor Errado E NãAO Exibir Erro nenhum (Ocasionado Por Erro de Lógica na Maioria das Vezes). Nos dois casos, podemos usar o MODO DEBUG (que são arvilitados por uma ide¹) ou adicionar alguns выходы Нет терминала USANDO A Funcáo Распечатать. Com Isso, Podemos Identificar o Проблема e corrigir nosso código para retornar o que éperado. Isso é Um Teste Manual.

IDE¹ (Интегрированная среда разработки) Do Português abmiente Integrado de desenvolvimento. Ammbiente que nos ajuda a desenvolver nossos códigos sendo possity não só utilizar como editor de texto, mas também facilitar execução, debbug e Integração com uptras ferramentas. Em python, o Pycharm é Uma Ide Muito utilizada e difundida.

REPARE QUE ISSO SE TORNA EXTREMAMETE CANSATIVO E ESTá Sujeito A Falhas Fazer Validações Dessa Forma. Ассим, Нена Гарантимос Qualidade Do Nosso Programa de forma Farma Farcytada se mais funcionalidades forem adicionadas pois todas в качестве Vezes teríamos Que Executor Nosso Programa e arvificar os cenários na mãa.

1.2 Яички Automatizados

Яички Automatizados SãAO Cenários Que Escrevemos Através de Linha de Código Simulando OS яичны Manuais que antes eram feitos. Poupando Assim tepo e esforço nessas verificaçes.

ESCREVER ATOMATIZADOS VAI MUITO ALém Do QUE SOMENTE ESCREVER CENários Para Validar Que O Código FoCa O Que Deveria Fazer. O teste também nos ajuda a:

  • Deixar O Código Mais Limpo (Ajuda na remoção de код запах )
  • Garantir Maior Manutenção do código
  • Servir Como Documentação: de forma Visual Conseguimos Sabre Quais são os cenários esperados e os tratamentos em caso de erro olhando o arquivo de teste
  • Evitar Trabalho Manual (Um Teste Automatizado é Muito melhor do Que um teste Руководство com print
  • Evitar Bug’s
  • ПРОВАНСКАЯ ОБРАТА ПАРА ESTá Desenvolvendo A Aplicação: Conseguimos Sabre Se O Programa Está retornAndo O Que Esperado Mesmo Alterando A Lógica do Programa Pringsal.

2. Teste Unitário

Um teste unitário é a maneira de você testar в роли Pequenas unidades, существующих Em seu código. Тамбем де -Чамадо де -Тесте де Унидад.

Para nos ajudar com os яички, Iremos utilizar o Framework встроенный (Nativo) Do Python Chamado Unittest Анкет

Пример 1:

from unittest import main, TestCase

def square(x):
    return x ** 2

class TestSquare(TestCase):
    def test_if_returns_square_of_2(self):
        result = square(2)
        expected = 4

        self.assertEqual(result, expected)

if __name__ == '__main__':
    main()

No Exemplo Acima, Estamos testando uma pequena unidade do nosso código, estamos validando um cenário da funcáo chamada квадрат Анкет

REPARE QUE TODO O Contexto de teste está sendo utilizado dentro de uma Классе .

MAS, Para Contender Melhor Como Funciona O Exemplo Acima, Vamos Primeiro Contender Alguns Canceitos.

3. Тщеславие

3.1 Preparação do teste

Nessa etapa é feita a Preparação do ambiente para fazer o teste rodar. Essa Preparação é Chamada de приспособление e Согласно nos itens reciance para um ou mais atings serem executos.

  • Пример: para conseguir testar uma funcão que le um deginado arquivo precisamos de um arquivo no nosso ambiente de teste para ser ospertavel fazer Validação

Pode Conter O USO DOS Métodos setup () e teardown () Анкет Isso SãAO ACõES QUE SEAO EXERTADAS ANTES E DEPOIS, COSASIVAMETE, DA EXERCUCAO DE CADA UM DOS CENários de Teste.

3.2 Caso de Teste

É o concunto de cenários Que Queremos testar. Em um caso de teste agrupamos todos os pequenos cenários que queremos validar de forma unitária que fazem parte do mesmo contexto.

Com O Framework Unittest, Usamos Uma Classe Base Chamada Testcase Анкет

3.3 Asserções

Asserções Servem para validar que o cenário do seu código ocorreu como o esperado.

O утверждение é Um Comando встроенный (Nativo) Do Python. E Podemos usar da seguinte forma:

REPARE QUE NA PRIMEIRA ASSERção é Comparradada Se A Soma de 1+1 é Igual a 2. Como o resultado é verdadeiro, nada é exibido no console.

Já na asserção seguinte, há uma falha e um erro é levantado do tipo AssertionError (Erro de Asserção).

O Структура Unittest FARITICA NESSAS ASSERções QUE VAMOS PRECESAR FAZER. Как Asserções opplas Podem Ser Vistas em Sua Propria Documentação Анкет

3.4 Тестовый бегун

Permite Rodar A Execução DOS яички. O Test Runner Orquestra A Execução DOS яичники E Asibe para o usuário os resultados.

Алем де Иулизар о Тестовый бегун Do Unittest Outros Podem ser utilizados como o pytest Анкет

3.5 покрытие

Покрытие Пометьте Cobertura de Testes, Ou Seja, O Quanto O Seu Código Está Sendo Testado.

Executando o освещение, Conseguimos Sabre Quais trechos de Código foram testados e Quais não foram.

Atenção: 100% de cobertura é deferente de ter todos os cenários testados! Alem de testar O Fluxo Pricnal Do Programa Também precisamos testar casos inesperados (Veremos mais adiante na série “em python”).

3,6 макет

Макет é UMA Biblioteca utilizada em яичковывает Quando Queremos simular um detrinado comportamento. Измешивайте Em Inglês é Literalmente “Imitar”. Ele é bastante utilizado quando nosso código se comunica com elementos externos como por exemplo: conexáo com o banco de dados e Chamadas http.

SE Não для Utilizado o Mock, без Que Que Arecearmos nosso código Chamadas reais irão acontecer para a red ou banco de dados, por exemplo (Veremos mais adiante na série “em python”).

4. Пример

Написание кошки: Покажи мне код!

4.1 Vamos condender o Funcionamento Do Exemplo 1

from unittest import main, TestCase

def square(x):
    return x ** 2

class TestSquare(TestCase):
    def test_if_returns_square_of_2(self):
        result = square(2)
        expected = 4

        self.assertEqual(result, expected)

if __name__ == '__main__':
    main()

Na Primeira Linha impormamos os iTens recients do framework unittest.

main () ⇒ Chamamos o Тестовый бегун Da Biblioteca para ao rodar nosso código python (python meu_arquivo.py).

Testcase ⇒ Fornece a Estrutura Necpistária para montar o caso de teste.

from unittest import main, TestCase

O próximo bloco se refere ao nosso código com o trecho quememos validar

def square(x):
    return x ** 2

Criamos Uma Classe de Teste Herdando O Testcase Do Unittest E seus métodos são os Casos de Teste .

REPARE QUE DETRO DA CLASSE ESCREVEMOS DE MODO DESCRITIVO O CENário Que Está Sendo Testado (Estamos testando se o nosso código retorna o Quadrado de dois). Depois fazemos uma Asserção USANDO Assertequal ComparryAndo se a thamada da funcão квадрат RETORNA O ESPERADO, QUE E 4.

class TestSquare(TestCase):
    def test_if_returns_square_of_2(self):
        result = square(2)
        expected = 4

        self.assertEqual(result, expected)

Nota: REPARE QUE O NOME DA CLASSE E O CENário Começam com A Палавра “тест”. O nome “test” é obrigatório ser iniciado para as funcões de teste, mas opcionais para a classe (nat antanto é Recomendado por Questões de clareza).

Por fim, o último trecho chama o main () Делайте Quando o arquivo python для receadado.

if __name__ == '__main__':
    main()

Para rodar o exemplo basta rodar como um arquivo python normalmente (нет meu caso eu salvei em um arquivo my_first_test.py)

python my_first_test.py

Нет консоли será exibido Que 1 teste foi executado e ele está com o Статус ХОРОШО , OU Seja, O Teste Passou.

Vamos adicionar wutro cenário de teste para simular um erro

from unittest import main, TestCase

def square(x):
    return x ** 2

class TestSquare(TestCase):
    def test_if_returns_square_of_2(self):
        result = square(2)
        expected = 4

        self.assertEqual(result, expected)

    def test_if_returns_square_of_4(self):
        result = square(4)
        expected = 4

        self.assertEqual(result, expected)

if __name__ == '__main__':
    main()

Executando novamente o código acima temos o seguinte retorno:

Repare que adicionando o cenário test_if_returns_square_of_4 receamos no Total 2 яички E Esseme Esse Cenário Falhou. Isso por Que Chamando A Funcáo квадрат ELA RETORNA 16 E ESTAMOS TENTANDO VALIDAR QUE O ESPERADO A SER RETORNADO E 4.

Corrigindo O Nosso Código, Ele Deveria Ficar Da Seguinte Forma:

from unittest import main, TestCase

def square(x):
    return x ** 2

class TestSquare(TestCase):
    def test_if_returns_square_of_2(self):
        result = square(2)
        expected = 4

        self.assertEqual(result, expected)

    def test_if_returns_square_of_4(self):
        result = square(4)
        expected = 16

        self.assertEqual(result, expected)

if __name__ == '__main__':
    main()

Stustação: ОС яичет nos ajudam. Идентификационные проблемы No Nosso Código Принципал, Mas O Proprio Cenário de Teste Também Está Suscetível A Errros. Devemos Semper Validar Se O Teste Está Bem Escrito E Se Realmente Testando O Cenário Esperado.

Stustação 2: ПРИМЕЧАНИЕ QUE ESSECTEAR FORMA DE CALCULAR O QUADADO DE UM Número. Нет пример Acima Calculamos como x*x Mas Perceba Que Se Mudarmos A Forma Que é Calculada Para x ** 2 o result retornado é o mesmo e isso -afeta OS Nossos яички. SE Executarmos novamente Veremos Que OS Cenários Continuarão Passando.

Um teste não deve inviesar forma como é realado o código. Por isso se efetuarmos refatorações no código, rodando os яичны conseguimos garantir se o comportamento é o mesmo retornado pelo código передний.

Refatoração² é o efeito de você mudar a infulataço do código sem afetar o seu retorno (comportamento externo). Реализация Mudada de forma que o código fique mais aryarmanado, mais limpo e melhor estruturado.

Nota: É Uma boa prática searar o código Принципал Do código dos, Veremos isso no próximo examplo.

4.2 Detecção de divisão

O Пример abaixo mostra uma funcáo que detecta uma divisão. SE Divisão для Orconing Deverá Retornar Вердадиро , SE Não Deverá Retornar Фальсо .

Essa Funcáo está armazenada dentro de um arquivo chamado division_detect.py

def division_detect(numerator: int, denominator: int) -> bool:
    if numerator / denominator:
        return True
    return False

Código 4.2.1

Vamos Escrever Um Cenário de яичники Para Essa Funcáo. Para Isso, Vamos Criar Um Arquivo chamado test_division_detect.py

Nota: ApeSar Dos яичет Rodarem Independente Do Nome Do Arquivo, é Uma boa prática escrever o arquivo de teste keyçando com a palavra “Тест” Ассим Комо Носса Классе.

O arquivo de teste proscui o seguinte esqueleto:

from unittest import TestCase

class TestDivisionDetect(TestCase):

    def test_it_returns_true_if_division_by_number_is_successful(self):
        pass

Código 4.2.2

Para Escrever Esse Cenário de Teste, Queremos validar se a nossa funcáo Division_detect ретрансляция Верно SE Divisão для Bem Sucedida.

Questão é: Qual Número Vamos USAR Para Fazer Esse Teste? Poderíamos Escolher dois números aleatórios como 10 para o numerador e 2 para o деноминадор. Ampryando A Funcáo E Comparryand Se O Restureado RETORNADO E VERDADEIRO COM A ASSERção asserttrue Temos O Seguinte Cenário de Teste:

from unittest import TestCase

from division_detect import division_detect

class TestDivisionDetect(TestCase):
    def test_it_returns_true_if_division_by_number_is_successful(self):
        result = division_detect(
            numerator=10, denominator=2
        )
        self.assertTrue(result)

Código 4.2.3

Нет Teste Acima, Vamos validar se divisão de 10/2 é Agustada Válida.

Vamos rodar o arquivo de teste com o comando abaixo:

python -m unittest test_division_detect.py

Como Sabemos, o Resultado Da Operação é 5 E Bool (5) Эрдадиро

Veremos que um teste rodou e o restureado foi ОК (o Cenário de Teste Passou)

Mas, O Que aconteceria se a Gente Mudasse O Código Принципал без arquivo Division_detect.py Para Esse Código:

def division_detect(numerator: int, denominator: int) -> bool:
    if numerator == 10:
        return True
    return False

Código 4.2.4

Claro Que aqui estamos forçando um pouco a barra e Alterando a Logica do Coodigo Принципал, Mas Se OS -яички Forem Executos Novamente O Teste Vai Passar.

Nesse Caso O Teste Passou Mas Isso não é garantia que o cenário está sendo validado de fato. Para Garantir Que A Divisáo Está Sendo Feita Vamos gerar números aleatórios tanto para o numerador Quanto para o genminador. Para isso vamos usar a funcão do python Рэндинт

from random import randint
from unittest import TestCase

from division_detect import division_detect

class TestDivisionDetect(TestCase):
    def test_it_returns_true_if_division_by_number_is_successful(self):
        result = division_detect(
            numerator=randint(0, 100000), denominator=randint(0, 100000)
        )
        self.assertTrue(result)

Código 4.2.5

Repare que tanto para o numerador como para o genminador está sendo gerado números aleatórios entre 0 e 100000 e se executarmos novamente o arquivo Division_detect.py que foi escrito Нет Código 4.2.4 Vamos ver que o código não vai passar. Vamos voltar o código para Que fique o mesmo do Código 4.2.1 Анкет

Olhando novamente para o cenário de teste, o que aconteceria se o genminador sorteado fosse 0?

É, aqui temos um problesa. Divisão de Qualquer Número por Zero é Indefinida !*

* Divisão por Zero é Uma OperAção Que tende ao Infinito e Portanto é Dada Como Indefinida.

Vamos adicionar um novo cenário de teste para validar isso, dessa Vez vamos forçar Que o Denominador seja Zero.

from random import randint
from unittest import TestCase

from division_detect import division_detect

class TestDivisionDetect(TestCase):
    def test_it_returns_true_if_division_by_number_is_successful(self):
        result = division_detect(
            numerator=randint(0, 100000), denominator=randint(0, 100000)
        )
        self.assertTrue(result)

    def test_it_returns_false_if_division_by_number_is_not_possible(self):
        result = division_detect(numerator=randint(0, 100000), denominator=0)
        self.assertFalse(result)

Código 4.2.6

Rodando novamente esse arquivo de testes, vamos receber o seguinte retorno

REPARE QUE DOISESES FORAM EXERTADOS, O QUE E CORRETO POIS ESCREVEMOS DOIS CENários de Teste. MAS UM DOS яички, O test_it_returns_false_if_division_by_number_is_not_possible , Фалхоу. Isso pois aconteceu um erro kamado ZerodivisionError ( https://docs.python.org/3/library/exceptions.html#zerodivisionError ).

Олхандо Носсо Кодиго Директор, Вемос Кеса Нао Эста Сенто Фейто Ненхум Типо де -Тратаменто Пара Эс -Эрро. Vamos refatorar onso o nosso código para lidar com esse erro, para isso vamos usar o Заявление Try/кроме Python Анкет

def division_detect(numerator: int, denominator: int) -> bool:
    try:
        numerator / denominator
    except ZeroDivisionError:
        return False
    else:
        return True

Código 4.2.7

Нет Código Acima Primeiro Tentamos Fazer A Divisão Entre Os Dois Parâmetros Cecedos, SE Operação для Bem Sucedida Irá Retornar Верно , mas se acontecer uma exceção do tipo ZerodivisionError Irá Retornar Фальсо Анкет

Rodando novamente OS яички com python -m Unittest test_division_detect.py Vamos ver que os dois cenários passaram.

Nota: REPARE QUE NOSSO Código Original Não Estava Preparado Para Uma divisão por Zero. Isso é Chamado de Corner Case, OU Seja, SãARIOS QUE PODEM ACONTECER FORA DO ПАДРАО ЭСПЕРАДО. Para Tratar Esse cenário tivemos que adicionar um tratamento com, как Exceções do Python.

No Arquivo de Teste, Para os dois cenários Que estamos testando, estamos repetindo Рэндинт (0, 100000) Анкет Como Queremos Pegar Semper um numerador aleatório para todos os яички, Podemos utilizar o setup () ( https://docs.python.org/3/library/unittest.html#unittest.testcase.setup ) Que é Uma inicialização que é receadada semper no início de cada cenário de teste.

Por Fim, Chegaremos ao código abaixo:

from random import randint
from unittest import TestCase

from division_detect import division_detect

class TestDivisionDetect(TestCase):
    def setUp(self) -> None:
        self.random_numerator = randint(0, 100000)

    def test_it_returns_true_if_division_by_number_is_successful(self):
        result = division_detect(
            numerator=self.random_numerator, denominator=randint(1, 100000)
        )
        self.assertTrue(result)

    def test_it_returns_false_if_division_by_number_is_not_possible(self):
        result = division_detect(numerator=self.random_numerator, denominator=0)
        self.assertFalse(result)

Que Que o genminador no primeiro Cenário sorteia um número entre 1 e 100000, Pois estamos Querendo valdar um cenário onde a divisão é bem sucedida.

5. Учитывает Адиционайс

Aqui, Listo Alguns Pontos Que Devem Ser Levados Em Commousação no sommon de programar e testar seus códigos:

  • Divida Para Conkistar: Mantenha A Estrutura de Arquivos Organizadas. Se um projeto é grande, é semper uma boa prática дивидир Эм Arquivos Menores (Esso farsea a Manutenção e Legibilidade)
  • UM Teste Também Deve Ser Limpo Igual Ao Código Принципал (Чистый код – Роберт С. Мартин)
  • Используйте Nomes descriTivos para как Funcões de Teste, Mesmo Que seja um nome muito longo
  • Пенсиовать угловые чехлы (Cenários fora do padrão esperado) , igual fizemos na divisão por Zero no Exemplo 2
  • Um teste não deve engessar a infulação do seu código, igual vimos no examplo 1 (o Quadrado de um número pode ser feito de duas formas)
  • Escrever em pequenas Unidades ajudam avatar o código e melhorar sua clareza
  • Refatore: Semper Que Puder Melhorar Seu Código Melhore! (Lema de Escoteiro)

De acordo com a PEP20 ³:

Ошибки никогда не должны проходить молча

Pep³ (do Inglês (предложения по улучшению Python) SE se se se se se se se sepostas de como utilizar o Python da melhor forma: https://www.python.org/dev/peps/

6. Заключение

Яички Сан -Ума Мейра де Гарантир Кесо Программа ретрансляция o РЕЗУЛЬТАЛЬНЫЙ ЭСПЕРАДО. АЛЕМ ДИСОС, GARANTE MAIOR QUALIDADE NO PRODUTO QUE ESTá Sendo Entrege. ОС яичет Тамбем Аджудам Кеса Эк. que acontecem na aplicação e ajudam идентификатор cenários fora do padrão. Testando nosso código, Conseguimos incontrar Também Maneiras de Deixar Nosso Código Mais Limpo E Conciso, FARITITANDO ASSIM NA MANUTENCO FUTURA E EVITAR BUGS QUE OSORRER OCORRRE. É melhor que um teste pegue o erro do que o cliente usando o seu produto:)

Essa foi a Primeira Série de яичка Em Python, Espero Que Tenha ficado Claro O Intendentimento Dessa internução e em breve teremos mais publicaçes sobre esse assunto. Dúvidas Podem ser colocadas no comentário e lembre-se que testar faz parte do processo de escrever um bom código, segundo o программа Пит Гудлифф

“Ум бом código não surge do nada. […] Para Ter um bom código é preciso trabalhar nele. Arduamente. E Você Só Terá Um Código Bom Se Realmente Se Importionar Com Códigos Bons ».

Como Ser программа Melhor: UM Manual Para Programores Que Se impormam Com Código (Пит Гудлифф)

Оригинал: “https://dev.to/womakerscode/testes-em-python-parte-1-introducao-43ei”