정말 간단하게 정리했다. 자세한건 docs에...
파이썬도 JUnit과 같은 단위 테스트를 할 수 있다. 주로 unittest라는 표준 라이브러리를 사용한다.
import unittest
unittest 모듈의 기본 개념unittest는 클래스는 단일 테스트 케이스를 정의하는 데 사용된다. 각 테스트 메서드는 반드시 test_로 시작하는 이름을 가져야 하며, 이는 unittest가 테스트 메서드를 자동으로 인식하는 규칙이다.
import unittest
class TestExample(unittest.TestCase):
def test_addition(self):
self.assertEqual(1 + 1, 2)
def test_subtraction(self):
self.assertEqual(5 - 3, 2)
if __name__ == '__main__':
unittest.main()
위 코드에서 TestExample 클래스는 TestCase를 상속받고 있으며, 각 테스트 메서드는 test_로 시작한다. assertEqual 메서드는 두 값이 같은지 확인하는 함수이다. 이 파일을 실행하면 unittest는 자동으로 테스트 메서드를 찾아 실행한다.
unittest의 주요 구성 요소unittest.Testcase를 상속받아 작성된다.def suite():
suite = unittest.TestSuite()
suite.addTest(TestExample('test_addition'))
suite.addTest(TestExample('test_subtraction'))
return suite
unittest.main()이 테스트 러너로 동작하며, 다양한 출력 포맷을 제공하는 테스트 러너를 선택할 수도 있다.setUp()과 treeDown() 메서드를 사용한다.setUp(): 각 테스트 메서득 실행되기 전에 실행되며, 테스트를 위한 초기화 작업을 수행한다.tearDown(): 각 테스트 메서드가 실행된 후에 호출되며, 테스트가 끝난 후 정리 작업을 수행한다.import unittest
class TestExample(unittest.TestCase):
def setUp(self):
# 테스트 초기화 코드
self.number = 10
def tearDown(self):
# 테스트 종료 후 정리 코드
pass
def test_multiplication(self):
self.assertEqual(self.number * 2, 20)
여기서 setUp() 메서드는 테스트가 실행되기 전에 self.number를 10으로 초기화하고, 테스트 메서드 test_multiplication은 self.number에 대한 연산을 테스트한다.
unittest의 주요 메서드unittest에서 제공하는 주요 단연 메서드(Assertion Methods)는 테스트가 기대하는 결과와 실제 결과를 비교합니다. 이러한 메서드를 사용해 테스트 조건을 정의할 수 있다.
1. assertEqual(a, b)
두 값이 동일한지 확인한다.
self.assertEqual(2 + 2, 4)
assertNotQueal(a, b)self.assertNotEqual(2 + 2, 5)
assertTrue(x)x가 True인지 확인한다self.assertTrue(3 > 2)
assertFalse(x)x가 False인지 확인한다.self.assertFalse(3 < 2)
assertIs(a, b)self.assertIs(a, b)
assertIsNone(x)None인지 확인합니다.self.assertIsNone(None)
assertIn(a, b)a가 b에 포함되는지 확인한다.self.assertIn(3, [1, 2, 3])
assertRaises(exception, callable, *args, **kwargs)with self.assertRaises(ZeroDivisionError):
1 / 0
unittest는 터미널에서 실행할 수 있으며, 실행 결과는 성공, 실패 또는 에러로 구분된다.
if __name__ == '__main__':
unittest.main()
위의 코드로 테스트 파일을 실행하면, 테스트 러너가 각 테스트 케이스를 실행한 후 결과를 출력한다. 일반적으로 다음과 같은 형식의 출력이 제공된다.
.: 테스트가 성공적으로 실행됨F: 테스트 실패E: 테스트 실행 중 예외가 발생함때로는 특정 조건에서 테스트를 건너뛰거나, 조건부로 테스트를 실행해야 할 때가 있다.
unittest는 이를 위해 skip 데코레이터와 메서드를 제공한다.
@unittest.skip(reason)@unittest.skip("이 테스트는 건너뜁니다.")
def test_skipped(self):
self.assertEqual(1, 1)
@unittest.skipIf(condition, reason)@unittest.skipIf(sys.platform == "win32", "윈도우에서 실행 안 함")
def test_not_on_windows(self):
self.assertEqual(1, 1)
@unittest.expectedFailure@unittest.expectedFailure
def test_will_fail(self):
self.assertEqual(1, 2)
때때로 실제 객체가 아니라 테스트를 위해 가짜 객체를 사용해야 할 필요가 있다. 이를 위해 파이썬은 unittest.mock 모듈을 제공한다. mock 객체는 외부 의존성을 제거하고 코드의 일부만을 테스트하는데 유용하다.
mock 사용 예시
from unittest.mock import MagicMock
class ProductionClass:
def method(self):
pass
mock = MagicMock()
mock.method.return_value = 3
print(mock.method()) # 출력: 3
여기서 MagicMock 객체는 원래 메서드를 호출하는 대신, 사전에 정의된 값을 반환한다.
테스트를 반복해서 다른 입력값으로 실행해야 할 경우, 파라미터화된 테스트가 유용합니다. 기본적으로 unittest는 파라미터화된 테스트를 직접 지원하지 않지만, unittesst 확장 라이브러리인 parameterized와 같은 라이브러리를 사용하면 쉽게 구현할 수 있다.
from parameterized import parameterized
class TestParameterized(unittest.TestCase):
@parameterized.expand([
("case1", 1, 2, 3),
("case2", 2, 3, 5),
])
def test_addition(self, name, a, b, expected):
self.assertEqual(a + b, expected)
위 예시에서 parameterized.expand() 데코레이터는 각 테스트 케이스에 다른 매개변수를 전달하여 동일한 테스트를 반복적으로 실행한다.