Closed8
Djangoのチュートリアルをなぞってみる その7:テスト
前回のスクラップの続き
Django公式チュートリアルをなぞっています。
今回は以下のページです。
テストコードを書いてみる。
diff --git a/mysite/polls/tests.py b/mysite/polls/tests.py
index 7ce503c..1179e3f 100644
--- a/mysite/polls/tests.py
+++ b/mysite/polls/tests.py
@@ -1,3 +1,17 @@
+import datetime
+
from django.test import TestCase
+from django.utils import timezone
+
+from .models import Question
+
-# Create your tests here.
+class QuestionModelTests(TestCase):
+ def test_was_published_recently_with_future_question(self):
+ """
+ was_published_recently() returns False for questions whose pub_date
+ is in the future.
+ """
+ time = timezone.now() + datetime.timedelta(days=30)
+ future_question = Question(pub_date=time)
+ self.assertIs(future_question.was_published_recently(), False)
python manage.py test
コマンドでテストが実行できる。
$ python manage.py test polls
Found 1 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionModelTests.test_was_published_recently_with_future_question)
was_published_recently() returns False for questions whose pub_date
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ubuntu/django-tutorial/mysite/polls/tests.py", line 17, 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'...
tests.py
のファイル名を変えてみたけど、同じようにテストが実行できた。polls
ディレクトリの中からテストケースを探してくれるようだ。
ディレクトリを掘って中に入れてみたら、ダメだった。polls
ディレクトリ直下に必要みたい。
テストケースのファイルをコピーして2つにしたら、2つとも実行された。
$ python manage.py test polls
Found 2 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
FF
======================================================================
FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionModelTests.test_was_published_recently_with_future_question)
was_published_recently() returns False for questions whose pub_date
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ubuntu/django-tutorial/mysite/polls/tests.py", line 17, in test_was_published_recently_with_future_question
self.assertIs(future_question.was_published_recently(), False)
AssertionError: True is not False
======================================================================
FAIL: test_was_published_recently_with_future_question (polls.tests2.QuestionModelTests.test_was_published_recently_with_future_question)
was_published_recently() returns False for questions whose pub_date
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ubuntu/django-tutorial/mysite/polls/tests2.py", line 17, in test_was_published_recently_with_future_question
self.assertIs(future_question.was_published_recently(), False)
AssertionError: True is not False
----------------------------------------------------------------------
Ran 2 tests in 0.002s
FAILED (failures=2)
Destroying test database for alias 'default'...
テストに成功した時の出力例
$ python manage.py test polls
Found 1 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Destroying test database for alias 'default'...
次はViewのテストコード。
テストコードに以下のコード断片を追加。
from django.utils import timezone
from django.urls import reverse
def create_question(question_text, days):
"""
Create a question with the given `question_text` and published the
given number of `days` offset to now (negative for questions published
in the past, positive for questions that have yet to be published).
"""
time = timezone.now() + datetime.timedelta(days=days)
return Question.objects.create(question_text=question_text, pub_date=time)
class QuestionIndexViewTests(TestCase):
def test_future_question(self):
"""
Questions with a pub_date in the future aren't displayed on
the index page.
"""
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"], [])
viewのindexのバグ修正
diff --git a/mysite/polls/views.py b/mysite/polls/views.py
index a6a34e6..3da039b 100644
--- a/mysite/polls/views.py
+++ b/mysite/polls/views.py
@@ -2,6 +2,7 @@ from django.http import HttpResponse, Http404, HttpResponseRedirect
from django.shortcuts import get_object_or_404, render
from django.template import loader
from django.urls import reverse
+from django.utils import timezone
from django.views import generic
from .models import Question, Choice
@@ -11,8 +12,13 @@ class IndexView(generic.ListView):
context_object_name = "latest_question_list"
def get_queryset(self):
- """Return the last five published questions."""
- return Question.objects.order_by("-pub_date")[:5]
+ """
+ Return the last five published questions (not including those set to be
+ published in the future).
+ """
+ return Question.objects.filter(pub_date__lte=timezone.now()).order_by("-pub_date")[
+ :5
+ ]
def detail(request, question_id):
try:
これでテストが成功する。self.assertContains(response, "No polls are available.")
が成功する。テスト実行時はSQLiteの中のデータは関係なく、空の状態から実行されるみたいだ。
このスクラップは2023/08/09にクローズされました