TDD란? 테스트 주도 개발로 테스트 코드부터 구현 후 테스트 코드에 맞게 기능을 구현하는 것. 테스트가 개발을 이끌어 나간다고 보면 된다.
TDD의 과정 순환 : 테스트를 먼저 만들고 테스트를 통과하기 위한 것을 짜는 것 즉, 만드는 과정에서 우선 테스트를 작성하고 그걸 통과하는 코드를 만들고 테스트하여 리펙토링 작업 (예외처리, 중복제거, 추가 기능)을 해준다. 이 과정을 반복하면서 제대로 동작하는지에 대한 피드백을 적극적으로 받는 것
TDD를 해야하는 경우 : 불확실성이 높을 때 '피드백'과 '협력'이 중요하다. 이를 위해 아래와 같은 경우 TDD방식으로 개발해야한다
- 처음해보는 프로그램 주제
- 요구조건이 바뀔 수 있는 프로젝트
- 개발하는 중에 코드를 많이 바꿔야 된다고 생각하는 경우
- 개발하고 나서 이 코드를 타인이 유지보수할지 모르는 경우
TDD의 장점
- 결함이 줄어든다
- 코드 복잡도가 떨어지고 깨끗한 코드가 나온다
- 유지보수 비용이 낮아진다
- 코드 구현 과정에서 빠르게 피드백을 받을 수 있다
TDD의 단점
- 생산성이 저하된다
TDD TEST의 종류
- UNIT 테스트 : 가장 작은 단위로 테스트
- 통합 테스트 : 단위 테스트가 끝난 모듈을 통합하는 과정에서 발생할 수 있는 오류를 찾는 테스트
- 기능 테스트 : 기능 테스트는 통합 테스트 후 전체적인 기능이 잘 작동하는지 검사하는 테스트
- 리그레션 테스트 : 테스트된 프로그램의 테스팅을 반복하는 테스트
UNIT -> 통합 -> 기능 -> 리그레션 순이다
예외처리도 해야한다
- test 파일의 method 이름도 test로 시작해야한다
- test 파일은 django.test 모듈의 TestCase class를 상속받아야한다
- 함수 하나하나가 단위다
- assert : 검증하는 코드
- Django는 url과 함수를 매핑한다
- resolve는 주어진 url에 매핑된 함수를 반환받는 것
- test를 위해 url 추가
- test를 위해 view에 함수 추가
- assertEqual은 url에 매핑된 함수가 create 함수가 맞는지 확인하는 것이다
- test를 돌리면 Django가 test 이름이 들어간 파일들을 찾아 test를 진행한다
- .이 하나의 test가 진행됬다는 것이다
- setUp : 가장 먼저 실행이되서 테스트 케이스에 필요한 데이터를 생성 하는 메소드
- client : client란 post와 get같은 요청을 보낼수있게 해주는 객체
- self.assertEqual(response.status_code,200) : 요청 비교. 잘 요청이 갔다면 200일것이다
- self.assertTemplateUsed(response, 'board/create.html') : 올바른 템플릿을 썻는지 확인
- template을 추가하고 view에서 render하게 함수 생성
- 원하는 기능만 test 가능하다. '.'을 이용해 내부로 들어간다. board의 tests package의 test_views 파일을 test한다
- .이 2개면 test가 두 개 실행됬다는 것. 이때 URL 테스트 후 VIEW 테스트가 실행된다. 이는 VIEW에서 URL을 사용하여 불러오기에, URL에서 실패하면 VIEW로 넘어가지 않는다
test를 할때는 되는 상황만 test하면 안된다
로그인 했을 때와 안했을 때로 나눈다
test는 test가 끝나면 test도중 생성된 Data가 삭제되므로 실제 DB에 영향이 없다
- 로그인과 같은 사용자의 동작은 Client를 통해 한다
- User class를 통해 user를 생성하고, client를 통해 로그인을 구현한다. create_user 안에 username과 password를 넣어 직접 생성해준다
- 302는 redirect시 상태코드다
- test 위해 view 수정
- test를 위해 template를 생성하고, url을 수정한다
- 먼저, model을 생성해준다
- model도 생성하면 model에 대한 test를 해야한다
- setUp으로 user와 post Data 생성
- CRU에 대한 TEST
- D에 대한 TEST. 삭제 후 id = 1이 존재하는지 검사하여, False가 출력되는지 확인한다
- TEST 성공. 잘 작동된다
로그인이 되어있어야 한다
- test_view에 검사 함수 구현
- post로 Data를 받아와 저장하고, 작성한 title을 기준으로 객체를 가져와 post로 잘 저장됬는지 확인한다
- 검사 함수에서 작성한 response를 view에서 request로 받아와 저장하여 TEST를 진행한다. 실제 DB에는 저장되지 않는다
- 그 다음 redirect가 잘 됬는지 확인한다
- 검사 함수에 대한 view 함수 구현
- 잘 실행된다. 이처럼 TDD에서는 검사 함수를 만들고, 검사 함수에 대해 TEST할 함수를 구현한다
게시글 제목이 5글자 미만일때 error page로 redirect되는지 TEST한다
- 저장하기 전에 제목을 가져와 len을 비교하여 error page로 redirect되게 한다
- error 발생에 대한 Test이므로, 저장이 안될 것 이다. 따라서 저장과 관련된 검사 기능을 잠깐 없애준다
- 잘 실행된다
- redirect url도 검사 가능하다. redirect url은 response.HttpResponseRedirect에 저장되있다
- 이렇게도 redirect 검사가 가능하다
Django의 전달 message들은 contrib.messages에 저장되있다
create get 페이지에 갈려면 로그인을 해야하는데, 현재 해당 기능을 구현 안했으므로 관리자 계정으로 로그인 상태를 만든다
관리자 페이지에 로그인하고, create 페이지에 접속한다
잘 접속된다
form으로 담아와서 context에 담아 error 검사하는 변수를 생성한다. 이때 post 객체를 생성해서 제목만 담아와 검사하여 error 변수를 설정하고, 나머지 내용을 받아와서 error 변수에 따라 동작을 정의한다
context 형태로 사용하는 이유는 다시 사용자에게 error를 이용해 잘못 작성된 내용을 form에 담아 전달하기 위해서다. 이 context에 잘못 작성된 내용, error 변수, messages가 담긴다
제목이 5글자 이하면 error 페이지로 넘어간다
messages에도 등급이 있다
messages는 context에 자동으로 담겨 전달된다
messages class를 import한다
add_message를 통해 message를 추가한다. ERROR는 등급이고, 뒤에는 보낼 message 내용이다
messages는 list형태로 오기에 for tag를 사용해야한다
또한 내부에서 tag가 ERROR가 맞는지 검사한다
messages는 list 형태로 전달되며, context에 담겨 사용자에게 전달된다. status를 400으로 설정한다
message가 잘 출력된다
messages는 list 형태이기에 len을 통해 들어있는 message 갯수를 확인할 수 있다. 이때 response.context['messages']는 기본 스토리지 클래스인 FallbackStorage 클래스로 오기에 이를 list()안에 넣어줘야한다
이 context에는 messages만 존재하는데, 응답에는 받아온 context Data가 없기 때문이다
messages[]는 객체로 받기에 문자열 비교를 할려면 str에 담아야한다
위에 view에서 render시 status를 400으로 설정되게 했으므로 status_code를 400으로 TEST한다
잘 실행된다