클린 코드를 위한 테스트 주도 개발 1.4

전호종·2021년 3월 8일
0

TDD

목록 보기
3/6

셀레늄을 이용한 사용자 반응 테스트

기능 테스트 파일을 실행하면 ERR_CONNECTION_REFUSED 에러를 확인할 수 있다.
개발 서버를 실행하지 않았기 때문이다. TDD가 훌륭한 이유 중 하나가 다음에 무엇을 해야 할지 잊어버릴 걱정이 없다는 것이다. 테스트를 실행하기만 하면 다음 작업이 무엇인지 가르쳐준다.

기능 테스트 파일 수정

참고) any()
any(x)는 반복 가능한(iterable) 자료형 x를 입력 인수로 받으며 이 x의 요소 중 하나라도 참이 있으면 True를 돌려주고, x가 모두 거짓일 때에만 False를 돌려준다. all(x)의 반대이다.

오류 확인
< h1 > 요소를 페이지에서 찾지 못했다는 메세지다.

커밋
기능 테스트를 수정했다면 커밋을 하는 것이 좋은 습관이다. 커밋 시에는 가능한 작은 단위로 하는 것이 좋다.

$ git commit -m '기능 테스트가 작업 아이템을 추가할 수 있는지 확인'

"상수는 테스트하지 마라"는 규칙과 탈출구로 사용할 템플릿

lists/test.py에 있는 단위 테스트를 다시보자. 현재는 특정 HTML 문자열을 확인하고 있지만, HTML을 테스트하기 위한 효율적인 방법이 아니다.
단위 테스트 시의 일반적인 규칙 중 하나는 "상수는 테스트하지 마라"다. HTML을 문자열로 테스트하는 것은 상수 테스트와 같다고 할 수 있다.

단위 테스트는 호직이나 흐름 제어, 설정 등을 태스트 하기 위한 것이다. 정확이 어떤 글자들이 HTML 문자열에 배열돼 있는지 체크하는 어설션은 아무 의미가 없다. 이 경우는 템플릿을 이용하는 것이 훨씬 나은 접근법이다.

템플릿을 사용하기 위한 리팩터링
리팩터링(Refactoring)은 "기능은 바꾸지 않고" 코드 자체를 개선하는 작업을 일컫는다.

첫 번째 규칙은 테스트 없이 리팩터링을 할 수 없다는 것이다. 테스트를 통과하는지 확인하고 리팩터링 작업이 가능한지를 결정할 수 있다.

$ python manage.py test

템플릿 작성
테스트를 통과했다. 이제 HTML 문자열을 별도의 파일에 저장한다. lists/templates라는 폴더를 생성하고 템플릿 파일을 저장한다.
home.html 파일을 생성하고 아래와 같이 작성한다.

뷰 수정
Django의 render함수를 사용한다. 첫 번째 인수로 요청을 지정하고, 두 번째 인수로 렌더링할 템플릿명을 지정한다.
Django는 앱 폴더 내에 있는 templates 폴더를 자동으로 검색한다. 그리고 해당 파일을 기준으로 HttpResponse를 만들어준다.

테스트 및 트레이스백 분석

  • raise TemplateDoesNotExist(template_name, chain=chain)
    에러 확인 : 템플릿을 발견할 수 없어서 에러 발생
  • ERROR: test_home_page_returns_correct_html (lists.tests.HomePageTest)
    어떤 테스트가 실패하는지 확인
  • response = home_page(request)
    테스트의 어느 코드에 문제가 있는지 확인 : home_page 함수 호출에 문제
  • return render(request, 'home.html')
    함수의 어느 부분이 에러를 발생시키는지 확인 : render

수정
Django가 왜 템플릿을 못 찾는 걸까? 템플릿 파일의 위치는 맞지만 아직 이 앱을 Django에 등록하지 않았기 때문이다.
config/settings.py 파일을 열어 수정

테스트 및 오류 확인
템플릿 파일을 찾았지만 텍스트 편집기가 자동으로 마지막에 라인(\n)을 강제로 추가해서 오류가 발생했다.

수정
strip()함수를 이용해 공백(\n)을 제거한다.

다시 테스트

리팩터링 작업은 마쳤다.
다음은 상수를 테스트하지 않고 템플릿을 이용해서 렌더링하는 것을 테스트하도록 수정해야 한다.

코드 수정
Django의 render_to_string 함수를 이용한다.
decode 함수는 reponse.content 바이트 데이터를 파이썬 유니코드 문자열로 변환한다. 이를 통해 바이트와 바이트를 비교하는 것이 아니라 문자열과 문자열을 비교할 수 있는 것이다.

커밋

$ git commit -m '템플릿을 이용하도록 홈페이지 뷰를 리팩터링'

리펙터링에 관해

저자는 처음부터 render_to_string 함수를 사용해 필요 없는 3개의 어설션을 삭제하고 예상 렌더링과 콘텐츠를 비교하는 부분만 남겨두고 싶었다고 한다. 하지만 이렇게 단계를 나누어 설명함으로 쉽게 이해를 돕고 많은 것을 한 번에 수정하지 않기를 당부하고 있다.
테스트 코드와 앱 코드를 한 번에 수정하는 것이 아니라 하나씩 수정해야 한다고 말하고 있다.

메인 페이지 추가 수정

기능 테스트를 진행해보자. (현재 h1 태그에서 실패)

수정

테스트 및 오류 확인

수정

테스트 및 오류 확인

수정

테스트 및 오류 확인

수정

테스트 및 오류 확인
현재 사용자의 입력을 받아 서버로 전송하는 작업을 할 수 없는 상황이다. 이 문제를 해결하려면 폼(form) 제출 처리를 구현해야 한다. 다음 장에서 다루도록 한다.

우선 정확한 오류 메세지를 수정해 놓는다.

예상된 오류 확인

커밋

git commit -m '템플릿을 이용한 메인 페이지HTML 생성'

정리 : TDD 프로세스

  • 기능 테스트
  • 단위 테스트
  • 단위 테스트 - 코드 주기
  • 리팩터링

0개의 댓글