테스트에서 random모듈이 작업을 수행하고 있는지 확인해서는 안됩니다 . unittest는 다른 코드와 상호 작용하는 방식이 아니라 클래스 자체 만 테스트해야합니다 (별도로 테스트해야 함).
물론 코드가 random.randint()잘못 사용하는 것은 전적으로 가능합니다 . 또는 당신은 random.randrange(1, self._sides)대신 전화 를하고 당신의 주사위는 결코 가장 높은 가치를 던지지 않지만 그것은 다른 종류의 버그 일 것입니다. 단일 테스트로 잡을 수는 없습니다. 이 경우 die 장치 가 설계된대로 작동하지만 디자인 자체에 결함이 있습니다.
이 경우에는 조롱을 사용 하여 함수 를 바꾸고 올바르게 호출 되었는지 randint()확인 합니다. Python 3.3 이상에는 이러한 유형의 테스트를 처리 하는 모듈 이 제공 되지만 이전 버전에 외부 패키지 를 설치하여 동일한 기능을 얻을 수 있습니다unittest.mockmock
import unittest
try:
from unittest.mock import patch
except ImportError:
# < python 3.3
from mock import patch
@patch('random.randint', return_value=3)
class TestDice(unittest.TestCase):
def _make_one(self, *args, **kw):
from die import Die
return Die(*args, **kw)
def test_standard_size(self, mocked_randint):
die = self._make_one()
result = die.roll()
mocked_randint.assert_called_with(1, 6)
self.assertEqual(result, 3)
def test_custom_size(self, mocked_randint):
die = self._make_one(sides=42)
result = die.roll()
mocked_randint.assert_called_with(1, 42)
self.assertEqual(result, 3)
if __name__ == '__main__':
unittest.main()
조롱하면 테스트가 매우 간단 해집니다. 실제로 2 가지 경우가 있습니다. 6면 금형의 기본 경우와 사용자 정의 측면 경우입니다.
randint()의 전역 네임 스페이스에서 함수 를 임시로 대체하는 다른 방법이 Die있지만 mock모듈이이를 가장 쉽게 만듭니다. 여기서 @mock.patch데코레이터 는 테스트 케이스의 모든 테스트 방법에 적용됩니다 . 각 테스트 메소드 random.randint()에는 모의 함수 라는 추가 인수가 전달 되므로 모의 테스트를 통해 모의 함수가 제대로 호출되었는지 확인할 수 있습니다. return_value가 호출 될 때 우리가 있음을 확인할 수 있도록, 모의에서 반환되는 것을 인수 지정 die.roll()방법은 참으로 우리에게 '랜덤'결과를 반환했습니다.
여기에 또 다른 Python unittesting 모범 사례를 사용했습니다 : 테스트의 일부로 테스트중인 클래스를 가져옵니다. 이 _make_one메소드는 가져 오기 및 인스턴스화 가 test 내에서 작동 하므로 구문 오류 또는 원래 모듈을 가져 오지 못하게하는 다른 실수가 있어도 테스트 모듈 이 계속로드됩니다.
이런 식으로 모듈 코드 자체에서 실수를하더라도 테스트는 계속 실행됩니다. 코드의 오류에 대해 알려 주면 실패합니다.
분명히, 위의 테스트는 극단적으로 간단합니다. 여기서 목표는 random.randint()예를 들어 올바른 인수로 호출 된 테스트를하는 것이 아닙니다 . 그 대신 목표는 특정 입력에 따라 장치가 올바른 결과를 생성하는지 테스트하는 것입니다.이 입력에는 테스트 되지 않은 다른 장치의 결과가 포함됩니다 . random.randint()메서드를 조롱함으로써 코드에 대한 다른 입력 만 제어 할 수 있습니다.
실제 테스트 에서는 테스트 대상 단위의 실제 코드가 더 복잡해집니다. API에 전달 된 입력과의 관계 및 다른 단위가 호출되는 방식은 여전히 흥미로울 수 있으며 조롱하면 중간 결과에 액세스 할 수있을뿐만 아니라 해당 호출의 반환 값을 설정할 수 있습니다.
예를 들어, 타사 OAuth2 서비스 (다단계 상호 작용)에 대해 사용자를 인증하는 코드에서 코드가 올바른 데이터를 해당 타사 서비스로 전달하고 있는지 테스트하고, 타사 서비스가 반환되므로 전체 OAuth2 서버를 직접 구축하지 않고도 다양한 시나리오를 시뮬레이션 할 수 있습니다. 여기서 첫 번째 응답의 정보가 올바르게 처리되었고 두 번째 단계 호출로 전달되었는지 테스트하는 것이 중요하므로 모의 서비스가 올바르게 호출되고 있는지 확인하고 싶습니다.