Cet article est une série qui fait progresser le didacticiel officiel de Django. Cette fois, nous allons passer au cinquième article, "Création de votre première application Django, partie 5".
Résumé du tutoriel Django pour les débutants par les débutants ① (création de projet ~) Résumé du tutoriel Django pour les débutants par les débutants (Modèle, Admin) Résumé du tutoriel Django pour les débutants par les débutants ③ (Afficher) Résumé du didacticiel Django pour les débutants par les débutants ④ (Vue générique) Résumé du tutoriel Django pour les débutants par les débutants ⑤ (test) Résumé du tutoriel Django pour les débutants par les débutants ⑥ (fichier statique) Résumé des tutoriels Django pour les débutants par les débutants ⑦ (Personnaliser l'administrateur)
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
Ceci est évidemment incorrect car les dates futures ne sont pas récentes. Créez un test pour cela.
Par convention, les tests sont créés dans le fichier test.py
de l'application.
Tout nom commençant par test semble convenir.
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)
J'écris un test dans une sous-classe qui hérite de django.test.TestCase
.
Après cela, nous confirmons que la sortie de la méthode was_published_recently ()
est False
.
Vous pouvez exécuter le test en exécutant la commande suivante à partir du terminal.
$ python manage.py test polls
Ensuite, il sera exécuté comme suit.
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'...
Revenez à la définition de was_published_recently
et corrigez-la
polls/models.py
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
Maintenant, relancez le test.
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'...
Configurez un test plus complet pour was_published_recently
pour éviter qu'un bogue ne soit écrasé et un nouveau.
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 fournit un client qui vous permet de simuler l'interaction de l'utilisateur au niveau de la vue. Vous pouvez également l'utiliser dans tests.py ou dans shell.
Est-ce
Configurez un environnement de test avec shell.
$ python manage.py shell
>>> from django.test.utils import setup_test_environment
>>> setup_test_environment()
Installez le moteur de rendu de modèle avec setup_test_environment ()
.
Cela vous permet d'étudier certains attributs de la réponse que vous ne pouviez pas tester auparavant (comme 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?>]>
Le sondage qui n'a pas encore été publié est également visible maintenant, donc je vais le corriger.
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]
La page suivante était utile pour pub_date__lte
.
Résumé de l'utilisation de la méthode de filtrage QuerySet de Django
Écrivez un test pour voir si cette nouvelle implémentation fonctionne.
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
est une fonction qui facilite la création d'une question.
test_no_questions
ne crée pas de question et lorsque la question n'existe pas
-Le message "Aucun sondage n'est disponible." S'affiche.
・ La last_question_list est vide
Je vérifie.
Les tests suivants sont également testés pour voir si la situation est attendue dans certaines conditions. (Eh bien, les tests sont comme ça)
Les informations sur les autres tests sont résumées sur la page officielle ci-dessous. Test dans Django