[PYTHON] Résumé du tutoriel Django pour les débutants par les débutants ⑤ (test)

introduction

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)

Création de votre première application Django, partie 5

https://docs.djangoproject.com/ja/3.0/intro/tutorial05/

Créer votre premier test

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.

Créer un test pour exposer les bogues

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.

Lancer le test

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'...

Corriger les bugs

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'...

Des tests plus complets

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)

Tester la vue

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

Client de test Django

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&#x27;s up?</a></li>\n    \n    </ul>\n\n'
>>> response.context['latest_question_list']
<QuerySet [<Question: What's up?>]>

Améliorez la vue

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

Tester une nouvelle vue

É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)

D'autres tests

Les informations sur les autres tests sont résumées sur la page officielle ci-dessous. Test dans Django

Recommended Posts

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 ③ (Afficher)
Résumé du tutoriel Django pour les débutants par les débutants ⑦ (Personnaliser l'administrateur)
Résumé du tutoriel Django pour les débutants par les débutants ⑥ (fichier statique)
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 ① (création de projet ~)
Résumé du didacticiel Django pour les débutants par les débutants ④ (Vue générique)
Résumé du didacticiel Python Django
Résumé de l'apprentissage automatique par les débutants de Python
[Pour les débutants] Django -Construction d'environnement de développement-
Qu'est-ce que le grattage? [Résumé pour les débutants]
Vue basée sur les fonctions Django
Vue basée sur les classes Django
Django
Résumé du tutoriel Django pour les débutants par les débutants ③ (Afficher)
Ajax dans Django (en utilisant la vue de classe générique)
Résumé du didacticiel Django Girls Première moitié
Lien récapitulatif des bases de Pandas pour les débutants
[Déprécié] Tutoriel pour débutant Chainer v1.24.0
Tutoriel TensorFlow -MNIST pour les débutants en ML
Résumé de Django
Test Django
Résumé de Django
[Explication pour les débutants] Tutoriel TensorFlow Deep MNIST
Fonctionnement Linux pour les débutants Résumé des commandes de base
Tutoriel Django (Créer une application de blog) ④ --Test d'unité
Un manuel pour les débutants réalisé par des débutants Python
Une introduction à la programmation orientée objet pour les débutants par les débutants
Tutoriel Python Django (2)
Résumé du didacticiel Python
Prise en charge de l'internationalisation avec Django 1.9
mémo du didacticiel django
Tutoriel Python Django (8)
Tutoriel Python Django (6)
À propos des fonctions d'ordre supérieur de Nim pour les débutants Nim écrites par les débutants Nim
Résumé du filtre Django
Réalisation du didacticiel TensorFlow MNIST pour débutants en ML
Tutoriel Python Django (7)
Tutoriel Python Django (1)
Tutoriel du didacticiel Python Django
Tutoriel Python Django (3)
Tutoriel Python Django (4)
[Français] Tutoriel officiel NumPy "NumPy: les bases absolues pour les débutants"
J'ai essayé le tutoriel MNIST de tensorflow pour les débutants.
Résumé des méthodes de prétraitement pour les débutants en Python (trame de données Pandas)
[Pour les débutants] Django Commandes fréquemment utilisées et collection de références
Jugement des nombres premiers par Python
Résumé du didacticiel d'apprentissage automatique
Paramètres Spacemacs (pour les débutants)
Didacticiel sur les associations polymorphes Django
tutoriel simple django oscar
Manuel python pour les débutants
Résumé Faker par langue
Note du didacticiel Django Girls
[Mémo] Résumé du code de test
Algorithme Dikstra pour les débutants
Résumé de l'apprentissage RAPIDS
OpenCV pour les débutants en Python
Résumé de la méthode d'essai
Automatisation des tests pour le travail
[Pour les débutants] Les bases de Python expliquées par Java Gold Part 2
[Traduisez approximativement le didacticiel TensorFlow en japonais] 1. MNIST pour les débutants en ML