Python unittest – exemplo de teste unitário

Hoje vamos aprender sobre o python unittest e analisar programas de exemplo de teste de unidade em python. No tutorial anterior, aprendemos sobre a função zip do python.

Python unittest

O módulo unittest do Python é usado para testar uma unidade de código-fonte. Suponha que você precise testar seu projeto. Você sabe que tipo de dados a função retornará. Após escrever um código extenso, você precisa verificá-lo para saber se a saída está correta ou não. Normalmente, o que fazemos é imprimir a saída e compará-la com o arquivo de saída de referência ou verificar a saída manualmente. Para reduzir essa dificuldade, o Python introduziu o módulo unittest. Usando este módulo, você pode verificar a saída da função com algum código simples. Neste tutorial, discutiremos sobre o uso básico do módulo unittest do Python e escreveremos alguns casos de teste de unidade em python para testar as funções de uma classe.

Exemplo de Código de Teste de Unidade em Python

Primeiro, temos que escrever algum código para testá-los unitariamente. Vamos ter uma classe Python. O principal objetivo da classe é armazenar e recuperar o nome da pessoa. Portanto, escrevemos a função set_name() para armazenar os dados e a função get_name() para recuperar o nome da classe.

class Person:
    name = []

    def set_name(self, user_name):
        self.name.append(user_name)
        return len(self.name) - 1

    def get_name(self, user_id):
        if user_id >= len(self.name):
            return 'There is no such user'
        else:
            return self.name[user_id]


if __name__ == '__main__':
    person = Person()
    print('User Abbas has been added with id ', person.set_name('Abbas'))
    print('User associated with id 0 is ', person.get_name(0))

Nomeamos o arquivo da classe como Person.py. E a saída do código acima será como abaixo.

$ python3.6 Person.py 
User Abbas has been added with id  0
User associated with id 0 is  Abbas
$

Estrutura de testes unitários Python

Agora, vamos aprender como codificar para testes unitários. Um caso de teste individual é criado por subclasse de unittest.TestCase. Ao substituir ou adicionar funções apropriadas, podemos adicionar lógica para testar. O código a seguir será bem-sucedido se a for igual a b.

import unittest


class Testing(unittest.TestCase):
    def test_string(self):
        a = 'some'
        b = 'some'
        self.assertEqual(a, b)

    def test_boolean(self):
        a = True
        b = True
        self.assertEqual(a, b)

if __name__ == '__main__':
    unittest.main()

Como executar o módulo de teste unitário Python

Se estiver a usar o IDE PyCharm, pode simplesmente pressionar ctrl+shift+F10 para executar o módulo de testes unitários. Caso contrário, pode utilizar o prompt de comando para executar este módulo. Por exemplo, se nomearmos o ficheiro para teste unitário como Basic_Test.py, o comando para executar os testes unitários em Python será: $python3.6 -m unittest Basic_Test.Testing. Se desejar ver a saída detalhada, o comando será; $python3.6 -m unittest -v Basic_Test.Testing. Ao usar o PyCharm, obtemos a seguinte saída.

Resultado do Teste Unitário em Python & Funções Básicas

Este teste unitário tem 3 resultados possíveis. Eles estão mencionados abaixo:

  1. OK: Se todos os casos de teste passarem, a saída mostra OK.
  2. Falha: Se algum caso de teste falhar e gerar uma exceção AssertionError.
  3. Erro: Se ocorrer alguma exceção que não seja uma exceção AssertionError.

Existem várias funções no módulo de testes unitários. Elas estão listadas abaixo.

Method Checks that
assertEqual(a,b) a==b
assertNotEqual(a,b) a != b
assertTrue(x) bool(x) is True
assertFalse(x) bool(x) is False
assertIs(a,b) a is b
assertIs(a,b) a is b
assertIsNot(a, b) a is not b
assertIsNone(x) x is None
assertIsNotNone(x) x is not None
assertIn(a, b) a in b
assertNotIn(a, b) a not in b
assertIsInstance(a, b) isinstance(a, b)
assertNotIsInstance(a, b) not isinstance(a, b)

Exemplo de teste unitário em Python

Agora é hora de escrever testes unitários para nossa classe de origem Person. Nesta classe, implementamos duas funções – get_name() e set_name(). Agora, vamos testar essas funções usando unittest. Então, projetamos dois casos de teste para essas duas funções. Dê uma olhada no código a seguir, você entenderá facilmente.

import unittest

# Esta é a classe que queremos testar. Portanto, precisamos importá-la
import Person as PersonClass


class Test(unittest.TestCase):
    """
    The basic class that inherits unittest.TestCase
    """
    person = PersonClass.Person()  # instantiate the Person Class
    user_id = []  # variable that stores obtained user_id
    user_name = []  # variable that stores person name

    # função do caso de teste para verificar a função Person.set_name
    def test_0_set_name(self):
        print("Start set_name test\n")
        """
        Any method which starts with ``test_`` will considered as a test case.
        """
        for i in range(4):
            # inicializar um nome
            name = 'name' + str(i)
            # armazenar o nome na variável de lista
            self.user_name.append(name)
            # obter o ID do usuário obtido da função
            user_id = self.person.set_name(name)
            # verificar se o ID do usuário obtido é nulo ou não
            self.assertIsNotNone(user_id)  # null user id will fail the test
            # armazenar o ID do usuário na lista
            self.user_id.append(user_id)
        print("user_id length = ", len(self.user_id))
        print(self.user_id)
        print("user_name length = ", len(self.user_name))
        print(self.user_name)
        print("\nFinish set_name test\n")

    # função do caso de teste para verificar a função Person.get_name
    def test_1_get_name(self):
        print("\nStart get_name test\n")
        """
        Any method that starts with ``test_`` will be considered as a test case.
        """
        length = len(self.user_id)  # total number of stored user information
        print("user_id length = ", length)
        print("user_name length = ", len(self.user_name))
        for i in range(6):
            # se não exceder o comprimento total, então verificar o nome retornado
            if i < length:
                # se os dois nomes não coincidirem, o caso de teste falhará
                self.assertEqual(self.user_name[i], self.person.get_name(self.user_id[i]))
            else:
                print("Testing for get_name no user test")
                # se o comprimento exceder, verifique a mensagem do tipo 'nenhum usuário encontrado'
                self.assertEqual('There is no such user', self.person.get_name(i))
        print("\nFinish get_name test\n")


if __name__ == '__main__':
    # começar o unittest.main()
    unittest.main()

Observe que o módulo unittest executa as funções de teste na ordem de seus nomes, não na ordem em que são definidos. E como queremos que nosso teste set_name seja executado primeiro, nomeamos nossas funções de caso de teste como test_0_set_name e test_1_get_name.

Exemplo de Saída de Teste Unitário em Python

As imagens abaixo mostram a saída produzida pelo nosso programa de teste unitário – tanto no modo normal quanto no modo verbose.

$ python3.6 -m unittest -v PersonTest.Test
test_0_set_name (PersonTest.Test) ... Start set_name test

user_id length =  4
[0, 1, 2, 3]
user_name length =  4
['name0', 'name1', 'name2', 'name3']

Finish set_name test

ok
test_1_get_name (PersonTest.Test) ... 
Start get_name test

user_id length =  4
user_name length =  4
Testing for get_name no user test
Testing for get_name no user test

Finish get_name test

ok

----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
$

Isso é tudo sobre o tutorial de teste unitário em Python. Para saber mais, leia a Documentação Oficial. Para qualquer dúvida adicional, por favor, utilize a caixa de comentários. 🙂

Source:
https://www.digitalocean.com/community/tutorials/python-unittest-unit-test-example