Exceção Python Assert
-
Usando o Gerenciador de Contexto para Apanhar a Exceção Python
assert
- Utilizando Argumentos de Palavras-Chave para Apanhar a Exceção Python Assert
Este artigo traz uma compreensão de assert
como uma unidade de teste, para testar se as funções podem lançar exceções (erros detectados durante a execução do código) sem necessariamente sair da execução. Em outras palavras, a exceção lançada é encapsulada.
Este teste será aprovado se uma exceção for levantada. Um erro é lançado se uma exceção diferente da esperada for lançada. Em uma instância em que não haja nenhuma exceção levantada, o teste falha.
Usando o Gerenciador de Contexto para Apanhar a Exceção Python assert
Semelhante ao modo como permite a alocação e liberação de recursos quando necessariamente exigidos no conceito geral do Python, o contexto aqui obtém o objeto de exceção real que está sendo lançado durante o teste.
Ele armazena esse atributo de exceção no objeto se houver necessidade de uma verificação de desempenho adicional na exceção gerada.
Para testar se uma função falha ou passa se uma exceção é lançada ou não, vamos empregar TestCase.assertRaises
do módulo unittest
.
Vamos ver um exemplo prático usando o gerenciador de contexto.
import unittest
class TestCase(unittest.TestCase):
def test_nameerror(self):
with self.assertRaises(Exception):
100 * (someNumber / 5)
if __name__ == "__main__":
unittest.main()
Resultado:
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
No código de exemplo, o teste é aprovado porque esperamos que uma exceção seja lançada. Estamos dividindo 5 por uma variável indefinida someNumber
. Portanto, a função lança uma exceção NameError
. Portanto, nosso teste passa conforme exibido pelo .
na primeira linha da saída.
Vamos ver um exemplo em que o teste falha quando uma exceção não é lançada.
import unittest
class TestCase(unittest.TestCase):
def test_nameerror(self):
with self.assertRaises(Exception):
someNumber = 10
100 * (someNumber / 5)
if __name__ == "__main__":
unittest.main()
Resultado:
F
======================================================================
FAIL: test_nameerror (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last): File "c:\Users\Neema\Desktop\Article Requirement Spec and Example
Articles\Article Requirement Spec
and Example Articles\fah.py", line 106, in test_nameerror
100 * (someNumber/5)
AssertionError: Exception not raised
----------------------------------------------------------------------
Ran 1 test in 0.002s
FAILED (failures=1)
Neste código de exemplo, definimos um valor para someNumber
e então executamos a expressão aritmética com ele.
A saída nos mostra que o teste falha conforme o esperado. Não esperamos que nenhuma exceção NameError
seja lançada desta vez, uma vez que existe um valor definido para someNumber
.
Também podemos implementar o gerenciador de contexto usando exceções definidas pelo usuário, como no exemplo a seguir.
import unittest
def user_function():
raise Exception("A user-defined exception")
class MyTestCase(unittest.TestCase):
def test_userexception(self):
with self.assertRaises(Exception) as context:
user_function()
self.assertTrue("A user-defined exception" in str(context.exception))
if __name__ == "__main__":
unittest.main()
Resultado:
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK
Lembre-se de usar
str
para incluir ocontext.exception
para evitar a obtenção de um TypeError.
Apresentamos assertTrue
, uma biblioteca unittest
que compara um valor de teste com true em testes de unidade.
Você também pode optar por usar assertIn
em vez de assertTrue.
Exemplo:
import unittest
def user_function():
raise Exception("A use defined exception")
class MyTestCase(unittest.TestCase):
def test_userexception(self):
with self.assertRaises(Exception) as context:
user_function()
self.assertIn("A use defined exception", str(context.exception))
if __name__ == "__main__":
unittest.main()
Vemos a mesma saída em que as aprovações no teste serão produzidas.
Utilizando Argumentos de Palavras-Chave para Apanhar a Exceção Python Assert
Ao contrário do gerenciador de contexto, onde apenas passamos a exceção para assertRaises()
, também passamos a chamada de função e os parâmetros da função como argumentos de palavra-chave para evocar a exceção.
Sintaxe
assertRaises(exception, function, *args, **keywords)
Exemplo:
import unittest
class MyTestCase(unittest.TestCase):
def test_division_by_error(self):
import operator
self.assertRaises(ZeroDivisionError, operator.floordiv, 55, 0)
if __name__ == "__main__":
unittest.main()
Resultado:
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
O código de exemplo acima usou assertRaises()
com argumentos de palavra-chave. Passamos a ele a exceção ZeroDivisionError
esperada após tentar dividir um número por zero. Importamos a função do operador usada com a função do operador floordiv
como o segundo argumento. Os valores dos parâmetros aqui são os terceiros parâmetros; 55 para dividir por 0.
A última aplicação de assert é quando passamos uma exceção diferente da esperada para assertRaises (). Em vez disso, é produzido um erro.
Usando o mesmo código de exemplo que acabamos de usar acima, vamos implementar isso.
import unittest
class MyTestCase(unittest.TestCase):
def test_division_by_error(self):
import operator
self.assertRaises(TypeError, operator.floordiv, 55, 0)
if __name__ == "__main__":
unittest.main()
Resultado:
E
======================================================================
ERROR: test_division_by_error (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last): File "c:\Users\Neema\Desktop\Article Requirement Spec and Example
Articles\user.py", line 16, in test_division_by_error
self.assertRaises(TypeError, operator.floordiv, 55, 0)
File "C:\Users\Neema\AppData\Local\Programs\Python\Python39\lib\unittest\case.py", line 733, in assertRaises
return context.handle('assertRaises', args, kwargs)
File "C:\Users\Neema\AppData\Local\Programs\Python\Python39\lib\unittest\case.py", line 201, in handle
callable_obj(*args, **kwargs)
ZeroDivisionError: integer division or modulo by zero
----------------------------------------------------------------------
Ran 1 test in 0.031s
FAILED (errors=1)
A partir da saída, um rastreamento de erro é produzido. Esperamos uma exceção ZeroDivisionError ao dividir um número por zero. Em vez disso, passamos uma exceção TypeError aplicada ao realizar uma operação aritmética entre diferentes tipos de dados, digamos uma string e um inteiro.