seminar-2020
seminar-2020 copied to clipboard
TestCase의 setUp에서 다른 API를 이용하는 방법에 대해
TestCase class의 setUp 메소드는 각 API를 테스트 하기 위한 세팅을 하고, 이 과정에서 DB에 특정 row를 insert 합니다.
DB에 row를 insert 하기 위해서는 아래의 2가지 방법을 이용할 수 있다고 생각했습니다.
-
client.post()
등을 이용해서, 구현해놓은 API를 사용 -
Seminar.objects.create()
등을 이용해서, object를 직접 생성
제공받은 tests_user.py를 살펴보면 1번 방법을 이용하고 있음을 알 수 있습니다.
질문 : 두 방법 중 무엇을 사용하는 것이 더 좋을까요? 어떤 방법을 사용하는지는 개인 취향일 뿐인가요?
개인적으로는, 1번 방법에서 다른 API를 이용하는 점이 좋지 않다 생각합니다. 테스트를 실패한 원인이 테스트 중인 API가 아니라 setUp에서 사용한 API의 문제일 수 있기 때문입니다. 물론 궁극적으로는 모든 API를 맞게 구현해야 하므로 모든 테스트를 통과하게 되겠지만요.
@gina0605 저도 일반적으로 view 단위의 test를 작성하기 위해서는 2.의 방식이 더 좋다고 생각하고, 실제로 저도 여러 프로젝트에서 그런 방식으로 테스트를 작성합니다. :) 그야말로 다른 API에 의존성이 생기는 것이니까요! 물론, Seminar.objects.create()
같은 코드를 사용하더라도 model code에 의존하는 것이 되긴 하지만요.(특히 save()
method를 overrding 했다면요) 그렇기 때문에 과제 내용 중에 언급했듯, class, method 등의 단위만을 위한 테스트도 존재할 수 있을 것입니다.
제가 1.의 방식으로 드릴 수밖에 없었던 것은, 꼭 1.의 방식이 '틀렸다'는 것이 아니기도 해서이지만(물론 view 단위의 철저한 unit test를 작성해야 한다면 거의 '틀렸다'고 할 수 있을 것입니다. 예를 들어 PUT /api/v1/user/me/
API를 test하기 위해 POST /api/v1/user/
API에 의존하고 있으니까요), 정말 부득이하게도 우리 각자가 가장 기본적인 model부터 설계와 코드를 다르게 만들었기 때문입니다. 때문에 거의 client에서 인터페이스(API의 그 I이지요)상으로 동작시켜보는 것과 비슷하게 테스트를 작성했습니다.(실제로 이용하는 class 이름도 Client
이지요.) 이런 측면에선 오히려 종단 간(end-to-end, E2E) test에 가깝다고 할 수 있습니다.
별개로 얼핏 비슷해보일 수 있으나, 이것은 과제 3에서 서로 다른 test 간에 직접적으로 dependency가 있어서는 안된다는 내용(내용 3의 두 번째 점)과는 다르다는 점을 상기시켜 드립니다. 여기서 짚어주신 부분은, 'test가 가급적 명확히 하나의 내용을 검증해야 한다'라는 지향점(내용 2의 다섯 번째 점)과 더 관련이 있는 셈입니다.
나중에라도 꼭 공유하고 싶었던 얘기인데 이슈로 나눠주셔서 정말 감사합니다.
전혀 다른 주제이지만 과제 2에 대해, 과제이기에 부득이하게 존재하는 한계점을 얘기한 https://github.com/wafflestudio/rookies/issues/163#issuecomment-693265133 코멘트의 뒤쪽 내용이 비슷한 느낌으로 생각나네요!
@gina0605 조금 여담이지만, 1.과 2. 외에 Python으로 직접 DB에 쌩 query를 날려서 insert 하거나...(?!) 미리 JSON 파일 등에 데이터를 저장해두고 읽어와 이용하는 fixture loading 방식도 활용할 수 있다고 생각합니다. 후자가 궁금하시면 여기 등을 참고해보시면 좋을 것 같습니다.
@davin111 좋은 정보 감사합니다! fixture loading 방식도 장점이 있어보이네요ㅎㅎ