본문 바로가기
프로그래밍/Python

[TDD][Python] unittest - 예제로 익혀보기(2)

by 우주를놀라게하자 2022. 3. 16.
반응형
SMALL

unittest - 예제로 익혀보기(1)에선 간단하게 날짜를 이용한 테스트를 구현해보았다

이번에는 날짜 계산 테스트 모듈을 확장해보는 예제를 만들어보자. 

확장하기 전 이전에 만들어둔 datetimehelper.py모듈의 문제점부터 짚고 넘어가자

📃 소스코드 및 설명(datetimehelper.py)

"""
날짜 계산 모듈
"""

import datetime

class DateTimeHelper(object):
    """
    기존의 datetime이 주는 형식(2022-03-16 12:36:53.954430)에서 편의성을 위해
    날짜, 요일로 분리해주는 모듈입니다.
    """
    def today(self):
        """
        오늘 날짜를 반환합니다.
        @returns
            2022-03-16 12:36:53.954430
        """
        
        return datetime.datetime.now()

    def date(self):
        """
        오늘 날짜를 반환합니다. 다만, today함수의 형식과 다른 일/월/년도 형식으로 반환합니다
        @returns
            16/03/22
        """
        return self.today().strftime("%d/%m/%Y")

    def weekday(self):
        """
        오늘 요일을 반환합니다. 
        @returns
            Wednesday
        """
        return self.today().strftime("%A")

    def us_to_korea(self,date):
        """
        미국식 날짜(16/03/22) -> 한국식(2022/03/16) 날짜로 변경합니다.
        @params
            date - 08/12/2016
        @returns
            2022/03/16
        """
        dd, mm, yy = date.split('/')
        date_obj = datetime.date(year=int(yy), month=int(mm), day=int(dd))
        return date_obj.strftime("%Y/%m/%d")

코드를 보면, us_to_korea의 메소드는 입력값을 받아서 내 입맛대로 테스트 케이스를 만들어서 테스트를 진행할 수 있다.

그러나 today(), weekday() 메소드를 보면 datetime.datetime.now() 함수를 사용해서 처리하게 되므로, 내가 원하는 테스트 케이스를 만들어서 처리할 수 없다는 문제가 있다!😅

이 문제를 해결하기 위해서 우리는 unittest.mock 라이브러리를 사용해서 모의 객체를 생성하여 외부 라이브러리의 의존성을 덜것이다. 이 방법을 통해서 datetime.datetime.now() 객체가 제공하는 '오늘' 날짜뿐만 아니라 내가 지정한 날짜에 대해서도 테스트를 구하게 된다.

📃 소스코드 및 설명(test_datetimehelper.py)

"""
datetimehelper 모듈 테스터
"""
import datetime
import unittest
from unittest.mock import patch
import datetimehelper
class DateTimeHelperTestCase(unittest.TestCase):
    """
    Unit Test - testcase class [DateTimeHelper 클래스]
    """
    def setUp(self) -> None:
        self.obj = datetimehelper.DateTimeHelper()

    def test_us_korea_conversion(self):
        """
        미국식 날짜 -> 한국식 날짜 변경 테스트
        """
        # 테스트 케이스 생성
        d1 = '08/12/2016'
        d2 = '24/11/2021'
        d3 = '02/02/2019'
        d4 = '16/03/2021'
        self.assertEqual(self.obj.us_to_korea(d1), '2016/12/08')
        self.assertEqual(self.obj.us_to_korea(d2), '2021/11/24')
        self.assertEqual(self.obj.us_to_korea(d3), '2019/02/02')
        self.assertEqual(self.obj.us_to_korea(d4), '2021/03/16')
    
    def test_date(self):
        """
        datetimehelper.py > today() 메소드 테스트
        """

        # 테스트를 위한 날짜를 지정해서 만들어줍니다.
        test_date = datetime.datetime(year=2022,month=2,day=10)

        # patch를 통해 today() 메소드에 내가 지정한 날짜를 넣고 테스를 진행합니다.
        #                   객체, 객채의 메소드 명,   테스트용 데이터 
        with patch.object(self.obj, 'today', return_value=test_date):
            response = self.obj.date()
            self.assertEqual(response, '10/02/2022')
    
    def test_weekday(self):
        """
        datetimehelper.py > weekday() 메소드 테스트
        """
        
        # 테스트를 위한 날짜를 지정해서 만들어줍니다.
        test_date = datetime.datetime(year=2022,month=2,day=10)

        # self.obj = datetimehelper.DateTimeHelper()에 있는 today메소드에 테스트를 원하는 데이터를 넣고 테스트를 진행합니다.
        with patch.object(self.obj, 'today', return_value=test_date):
            response = self.obj.weekday()
            self.assertEqual(response, 'Thursday')

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

 

이제 테스트를 돌려보자. 그럼 아래와 같이 성공한 것을 눈으로 확인 할 수 있다.

 

 위의 코드를 실행했을때, 저번 시간에 말한 테스트 케이스의 갯수를 .의 갯수로 파악할 수 있다고했는데, 위와같이 테스트 케이스가 3개일 경우 ...으로 증가한것도 확인 할 수 있다.

반응형
LIST