์๋ํ๋ ํ
์คํธ๋ ์์์ shell
์ ์ฌ์ฉํด ๋ฉ์๋์ ๋์์ ๊ฒ์ฌํ๊ฑฐ๋ ๋ฐ์ดํฐ๋ฅผ ์
๋ ฅํด์ ํ
์คํธ ํ๊ฒ๊ณผ ๋ค๋ฅด์ง ์๋ค. ์ฐจ์ด์ ์ ํ
์คํธ ์์
์ด ์์คํ
์์ ์ํ๋๋ค๋ ์ ์ด๋ค. ํ๋ฒ ํ
์คํธ ์ธํธ๋ฅผ ์์ฑํ ํ์๋ ์ฑ์ ๋ณ๊ฒฝํ ๋ ์๋ ํ
์คํธ๋ฅผ ์ํํ์ง ์์๋ ์๋ ์๋๋๋ก ์ฝ๋๊ฐ ์๋ํ๋์ง ํ์ธํ ์ ์๋ค.
์๋ํ๋ ํ
์คํธ๋ฅผ ํตํด ์๊ฐ์ ์ ์ฝํ ์ ์๋ค. ํ
์คํธ๋ฅผ ์์ฑํ๋ ์์
์ ์ดํ๋ฆฌ์ผ์ด์
์ ์๋์ผ๋ก ํ
์คํธํ๊ฑฐ๋ ์๋ก ๋ฐ๊ฒฌ๋ ๋ฌธ์ ์ ์์ธ์ ํ์ธํ๋ ๋ฐ ๋ง์ ์๊ฐ์ ํฌ์ํ๋ ๊ฒ๋ณด๋ค ํจ์ฌ ๋ ํจ๊ณผ์ ์
๋๋ค.
๋ฌธ์ ๋ฅผ ์๋ณํ๋ ๊ฒ์ด ์๋๋ผ ์๋ฐฉํ ์ ์๋ค.
์ ํ๋ฆฌ์ผ์ด์
ํ
์คํธ๋ ์ผ๋ฐ์ ์ผ๋ก <app_name>/tests.py
ํ์ผ์ ์๋ค. ํ
์คํธ ์์คํ
์ test๋ก ์์ํ๋ ๋ฉ์๋๋ฅผ ์๋์ผ๋ก ์ฐพ๋๋ค.
Model Test
# polls/models.py
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return '%s >> %s' % (self.question_text, self.pub_date)
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
# polls/test.py
import datetime
from django.utils import timezone
from django.test import TestCase
from .models import Question
# Create your tests here.
class QuestionMdoelTests(TestCase):
def test_was_published_recently_with_future_question(self):
time = timezone.now() + datetime.timedelta(days=30)
future_question = Question(pub_date=time)
self.assertIs(future_question.was_published_recently(),False)
๋ค์์ ๊ฐ๋จํ ์์์ด๋ค. ์ง๊ธ ์๊ฐ๋ณด๋ค 30์ผ ์ดํ์ Question์ ์์ฑํ ๋ค ์ต๊ทผ์ ์์ฑํ๊ฒ ๋ง๋์ง ํ์ธํ๋ ๊ฒ์ด๋ค.
$ python manage.py test <app_name>
$ python manage.py test polls
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionMdoelTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/jeongdaye/Documents/study/test_app/mysite2/polls/tests.py", line 13, in test_was_published_recently_with_future_question
self.assertIs(future_question.was_published_recently(),False)
AssertionError: True is not False
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)
Destroying test database for alias 'default'...
์ฐ๋ฆฌ๋ False๊ฐ return๋๊ธฐ๋ฅผ ๋ฐ๋ผ๋๋ฐ True๊ฐ ๋ฐํ๋๋ค๋ ๊ฒ์ ๋ฐ๊ฒฌํ ์ ์๋ค.
# Create your models here.
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return '%s >> %s' % (self.question_text, self.pub_date)
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
๋ค์๊ณผ ๊ฐ์ด was_published_recently()
๋ฅผ ์์ ํด์ฃผ๊ณ ํ
์คํธ ๋ช
๋ น์ด๋ฅผ ์คํํด๋ณด๋ฉด ํ
์คํธ๋ฅผ ํต๊ณผํ ๊ฒ์ ํ์ธํ ์ ์๋ค.
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Destroying test database for alias 'default'...
View Test
Shell์ ํ
์คํธ ํ๊ฒฝ ๊ตฌ์ฑํ๊ธฐ
$ python manage.py shell
Python 3.7.2 (default, Mar 5 2019, 16:08:31)
[Clang 10.0.0 (clang-1000.10.44.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
>>> from django.test.utils import setup_test_environment
>>> setup_test_environment()
์ด ๋ฉ์๋๋ ํ
์คํธ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์ค์ ํ์ง ์๊ธฐ ๋๋ฌธ์ ํ์ฌ ์ฌ์ฉ์ค์ธ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์์์ ๋๊ฒ๋๋ฉฐ ๊ฒฐ๊ณผ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ฐ์ดํฐ์ ๋ฐ๋ผ ๋ค๋ฅด๊ฒ ๋์จ๋ค.
>>> from django.test import Client
>>> client = Client()
ํ
์คํธ ํด๋ผ์ด์ธํธ๋ฅผ ์์ฑํ์ฌ ์์
์ ์ํํ ์ ์๋ค.
>>> from django.test.utils import setup_test_environment
>>> setup_test_environment()
>>> from django.test import Client
>>> client = Client()
>>> from django.urls import reverse
>>> response = client.get(reverse('polls:index'))
>>> response.status_code
200
>>> response.content
b'\n <ul>\n \n <li><a href="/polls/2/">Are you happy?</a></li>\n \n <li><a href="/polls/1/">What's your name?</a></li>\n \n </ul>\n'
>>> response.context['latest_question_list']
<QuerySet [<Question: Are you happy? >> 2019-04-05 05:54:39>, <Question: What's your name? >> 2019-04-04 06:21:55.323284>]>
>>>
def create_question(question_text, days):
time = timezone.now() + datetime.timedelta(days=days)
return Question.objects.create(question_text=question_text, pub_date=time)
class QuestionIndexViewTests(TestCase):
def test_no_questions(self):
response = self.client.get(reverse('polls:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "No polls are available.")
self.assertQuerysetEqual(response.context['latest_question_list'], [])
def test_past_question(self):
create_question(question_text="Past question.", days=-30)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question.>']
)
def test_future_question(self):
create_question(question_text="Future question.", days=30)
response = self.client.get(reverse('polls:index'))
self.assertContains(response, "No polls are available.")
self.assertQuerysetEqual(response.context['latest_question_list'], [])
def test_future_question_and_past_question(self):
create_question(question_text="Past question.", days=-30)
create_question(question_text="Future question.", days=30)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question.>']
)
def test_two_past_questions(self):
create_question(question_text="Past question 1.", days=-30)
create_question(question_text="Past question 2.", days=-5)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question 2.>', '<Question: Past question 1.>']
)
class QuestionDetailViewTests(TestCase):
def test_future_question(self):
future_question = create_question(question_text='Future question.', days=5)
url = reverse('polls:detail', args=(future_question.id,))
response = self.client.get(url)
self.assertEqual(response.status_code, 404)
def test_past_question(self):
past_question = create_question(question_text='Past Question.', days=-5)
url = reverse('polls:detail', args=(past_question.id,))
response = self.client.get(url)
self.assertContains(response, past_question.question_text)
๋ค์๊ณผ ๊ฐ์ด View์ ๋ํด์๋ ํ
์คํธ ์ฝ๋๋ฅผ ์์ฑํ ์ ์๋ค. ํ
์คํธ๋ฅผ ํ ๋๋ ๋ง์ด ํ ์๋ก ์ข๋ค.