Python 어설션 예외
이 기사는 함수가 반드시 실행을 종료하지 않고도 예외(코드 실행 중에 감지된 오류)를 던질 수 있는지 테스트하기 위해 테스트 단위로서의 assert
에 대한 이해를 제공합니다. 즉, 던져진 예외는 캡슐화됩니다.
이 테스트는 예외가 발생하면 통과합니다. 예상한 것과 다른 예외가 발생하면 오류가 발생합니다. 발생한 예외가 전혀 없는 경우 테스트가 실패합니다.
컨텍스트 관리자를 사용하여 Python Assert 예외 포착
일반적인 파이썬 개념에서 필연적으로 필요할 때 리소스 할당 및 해제를 허용하는 방법과 유사하게 여기 컨텍스트는 테스트 중에 던져지는 실제 예외 객체를 보유한다.
발생한 예외에 대한 추가 성능 검사가 필요한 경우 이 예외 속성을 개체에 저장합니다.
예외가 발생했는지 여부에 관계없이 함수가 실패하거나 통과하는지 테스트하기 위해 unittest
모듈에서 TestCase.assertRaises
를 사용합니다.
컨텍스트 관리자를 사용하는 실제 예를 살펴보겠습니다.
import unittest
class TestCase(unittest.TestCase):
def test_nameerror(self):
with self.assertRaises(Exception):
100 * (someNumber / 5)
if __name__ == "__main__":
unittest.main()
출력:
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
예제 코드에서는 예외가 throw될 것으로 예상하기 때문에 테스트가 통과합니다. 5를 정의되지 않은 변수 someNumber
로 나눕니다. 따라서 함수는 NameError
예외를 발생시킵니다. 따라서 우리의 테스트는 출력의 첫 번째 줄에 .
로 표시된 대로 통과합니다.
예외가 발생하지 않을 때 테스트가 실패하는 예를 살펴보겠습니다.
import unittest
class TestCase(unittest.TestCase):
def test_nameerror(self):
with self.assertRaises(Exception):
someNumber = 10
100 * (someNumber / 5)
if __name__ == "__main__":
unittest.main()
출력:
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)
이 예제 코드에서 someNumber
에 대한 값을 정의한 다음 이를 사용하여 산술 표현식을 수행합니다.
출력은 테스트가 예상대로 실패했음을 보여줍니다. someNumber
에 대해 정의된 값이 존재하기 때문에 이번에는 NameError
예외가 발생하지 않을 것으로 예상됩니다.
다음 예제와 같이 사용자 정의 예외를 사용하여 컨텍스트 관리자를 구현할 수도 있습니다.
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()
출력:
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK
TypeError가 발생하지 않도록
str
을 사용하여context.exception
을 묶는 것을 잊지 마십시오.
단위 테스트에서 테스트 값을 true와 비교하는 unittest
라이브러리인 assertTrue
를 소개합니다.
assertTrue 대신 assertIn
을 사용하도록 선택할 수도 있습니다.
예시:
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()
테스트 통과가 생성되는 동일한 출력이 표시됩니다.
키워드 인수를 사용하여 Python Assert 예외 잡기
assertRaises()
에만 예외를 전달하는 컨텍스트 관리자와 달리 함수 호출과 함수의 매개변수도 예외를 유발하는 키워드 인수로 전달합니다.
통사론
assertRaises(exception, function, *args, **keywords)
예시:
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()
출력:
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
위의 예제 코드는 키워드 인수와 함께 assertRaises()
를 사용했습니다. 숫자를 0으로 나누려고 시도한 후 예상되는 ZeroDivisionError
예외를 전달했습니다. floordiv
연산자 함수와 함께 사용되는 연산자 함수를 두 번째 인수로 가져왔습니다. 여기서 매개변수 값은 세 번째 매개변수(55를 0으로 나눈 값)입니다.
assert의 마지막 적용은 예상한 것과 다른 예외를 assertRaise()
에 전달할 때입니다. 대신 오류가 생성됩니다.
위에서 사용한 것과 동일한 예제 코드를 사용하여 이것을 구현해 보겠습니다.
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()
출력:
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)
출력에서 오류 역추적이 생성됩니다. 숫자를 0으로 나눌 때 ZeroDivisionError 예외가 예상됩니다. 대신, 문자열과 정수와 같은 서로 다른 데이터 유형 간에 산술 연산을 수행할 때 적용되는 TypeError 예외를 전달합니다.