seminar-2020 icon indicating copy to clipboard operation
seminar-2020 copied to clipboard

coverage missing에 대한 질문

Open YeonghyeonKO opened this issue 4 years ago • 4 comments

다음은 coverage html에서 assignment2,3 에 해당되지 않는 파일인 (사실 좋은 개발에 있어서 끊임없는 보완과 test는 필수불가결하기에 '해당되지 않는다'는 표현은 적절하지 않지만) survey/views.py를 검사해본 결과입니다.

image

잘 동작하는 코드들도 missing 이라며 가차 없이 쳐내는 것을 볼 수 있는데요, coverage 5.3 api을 얼핏 살펴보았는데 어떻게 동작하는지, 그리고 어떤 기준으로 missing으로 판별하는지 감이 잘 오지 않아 질문드립니다.

YeonghyeonKO avatar Oct 10 '20 16:10 YeonghyeonKO

흠 글쎄요, coverage run --source='.' manage.py test 등을 통해 정말 SurveyResultViewSet의 저기 실행되지 않은 코드들을 test하는 test들이 잘 동작하고, 그 이후 coverage html를 사용하신 것 맞나요? coverage report과 결국 같은 결과이므로 coverage html인지 등의 여부는 중요하지 않을 거 같고, 정말 의도한대로의 test들이 coverage에 측정된 것이 맞는 것인지 확인해보셔야 할 것 같습니다. 예를 들어, 제가 드렸던 tests_user.py를 제 로컬에서 측정해본 후 html로 열어본 화면은 아래와 같습니다. test가 실행시킨 코드들은 초록색으로 표시된 것을 확인할 수 있습니다.

스크린샷 2020-10-11 02 32 48

(except Integrity에 해당하는 block이 실행되지 않은 것도 자연스러운 상황입니다. test 코드가 확인하는 중복된 username의 상황은 결국 UserSerializer 내부에서 validate 할 때 처리되는 상황입니다. 저기의 except 문이 방지하려는 상황은 validate 해놓고 막상 insert 하는 그 사이에 동일한 usernameUser가 생겨버린 특수한 상황입니다.)

과제 3에서 명시적으로 최소한으로 요구한 API들에 survey 관련 API들이 포함되어 있지 않았는데, 혹시 이에 대한 test를 작성하지 않으셔놓고 착각해 SurveyResultViewSet를 확인해본 것은 아닌지 싶기도 하구요.

davin111 avatar Oct 10 '20 17:10 davin111

캡쳐를 보시면 waffle_backend/settings.py 와 같이 test와 무관한 파일들에 대해서도 coverage가 측정하여 88%의 coverage rate를 나타내고 있습니다. test를 짜지 않았음에도 어떤 것은 통과하고 어떤 것은 missing이라고 판단하는 기준이 궁금하여 일부러 과제들과 무관한 survey app을 선택해서 예시로 말씀드린건데 오히려 혼란을 야기한 것 같습니다.

image

waffle_backend/settings.py에 대한 coverage 내용 image

YeonghyeonKO avatar Oct 10 '20 18:10 YeonghyeonKO

아 그런 의미군요, 처음 메시지에서 올려주신 코드들 중 초록색인 부분들을 보면 import line들과, class의 attribute와 method를 정의하는 line들만임을 알 수 있습니다. 이것은 상당히 자연스럽고 정확하다고 볼 수 있는데요. Django가 실행하는 manage.py가 여러가지를 하지만 특히 settings.py의 모든 line을 읽어서 가져옵니다. 이 때 INSTALLED_APPS에 명시되는 앱들을 보고 그에 해당하는 py 파일들을 import해서 기본적인 것들을 다 실행하게 됩니다. 그렇기 때문에 프로젝트 내의 파일 관계 및 그 내부에 선언해둔 class, 함수들을 서로 참조할 수 있는 것입니다. 이러한 프로젝트 실행 시작 시점에서 아예 말도 안되는 syntax(class나 함수 정의 자체가 이상하거나) 같은 것은 걸러지고 runserver 단계에서 실패하는 것이구요. 이 때, class와 함수들의 정의를 읽는 과정에서 저런 초록색 코드들이 실행된다고 볼 수 있습니다. INSTALLED_APPS와 전혀 무관한 py 파일을 만들어서 비슷한 코드를 넣어두면, 이런 파일은 아예 전체가 실행되지 않는 것을 보실 수 있을 겁니다. 참고로 파일 간의 import 관계가 꼬이는 circular import 같은 문제가 있다면 마찬가지로 이 상황에서 발견됩니다.(에러 메시지가 직접적이지는 않을 수 있으나, 아무튼 뭔가 제대로 실행이 안 됩니다)

그런데 함수 내부가 실행되지 않는 이유는, 중언부언이긴 한데 그 내부가 진짜 실행될 일이 없기 때문입니다. 특히 Python은 compile을 하지 않는 interpreter 언어라서, 함수 내부가 엉망으로 짜여있어도, 그게 runtime에 가서야 발견되는 경우가 있습니다. 뭔가 함수 내부 문법 등이 이상한데(어떤 class object의 존재하지도 않는 attribute나 method를 참조해서 터지는, 사실 compile 단계에서 발견될 수 있는 상당히 명백한 문제 등. 이런 게 Python 류 언어들을 극혐하는 사람들이 싫어하는 포인트 중 하나이기도 합니다.) runserver는 잘 되었으나 막상 관련 API를 call했을 때 에러가 터지는 게 그런 이유 때문입니다. 지금 SurveyResultViewSet의 method 정의 line은 실행되었으나, 내부는 실행되지 않은 것이 같은 맥락입니다. (물론 그렇다고 compile 언어는 그럼 모든 line을 '실행'하는 것이라고 표현할 수 있냐, 라고 하면 그것은 아닐 거 같습니다. 암튼 검토를 해준다는 것이죠. Python이 특히 무책임하다고 보시면 될 것 같습니다.)

바로 위 메시지의 settings.py에서 if DEBUG_TOOLBAR 블럭 내부가 실행되지 않은 것은, 당연히 DEBUG_TOOLBARFalse여서 그렇겠죠? 이렇게 특정 분기 내부로 들어가지 않으면 마찬가지로 그 block이 실행되지 않습니다.

다시 강조하지만 이것은 Django나 test와 관련된 것이라기보다는, 사실 Python이 어떻게 실행되는가에 대한 아주 대략적인 내용입니다. 그 기제를 정확히 아시면 의문이 자연스레 해소될 것 같습니다.

'잘 동작하는 코드들도 missing 이라며 가차 없이 쳐내는 것을 볼 수 있는데요'라고 표현하셨지만, 그건 사람이 알 뿐이지 test 시점에 실제 관련 API를 실행하지도 않아본 컴퓨터 입장에서는 관련 코드를 정말로 line by line으로 실행되게 하기 전까지 알지 못하는 것입니다. 얘는 오로지 관련 class 정의를 처음에 가져올 때 깨지지는 않았음, 정도만 확신할 수 있는 것입니다. 사람의 '잘 동작한다' 같은 판단은 믿을 수 없기도 하구요!

그리고 coverage가 초록색으로 표시하는 것은 test가 성공했다는 '통과'의 의미라기보다는, '실행해봤다'라는 cover의 의미로 보시는 게 정확합니다.

davin111 avatar Oct 10 '20 18:10 davin111

자세한 답변 감사합니다! 좋은 글이라서 여러 번 읽어야겠습니다.

YeonghyeonKO avatar Oct 11 '20 08:10 YeonghyeonKO