테스트 코드 만들기

2023년 11월 27일 월요일

Today I learned

날짜

2023년 11월 27일 월요일

내용

테스트 코드를 고쳤다. 근데 제대로 된 건지 모르겠다.. 반복 실행해서 일관성도 확인해보고, 원하는 검증이 이뤄진건지 로직도 다 확인해봐야 한다.

테스트 함수 1

  1. TypeError 메시지로 보아 어떤 변수가 특정 함수 의 parameter로 없는 것으로 예상된다.

  2. 실제로 저 메서드를 찾아가보니 없길래 테스트 코드에서도 삭제해주었다.

  3. parameter로 들어간 값을 schemas 파일에서 Type 클래스를 가져와 그중 1개를 선택하도록 변경하였다.

  4. 메서드 내의 다른 함수의 반환 타입이 예상과 다르다는 오류가 발생했다.

  5. 여기서 내가 기능함수를 함부로 수정하면 안될것 같아 여쭤봤는데, 현재 잘 작동되고 있는 메서드이고, 중요한 기능이라 시간을 들여 테스트 코드를 제대로 작성하는 쪽으로 진행하는게 좋다고 말씀해주셨다. 역시 “해도되나?” 는 안하는게 맞다.

  6. 테스트 코드 내부의 함수에서 param을 수정하였다.

  7. 함수의 일부 params는 Query[None] 타입이다. 이는 값이 존재할 땐 Query로 처리하지만 없을땐 None으로 처리하겠다는 의미로 FastAPI에서만 쓰인다. 이 값이 데이터베이스 쿼리에 포함되면서 오류가 발생함. 실제 서비스에서는 해당 값들이 어떤 이유로든 반드시 입력되어서 오류가 발생하지 않은 걸까?

  8. 여러 필수적인 필드들에 구체적인 값을 넣어줬더니 PASS 처리 되었다. 하지만 확실한 테스트를 위해 내 가설을 검증할 필요가 있다.

  9. 검증 사항 : 위 필드들은 과정 상 주어질 수 밖에 없는 값인가?

    • 어떤 값은 반드시 설정하게 되어 있다.

    • 어떤 값은 넣을 값에 대한 로직이 존재하여 항상 값을 가진다.
    • 어떤 값은 기본값이 있다.
  10. 따라서 이 값들은 입력값이 반드시 존재한다. schemas 상 범위 내의 값을 무작위로 넣어주면 될듯

  11. 다른 parameter가 없다고 오류가 발생하였다. schema에 맞게 알맞은 mock 데이터를 추가하여 해결하였다.

테스트의 일관성 검증

  1. 현재 두 테스트 함수의 결과가 일관성이 없다.
  2. container를 down한 뒤 up 하여 반복적으로 테스트를 시도해봄
    1. 결과
      • 3개 실패
      • 3개 실패
      • 2개 실패
      • 3개 실패
      • 3개 실패
      • 2개 실패
      • 2개 실패
      • 2개 실패
      • 3개 실패
      • 3개 실패
  1. 현재 테스트 간 독립성이 보장되지 않은 듯 함. 테스트 코드가 서로 영향을 끼치는지, 회차 별로 누적되는것이 있는지 확인 필요.
  2. 테스트 후 db를 지우는 로직을 주석처리 해서 DB를 남겼다. DB를 확인해봤다.
    1. DB review 테이블
    id product_id is_archived
    1 1 0
    2 1 0
    3 1 0
    4 1 0
    5 1 0
    6 1 0
    7 1 0
    8 1 0
    9 1 0
    10 1 0
    11 11 0
    12 12 0
    13 12 1
    14 12 1
    15 12 0
    16 12 0
    17 12 1
    18 12 0
    19 12 1
    20 12 0
    21 12 1
  1. 딱봐도 뭔가 잘못되 보인다..product_id가 1인 레코드의 is_archived는 전혀 바뀌지 않았고 저 11이라는 1개는 무엇이며 12 는 또 왜생긴건지 모르겠다. 이후의 다른 테스트 로직에서 생겼을 수도 있으니 우선 1인것들 중 에서 is_archived가 수정되도록 바꿔야 한다.
  2. 원인을 찾았다. 테스트 코드 중 테스트를 위한 review와 product를 미리 생산하는데 각 테스트 함수에서 또 만드는 것 같다.
  3. 테스트는 각자 독립적이여야하므로 미리 데이터를 만들지 않도록 해야하나..?
  4. 일괄적으로 데이터 생성하기(효율성) VS 각 테스트 케이스마다 데이터 생성하기(독립성)
  5. 미리 데이터를 만드는 함수를 각주처리하니 11개만 생성됐다. product_id가 1인것 1개 + 2인것 10
  6. 테스트 함수를 각주처리 해보았다. 예상대로 딱 10개가 생성됐다.
  7. 우선 테스트가 진행되면서 레코드가 누적되는데, 로직상 이를 신경쓰지 않아 생긴 문제라고 결론지었다.
  8. 해결방안 : 필요한 데이터를 미리 생성한 후, 테스트 함수가 매번 롤백하기
  9. 테스트 함수에서 데이터 생성하는 로직 제거, product와 review는 이미 존재하는 레코드 들 중 무작위로 하나 선택하도록 수정
  10. 해결!

테스트 함수 2

  1. 여기서도 데이터를 생성하지 않고 기존에 존재하는 레코드 중 하나를 선택하도록 수정하였다.
  2. 그럼에도 로직에 오류가 발생하였다.
  3. 로그를 찍어보니 만들어진 리뷰들은 product_id가 1로 고정되어있었는데, product를 무작위 선택하다보니 아카이브할 리뷰가 선택되지 않는 문제였다.
  4. product_id를 값이 1인 것으로 고정시켰고 아카이브된 리뷰 개수를 셀 product를 선택할때도 id를 1로 설정하였다.
  5. 그럼에도 리뷰들이 아카이브 되지 않았다.
  6. 원인은 리뷰 데이터를 생성할때 shop_id를 실제와 다르게 설정했기 때문이었다. review의 product_id가 1이고 shop_id는 1로 설정되었지만, 실제 id가 1인 product의 shop_id는 4였다.
  7. 따라서 리뷰 데이터를 생성할때 10개 중 product_id가 1인 것을 선택하고 shop_id도 해당 product의 데이터로 설정하도록 변경했다.
  8. 갑자기 모든 테스트를 통과해버렸다(?)

회고

안풀릴땐 차근차근 가설을 세우고 검증할 것. 그리고 반드시 적어서 눈에 보이게 할 것.