Dieser Artikel ist eine Reihe, die das offizielle Django-Tutorial weiterentwickelt. Dieses Mal fahren wir mit dem fünften Artikel fort: "Erstellen Ihrer ersten Django-App, Teil 5".
Zusammenfassung des Django-Tutorials für Anfänger von Anfängern ① (Projekterstellung ~) Django-Tutorial-Zusammenfassung für Anfänger von Anfängern Model (Model, Admin) Zusammenfassung des Django-Tutorials für Anfänger von Anfängern ③ (Anzeigen) Zusammenfassung des Django-Tutorials für Anfänger von Anfängern ④ (generische Ansicht) Django Tutorial Zusammenfassung für Anfänger von Anfängern ⑤ (Test) Django Tutorial Zusammenfassung für Anfänger von Anfängern ⑥ (statische Datei) Zusammenfassung der Django-Tutorials für Anfänger durch Anfänger ⑦ (Admin anpassen)
https://docs.djangoproject.com/ja/3.0/intro/tutorial05/
python
>>> import datetime
>>> from django.utils import timezone
>>> from polls.models import Question
>>> # create a Question instance with pub_date 30 days in the future
>>> future_question = Question(pub_date=timezone.now() + datetime.timedelta(days=30))
>>> # was it published recently?
>>> future_question.was_published_recently()
True
Dies ist offensichtlich falsch, da zukünftige Daten nicht aktuell sind. Erstellen Sie hierfür einen Test.
Konventionell werden Tests in der Datei "test.py" innerhalb der Anwendung erstellt. Jeder Name, der mit test beginnt, scheint in Ordnung zu sein.
polls/tests.py
import datetime
from django.test import TestCase
from django.utils import timezone
from .models import Question
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)
Ich schreibe einen Test in einer Unterklasse, die django.test.TestCase
erbt.
Wir überprüfen dann, ob die Ausgabe der Methode was_published_recently ()
False
ist.
Sie können den Test ausführen, indem Sie den folgenden Befehl vom Terminal aus ausführen.
$ python manage.py test polls
Dann wird es wie folgt ausgeführt.
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)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/path/to/mysite/polls/tests.py", line 16, 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'...
Gehen Sie zurück zur Definition von "was_published_recently" und korrigieren Sie sie
polls/models.py
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
Führen Sie nun den Test erneut aus.
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'...
Richten Sie einen umfassenderen Test für "was_published_recently" ein, um zu verhindern, dass ein Fehler behoben wird und ein neuer.
polls/tests.py
def test_was_published_recently_with_old_question(self):
"""
was_published_recently() returns False for questions whose pub_date
is older than 1 day.
"""
time = timezone.now() - datetime.timedelta(days=1, seconds=1)
old_question = Question(pub_date=time)
self.assertIs(old_question.was_published_recently(), False)
def test_was_published_recently_with_recent_question(self):
"""
was_published_recently() returns True for questions whose pub_date
is within the last day.
"""
time = timezone.now() - datetime.timedelta(hours=23, minutes=59, seconds=59)
recent_question = Question(pub_date=time)
self.assertIs(recent_question.was_published_recently(), True)
Django bietet einen Client, mit dem Sie die Benutzerinteraktion auf Ansichtsebene simulieren können. Sie können dies auch in tests.py oder in der Shell verwenden.
Ist das
Richten Sie eine Testumgebung mit Shell ein.
$ python manage.py shell
>>> from django.test.utils import setup_test_environment
>>> setup_test_environment()
Installieren Sie den Template-Renderer mit setup_test_environment ()
.
Auf diese Weise können Sie einige Attribute der Antwort untersuchen, die zuvor nicht getestet werden konnten (z. B. "response.context").
>>> from django.test import Client
>>> # create an instance of the client for our use
>>> client = Client()
>>> # get a response from '/'
>>> response = client.get('/')
Not Found: /
>>> # we should expect a 404 from that address; if you instead see an
>>> # "Invalid HTTP_HOST header" error and a 400 response, you probably
>>> # omitted the setup_test_environment() call described earlier.
>>> response.status_code
404
>>> # on the other hand we should expect to find something at '/polls/'
>>> # we'll use 'reverse()' rather than a hardcoded URL
>>> 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/1/">What's up?</a></li>\n \n </ul>\n\n'
>>> response.context['latest_question_list']
<QuerySet [<Question: What's up?>]>
Die Umfrage, die noch nicht veröffentlicht wurde, ist jetzt auch sichtbar, daher werde ich sie beheben.
polls/views.py
from django.utils import timezone
def get_queryset(self):
"""
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]
Die folgende Seite war nützlich für pub_date__lte
.
Zusammenfassung der Verwendung der QuerySet-Filtermethode von Django
Schreiben Sie einen Test, um festzustellen, ob diese neue Implementierung funktioniert.
polls/tests.py
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_no_questions(self):
"""
If no questions exist, an appropriate message is displayed.
"""
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):
"""
Questions with a pub_date in the past are displayed on the
index page.
"""
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):
"""
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'], [])
def test_future_question_and_past_question(self):
"""
Even if both past and future questions exist, only past questions
are displayed.
"""
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):
"""
The questions index page may display multiple questions.
"""
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.>']
)
create_question
ist eine Funktion, die das Erstellen einer Frage erleichtert.
test_no_questions
erstellt keine Frage und wenn die Frage nicht existiert
-Die Meldung "Es sind keine Umfragen verfügbar." Wird angezeigt.
・ Die Liste der neuesten Fragen ist leer
Ich überprüfe.
Die folgenden Tests werden auch getestet, um festzustellen, ob die Situation unter bestimmten Bedingungen erwartet wird. (Nun, Testen ist so)
Informationen zu anderen Tests sind auf der offiziellen Seite unten zusammengefasst. Testen in Django
Recommended Posts