[230214 - TIL] 테스트코드에 대한 필요성 인식

Dongwoo Kim·2023년 2월 14일
0

TIL / WIL

목록 보기
81/113

1. 개요

지난 일주일가량 진행했던 작업 (외부 API를 통해 리소스 목록을 불러오고 기존의 데이터와 비교해서 최신화하는 작업)에 대한 검수를 하기위해 어제와 오늘 2일간 체크리스트를 작성하고 기능 동작을 확인하는 작업을 진행했다. 다만 개발 DB의 복잡성과 초기 테스트 데이터 설정 등의 두려움으로 인해 체크리스트별 테스트코드를 작성하는 것이 아니라 일일히 손으로 값을 수정해가며 결과값이 제대로 나오는지 확인하는 방식으로 진행했다. 일단 작업진행을 위해 시간이 좀 걸리고 번거롭더라도 마무리를 지었지만 그 과정에서 발생했던 문제점과 해결방법에 대해서 고민해보았다.


2. 작업방식

  1. 체크리스트 작성
  2. 체크리스트 케이스 동작 직접 진행 (리소스에 대한 CRUD 등)
  3. 기능 동작 결과 직접 비교
  4. 케이스별로 2,3번 반복
  5. 특이 케이스 발생시 코드 수정
  6. 수정한 코드로 체크리스트 케이스 1번부터 다시 진행
  7. 무한 반복

3. 문제점

문제점은 당연히 테스트자동화를 하지 못한 점이라고 생각한다. 체크리스트를 작성하고 기록을 남기는 것은 좋았지만 해당 테스트 케이스를 확인하기위해 직접 손으로 값을 수정하고 외부api에 요청을 보내고 다시 응답값에 대한 로직 확인과 DB 업데이트 확인 등 너무나 많은 시간이 필요했다. 더군다나 중간에 특이케이스가 발생해서 코트를 수정해야한다고 치면 앞선 테스트를 다시 일일히 반복해야되는 너무나도 끔찍한 일이 발생했다.

적어도 토이프로젝트를 할 때처럼 테스트코드를 작성할수만 있었어도 정말 효율적으로 일할 수 있었을 것이라 생각한다.

  • 과거 진행했던 프로젝트의 테스트케이스 예시
class TransactionViewTest(APITestCase):
    """
        거래내역 View 테스트
    """

    @classmethod
    def setUpTestData(cls):
        """
            테스트를 위한 유저, 계좌, 거래내역 오브젝트 생성
        """

        # 유저 생성
        cls.user_data_list = [
            {"username": "test_1", "password": "0000"},
            {"username": "test_2", "password": "0000"},
        ]
        cls.user_list = [ UserModel.objects.create_user(**user_data) for user_data in cls.user_data_list ]

        # 계좌 생성
        cls.account_data_list = [
            {"user": cls.user_list[0], "name": "test", "number": "11223344556677"},
            {"user": cls.user_list[0], "name": "test", "number": "77665544332211"},
        ]
        cls.account_list = [ AccountModel.objects.create(**account_data) for account_data in cls.account_data_list]

        # 거래 내역 생성
        cls.transaction_data_list = [
            { "user": cls.user_list[0], "account": cls.account_list[0], 
                "type": "deposit", "amount": 1000, "balance": 1000, "summary": "test" },
            { "user": cls.user_list[0], "account": cls.account_list[0], 
                "type": "deposit", "amount": 500, "balance": 1500, "summary": "test" },
            { "user": cls.user_list[0], "account": cls.account_list[0], 
                "type": "withdrawal", "amount": 800, "balance": 700, "summary": "test" },
            { "user": cls.user_list[0], "account": cls.account_list[0], 
                "type": "withdrawal", "amount": 300, "balance": 400, "summary": "test" },
            { "user": cls.user_list[0], "account": cls.account_list[0], 
                "type": "deposit", "amount": 1000, "balance": 1400, "summary": "test" },
        ]
        for data in cls.transaction_data_list:
            TransactionModel.objects.create(**data)
            print("create transaction and sleep 1 seconds....")
            sleep(1)


    def setUp(self):
        """
            거래내역 조회시 로그인
        """
        response = self.client.post(reverse("token"), self.user_data_list[0])
        self.access_token = response.data["access"]


    def test_view_get_transactions_when_defualt(self):
        """
            거래내역 조회 테스트
            case : 기본 설정으로 조회
        """

        # 조회 요청
        self.client.credentials(HTTP_AUTHORIZATION=f"Bearer {self.access_token}")
        url = reverse("transaction")
        response = self.client.get(f"{url}?account_id=1")

        self.assertEqual(response.status_code, 200)
        self.assertEqual(len(response.data), 5)

        response_amount_order = [data["amount"] for data in response.data ]
        self.assertListEqual(response_amount_order, [1000, 500, 800, 300, 1000])

4. 원인

이런 비효율적인 과정을 거친 가장 큰 이유는 아무래도 경험부족인듯 하다. 회사 시스템에 완전히 파악하지 못했다는 두려움과 기존에 작성된 코드들에서 테스트코드에 대한 정보를 경험해보지 못해서 일단 지금 당장 내가 할 수 있는 방법, 비효율적이지만 어느정도 검증할 수 있는 방법을 택한 것 같다.


5. 개선

때문에 나름 많은 테스트케이스에 대해서 검수를 진행했다고 생각이들면서도 계속 다른 좋은 방법을 찾고 싶었고 선임 개발자분에게 문의했고 같이 현재 상황에서 테스트를 자동화할 수 있는 방법에 대해 고민해보았다.

결론은

테스트에는 왕도가 없다.

규모가 크고 테스트케이스가 복잡하다고해서 더 편하게 할 수 있는 방법은 없었다. 물론 더 좋은 툴이 있고 상황에 맞게 사용할 수 있는 프로세스가 있겠지만 기본적으로는 내가 토이프로젝트에서 했던 방법처럼 테스트코드를 작성하는 것이 맞는 방법이라고 결론을 지었다. 내가 회사 시스템을 잘 몰라서, 내 자신에 대해 확신이 없어서 더 좋은 방법이 있지 않을까, 이렇게 해도 괜찮을까 싶은 마음에 지름길을 두고도 어려운 길을 택한 것이 아닌가 생각이 든다.


6. 결론 (셀프 피드백)

과거 온보딩 과제를 진행할 때에도 비슷한 피드백을 진행했던 기억이 난다. 뭔가 비효율적이라고 생각이 드는 방법에 대해선 개선된 방법을 찾아보자는 의미의 피드백이었다. 그런데 비슷한 실수를 한번더 진행한 것, 아니 이번에는 할 수 있는데도 더 나쁜 방법으로 진행한 케이스다.

앞으로는 내 자신에게 믿음을 가지고 의심을 가지고 더 좋은 방법을 찾아보자!!
대표님이 신년회 때 해주신 말이 떠오른다.

대도무문 (大道無門)

큰 길에는 문이 없다는 뜻으로 우리는 이미 우리도 모르는 사이에 문도 거치지 않고 이미 큰 길에 들어서 있을지도 모른다. 나 자신에게 확신을 가지자!

profile
kimphysicsman

0개의 댓글