장고에서는 자체적으로 test를 위한 라이브러리를 제공한다.
from django.test import TestCase, Client
from bs4 import BeautifulSoup
from .models import Post
class TestView(TestCase):
def setUp(self):
self.client = Client()
def test_post_list(self):
# 1.1 포스트 목록 페이지를 가져온다.
response = self.client.get('/blog/')
# 1.2 정상적으로 페이지가 로드된다.
self.assertEqual(response.status_code, 200)
# 1.3 페이지 타이틀은 'Blog'이다.
soup = BeautifulSoup(response.content, 'html.parser')
self.assertEqual(soup.title.text, 'Blog')
# 1.4 내비게이션 바가 있다.
navbar = soup.nav
# 1.5 Blog, About Me라는 문구가 내비게이션 바에 있다.
self.assertIn('Blog', navbar.text)
self.assertIn('About me', navbar.text)
# 2.1 메인 영역에 게시물이 하나도 없다면
self.assertEqual(Post.objects.count(), 0)
# 2.2 '아직 게시물이 없습니다'라는 문구가 보인다.
main_area = soup.find('div', id='main-area')
self.assertIn('아직 게시물이 없습니다', main_area.text)
# 3.1 게시물이 2개 있다면
post_001 = Post.objects.create(
title='첫 번째 포스트입니다.',
content='Hello World. We are the world.',
)
post_002 = Post.objects.create(
title='두 번째 포스트입니다.',
content='1등이 전부는 아니잖아요?',
)
self.assertEqual(Post.objects.count(), 2)
# 3.2 포스트 목록 페이지를 새로고침했을 때,
response = self.client.get('/blog/')
soup = BeautifulSoup(response.content, 'html.parser')
self.assertEqual(response.status_code, 200)
# 3.3 메인 영역에 포스트 2개의 타이틀이 존재한다.
main_area = soup.find('div', id='main-area')
self.assertIn(post_001.title, main_area.text)
self.assertIn(post_002.title, main_area.text)
# 3.4 '아직 게시물이 없습니다'라는 문구는 더 이상 보이지 않는다.s
self.assertNotIn('아직 게시물이 없습니다', main_area.text)
위와 같이 장고의 test 모듈을 이용해 테스트 코드를 구현할 수 있다.
TestCase는 특정 모듈에 대한 테스트 클래스를 작성할 때, 상속하여 구현할 수 있다.
Clinet는 테스팅 목적으로 사용하기 위한 가상의 클라이언트이고, GET과 POST 요청을 받거나 서버의 구체적인 응답 객체를 제공한다. 결국 클라이언트에게 제공되는 것을 그대로 테스트할 수 있도록 서버 응답 캡쳐를 주는 기능을 수행한다.
client.get(URL)과 같이 URL을 전달하면 server response를 받을 수 있다.
TestCase에서 제공하는 assertion
assertEqual(a, b): a가 b와 같은 값인지 비교
assertIn(a, b): a가 b에 포함되는지 비교
위 두 개의 연산만으로 대부분의 assertion을 구현하는 것이 가능하다. 다른 assert문을 사용해서 구현하면 편한 것은 있겠지만 라이브러리에 의존하게 되고 가장 바뀌지 않을 것 같은 두 함수를 사용해서 루프를 이용해 여러 번 사용하거나 미리 연산한 값을 삽입해서 테스트하는 것이 바람직하다고 생각한다.