Nice to meet you, everyone. I'm going to publish a memorandum of the process of creating a voting (poll) application using Django. Since I am a beginner of Qiita, please understand that some parts may be difficult to read.
series
-[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-No. 0- -[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 1- -[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 2- -[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 3- -[Beginner] [Python / Django] A fledgling web engineer tried a Django tutorial-Part 4-
I'll write the code to use with Django's automated testing feature.
What code do you need to test Django? First, run the test interactively.
Test content: Confirm that the was_published_recently function is False when the Question pub_date is in the future date (30 days from today). Test result: FAILD (The expected behavior of was_published_recently is False, but the actual behavior is True)
(poll-HcNSSqhc) C:\django\poll>python manage.py shell
Python 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:37:30) [MSC v.1927 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>
>>> import datetime
>>> from django.utils import timezone
>>> from polls.models import Question
>>>
>>> future_question = Question(pub_date=timezone.now()+datetime.timedelta(days=30))
>>> future_question.was_published_recently()
True
>>>
Code this. The expected behavior in self.assertIs is False.
polls/tests.py
from django.test import TestCase
import datetime
from django.utils import timezone
from .models import Question
# Create your tests here.
class QuestionModelTests(TestCase):
def test_was_published_recently_whit_future_question(self):
future_question = Question(pub_date=timezone.now() + datetime.timedelta(days=30))
self.assertIs(future_question.was_published_recently(), False)
Now let's run the test. Of course it's not interactive.
(poll-HcNSSqhc) C:\django\poll>python manage.py test polls
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_was_published_recently_whit_future_question (polls.tests.QuestionModelTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "C:\django\poll\polls\tests.py", line 13, in test_was_published_recently_whit_future_question
self.assertIs(future_question.was_published_recently(), False)
AssertionError: True is not False
----------------------------------------------------------------------
Ran 1 test in 0.002s
FAILED (failures=1)
Destroying test database for alias 'default'...
(poll-HcNSSqhc) C:\django\poll>
It is returning FAILD firmly. (The expected behavior of was_published_recently is False, but the actual behavior is True)
Now let's debug.
polls/models.py
def was_published_recently(self):
return timezone.now() - datetime.timedelta(days=1) <= self.pub_date <= timezone.now()
(poll-HcNSSqhc) C:\django\poll>python manage.py test polls
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
Destroying test database for alias 'default'...
(poll-HcNSSqhc) C:\django\poll>
It was OK. (The expected behavior of was_published_recently is False, and the actual behavior is False.)
Let's add more test items for the same class. A limit value test item is added.
polls/tests.py
def test_was_published_recently_with_old_question(self):
old_question = Question(pub_date=timezone.now() - datetime.timedelta(days=1, seconds=1))
self.assertIs(old_question.was_published_recently(), False)
def test_was_published_recently_with_recently_question(self):
recently_question = Question(pub_date=timezone.now(
) - datetime.timedelta(hours=23, minutes=59, seconds=59))
self.assertIs(recently_question.was_published_recently(), True)
(poll-HcNSSqhc) C:\django\poll>python manage.py test polls
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
...
----------------------------------------------------------------------
Ran 3 tests in 0.004s
OK
Destroying test database for alias 'default'...
(poll-HcNSSqhc) C:\django\poll>
OK is displayed.
Use the Client class to test your views in Django. First, run the test interactively.
Test content: The view "http://127.0.0.1/polls" exists Test result: HTTP200 and content can be obtained
(poll-HcNSSqhc) C:\django\poll>python manage.py shell
Python 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:37:30) [MSC v.1927 32 bit (Intel)] on win32
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
>>> from django.urls import reverse
>>> client = Client()
>>> response = client.get(reverse('polls:index'))
>>>
>>> response.status_code
200
>>>
>>> response.content
b'\n <ul>\n \n <li><a href="/polls/5/">What's this?</a></li>\n \n </ul>\n'
>>>
>>> response.context['latest_question_list']
<QuerySet [<Question: What's this?>]>
>>>
There is a problem displaying votes that are dated in the future, so let's fix it.
Question.objects.filter () means to filter, and pub_date__lte = timezone.now () is a conditional expression whose pub_date is less than or equal to timezone.now () (less than equal).
polls/views.py
from django.utils import timezone
class IndexView(generic.ListView):
***
def get_queryset(self):
return Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[:5]
Prepare the test code.
polls/tests.py
from django.urls import reverse
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 QuestionIndexViewTest(TestCase):
#HTTP200, screen message: No polls are available., Question list: empty
def test_no_question(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'], [])
#Question list: Past question.
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.>'])
#Question list: empty(Future questions are not displayed)
def test_feature_question(self):
create_question(question_text="Feature question.", days=30)
response = self.client.get(reverse('polls:index'))
self.assertContains(response, "No polls are available.")
self.assertQuerysetEqual(response.context['latest_question_list'], [])
#Question list: Past question.(Future questions are not displayed)
def test_feature_question_and_past_question(self):
create_question(question_text="Feature question.", days=30)
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.>'])
#Question list: Past question1.、Past question2.
#Note that the question list is retrieved in the order of the latest posts, so the creation order and retrieval order will be weak.
def test_tow_past_question(self):
create_question(question_text="Past question1.", days=-30)
create_question(question_text="Past question2.", days=-10)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(response.context['latest_question_list'], [
'<Question: Past question2.>', '<Question: Past question1.>'])
(poll-HcNSSqhc) C:\django\poll>python manage.py test polls
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
........
----------------------------------------------------------------------
Ran 8 tests in 0.063s
OK
Destroying test database for alias 'default'...
(poll-HcNSSqhc) C:\django\poll>
OK is displayed.
The detail view is also ready to display question details for future dates, so let's fix it.
polls/views.py
class DetailView(generic.DetailView):
***
def get_queryset(self):
return Question.objects.filter(pub_date__lte=timezone.now())
polls/tests.py
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)
(poll-HcNSSqhc) C:\django\poll>python manage.py test polls
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..........
----------------------------------------------------------------------
Ran 10 tests in 0.088s
OK
Destroying test database for alias 'default'...
(poll-HcNSSqhc) C:\django\poll>
That's all for today. Thank you very much.
Recommended Posts