[Débutant] [Python / Django] Un ingénieur Web débutant a essayé un tutoriel Django - Partie 5

introduction

Ravi de vous rencontrer, tout le monde. Je publierai le processus de création d'une application de vote (sondage) en utilisant Django comme mémorandum. Puisque je suis un débutant de Qiita, veuillez comprendre qu'il peut être difficile à lire.

séries

Commence travail

Présentation des tests automatisés

J'écrirai le code à utiliser dans la fonction de test automatique de Django.

Créer votre premier test

De quel type de code avez-vous besoin pour tester Django? Tout d'abord, exécutez le test de manière interactive.

Contenu du test: confirmez que la fonction was_published_recently a la valeur False lorsque la question pub_date est à la date future (30 jours à compter d'aujourd'hui). Résultat du test: FAILD (le comportement attendu de was_published_recently est faux, mais le comportement réel est vrai)


(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
>>>

Codez ceci. Le comportement attendu dans self.assertIs est 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)

Maintenant, exécutons le test. Bien sûr, ce n'est pas interactif.


(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>

Il revient fermement FAILD. (Le comportement attendu de was_published_recently est False, mais le comportement réel est True)

Maintenant, nous allons déboguer.

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>

C'était ok. (Le comportement attendu de was_published_recently est False et le comportement réel est False.)

Des tests plus complets

Ajoutons plus d'éléments de test pour la même classe. Un élément de test de valeur limite est ajouté.

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

Tester la vue

Utilisez la classe Client pour tester la vue dans Django. Tout d'abord, exécutez le test de manière interactive.

Contenu du test: la vue "http://127.0.0.1/polls" existe Résultat du test: HTTP200 et le contenu peuvent être obtenus


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

Améliorez la vue

Il y a un problème d'affichage des votes qui sont datés dans le futur, donc corrigeons-le.

Question.objects.filter () signifie filtrer, et pub_date__lte = timezone.now () est une expression conditionnelle dont pub_date est inférieur ou égal à timezone.now () (inférieur à égal).

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]

Tester une nouvelle vue

Préparez le code de test.

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, message d'écran: aucun sondage n'est disponible., Liste de questions: vide
    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'], [])

    #Liste de questions: question précédente.
    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.>'])

    #Liste de questions: vide(Les questions futures ne sont pas affichées)
    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'], [])

    #Liste de questions: question précédente.(Les questions futures ne sont pas affichées)
    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.>'])

    #Liste de questions: Question précédente1.、Past question2.
    #Notez que la liste de questions est récupérée dans l'ordre des derniers articles, donc l'ordre de création et l'ordre de récupération seront faibles.
    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 s'affiche.

Test DetailView

La vue détaillée est également prête à afficher les détails des questions pour les dates futures, alors corrigeons-le.

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>

C'est tout pour aujourd'hui. Merci beaucoup.

Recommended Posts

[Débutant] [Python / Django] Un ingénieur Web débutant a essayé un didacticiel Django-Partie 7-
[Débutant] [Python / Django] Un ingénieur Web débutant a essayé un didacticiel Django - Partie 1-
[Débutant] [Python / Django] Un ingénieur Web débutant a essayé un didacticiel Django - Partie 2
[Débutant] [Python / Django] Un ingénieur web débutant a essayé un didacticiel Django - Partie 0-
[Débutant] [Python / Django] Un ingénieur Web débutant a essayé un tutoriel Django - Partie 5
[Débutant] [Python / Django] Un ingénieur Web débutant a essayé un tutoriel Django - Partie 6
[Débutant] [Python / Django] Un ingénieur Web débutant a essayé un didacticiel Django - Partie 4
[Débutant] [Python / Django] Un ingénieur Web débutant a essayé un didacticiel Django - Partie 3
Framework Web Django Python
Déployer des applications Web Python 3.6 / Django / Postgres sur Azure
(Python) Essayez de développer une application Web en utilisant Django
Le débutant de la CTF a tenté de créer un serveur problématique (Web) [Problème]
Web scraping débutant avec python
Un ingénieur en arts libéraux a essayé de frapper 100 processus linguistiques en Python 02
Un débutant en python a essayé de faire un stage dans une entreprise informatique
Un ingénieur en arts libéraux a essayé de frapper 100 processus linguistiques en Python 01
Un ingénieur en arts libéraux a essayé de frapper 100 processus linguistiques en Python 00
[Python / Django] Créer une API Web qui répond au format JSON
J'ai essayé webScraping avec python.
Créer une application Web avec Django
Le débutant en Python a essayé 100 traitements de langage Knock 2015 (05 ~ 09)
le codeur Web a essayé d'exceller en Python
Les débutants en Python ont essayé d'utiliser Bottle et cela a fonctionné facilement de manière inattendue
Le débutant en Python a essayé 100 traitements de langage Knock 2015 (00 ~ 04)
Une introduction aux applications Web Python auto-conçues pour un ingénieur Web de troisième année paresseux
Une note où un débutant Python s'est retrouvé coincé
[Débutant] Scrapage Web Python facile à comprendre à l'aide de Google Colaboratory
J'ai une question! (Python, django) Facile
Démonisez une application Web Python avec Supervisor
J'ai essayé un langage fonctionnel avec Python
[Python] Une application web rapide avec Bottle!
J'ai créé une API Web
Utiliser Django à partir d'un script Python local
Exécutez une application Web Python avec Docker
Créez un framework Web avec Python! (1)
J'ai essayé de comparer le cadre d'application Web
Créez un framework Web avec Python! (2)
J'ai fait une application WEB avec Django
Un débutant en python a tenté de faire un stage dans une entreprise informatique [Enquête sur le chatbot jour 2]
Un débutant en python a tenté de faire un stage dans une entreprise informatique [Processus de développement du jour 1]
Les débutants ont essayé de créer une application Web native pour le cloud à l'aide de Datastore / GAE
J'ai recherché les compétences nécessaires pour devenir ingénieur web avec Python
Mémo d'apprentissage automatique d'un ingénieur débutant Partie 1
J'ai essayé le web scraping en utilisant python et sélénium
J'ai essayé de jouer à un jeu de frappe avec Python
Démarrez un serveur Web Python simple avec Docker
[Python] Créer un environnement de développement Django avec Docker
[Python] Dessinez un Mickey Mouse avec une tortue [Débutant]
Créer une carte Web en utilisant Python et GDAL
Étapes pour développer une application Web en Python
[Python] Préparation au développement Web (création d'un environnement virtuel)
J'ai essayé de lire un fichier CSV en utilisant Python
Enregistrement de l'examen de base de la certification d'ingénieur Python3 pour débutant en programmation
Lancer un serveur Web avec Python et Flask
Mémo d'apprentissage automatique d'un ingénieur débutant Partie 2