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

2016-09-19

p.32-33

    urls.py를 편집하는 부분. Django 1.8부터는 url()에서 string view를 인자로 받지 않는다. 따라서 바뀐 superlists/urls.py는 아래와 같다.

from django.conf.urls import url
from lists import views

urlpatterns = [
    url(r'^$', views.home_page, name='home'),
    # url(r'^admin/', admin.site.urls),
]

여기까지만 고치고 실행하면
raise TypeError('view must be a callable or a list/tuple in the case of include().') TypeError: view must be a callable or a list/tuple in the case of include().
라는 에러가 나온다. 책과 다르다고 당황하지 말고 p.33 에 있는 lists/views.py까지 작성하면 테스트가 성공한다.

p.60-64

    p.64 마지막에 단위테스트를 통과한다고 하지만 되지않는다. csrf 토큰때문에 생긴 문제다. 스택오버플로의 답에 의하면 render_to_string()request=request 인자를 추가해주면 된다고 하지만 실상은 이것만 해서 되는것이 아니었다.

    print(expected_html), print(response.content.decode())해 보면 아래와 같이 출력된다.
csrf token을 제거하자: 1 둘을 비교 해 보면 input 태그의 value값이 다르다. 사실 이게 맞는 방법인지 모르겠는데 테스트 통과를 위해서 이 글을 참고하여 아예 없애버렸다. 이렇게 하니까 깔끔하게 통과되었다.

from django.template.loader import render_to_string
from django.core.urlresolvers import resolve
from django.test import TestCase
from django.http import HttpRequest
from django.shortcuts import render
import re
from lists.views import home_page

class HomePageTest(TestCase):

    def remove_csrf(self, origin):
        csrf_regex = r'<input[^>]+csrfmiddlewaretoken[^>]+>'
        return re.sub(csrf_regex, '', origin)

    def test_root_url_resolves_to_home_page_view(self):
        found = resolve('/')
        self.assertEqual(found.func, home_page)

    def test_home_page_returns_correct_html(self):
        request = HttpRequest()
        response = home_page(request)

        expected_html = self.remove_csrf(render_to_string('home.html', request=request))
        response_decode = self.remove_csrf(response.content.decode())

        self.assertEqual (response_decode, expected_html)

    def test_home_page_can_save_a_POST_request(self):
        request = HttpRequest()
        request.method = 'POST'
        request.POST['item_text'] = '신규 작업 아이템'

        response = home_page(request)

        self.assertIn('신규 작업 아이템', response.content.decode())
        expected_html = self.remove_csrf(render_to_string(
            'home.html',
            {'new_item_text': '신규 작업 아이템'},
            request=request,
        ))
        response_decode = self.remove_csrf(response.content.decode())

        self.assertEqual(response_decode, expected_html)