[PYTHON] Get started with Django! ~ Tutorial ⑤ ~

Overview

I've covered Django's tutorials four times, Last time completed the entire app.

Part 5 will explain the introduction of automated testing.

What is an automated test?

A test is a simple program that checks the behavior of your code.

The tests run at a different level than the code in other apps. One test may be done on a small feature (does a method in one particular model return the expected value?), And another test is done on the behavior of the entire software. (Does the user's sequence of inputs on the site produce the expected results?).

What sets automated testing apart is that the testing work is performed by the system. Once you've created a test set, you can then make changes to your app to see if your code works as you intended. It doesn't take long to test manually.

Project without test code

Having the test code gives you a sense of security that it's okay for people to see it on GitHub. (If not, this project will be okay.)

If you run the code for that test and return a Suceess, no matter what fixes you put in, it's bug-free and ready to launch.

Writing test code is more than just testing It reassures the reader of the code and guarantees that a series of tests can be guaranteed when developed by multiple people.

Write according to the "test-driven" principle! Not to mention, it is imperative to finally prepare for the test.

Creating your first test

Django also recommends writing test code, There are modules that make it easy to create tests.

I'd like to actually run the test code with one example.

In fact, the voting apps we've created so far have one small bug.

polls/models.py


from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils import timezone
import datetime

# Create your models here.


@python_2_unicode_compatible
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text

	#This method
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)


@python_2_unicode_compatible
class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

The `` `was_published_recently``` method above is a method that returns True if the Question was created after yesterday.

That's OK, but this method returns True even on future dates. (There is no such vote.)

Let's actually check the operation with the shell command provided by Django.

Execute the following command in the terminal.

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

As expected, True has returned. This result is incorrect because the future date is not'recent'.

It would be convenient if you could leave what you did above in the project as test code and test it at any time. (You also know what the method wants to do.)

Actually create the test code.

First of all, the directory structure where the test code is placed, Create it with the name tests.py under the polls directory.

polls/tests.py


from django.test import TestCase

import datetime
from django.utils import timezone

from .models import Question

# Create your tests here.


class QuestionMethodTest(TestCase):
    def test_was_published_recently_with_future_question(self):
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(pub_date=time)
        self.assertIs(future_question.was_published_recently(), False)

First, we're creating a subclass that inherits from django.test.TestCase and an instance of Question with a pub_date for a future date. Then I'm checking the output of was_published_recently (). This should be False.

It's a very intuitive code, and it seems to be Python / Django.

Run the test

Run the following command in the terminal to start the automated test.

$ python manage.py test polls

Then, the following execution result will be obtained.

Creating test database for alias 'default'...
F
======================================================================
FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionMethodTests)
----------------------------------------------------------------------
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'...

In the above, the following things are done.

--python manage.py test polls looks for tests in polls applications --Discover a subclass of the django.test.TestCase class --Create a special database for testing --Look for methods that start with test as methods for testing --In test_was_published_recently_with_future_question, a Question instance is created in the pub_date field with a date 30 days after today. --Determine if the result of the argument of the assetIs method is correct.

Fix bugs

Let's actually fix Question.was_published_recently.

polls/models.py


from django.db import models
from django.utils.encoding import python_2_unicode_compatible
from django.utils import timezone
import datetime

# Create your models here.


@python_2_unicode_compatible
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')

    def __str__(self):
        return self.question_text
	
	#Modified method
    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now


@python_2_unicode_compatible
class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text

After making the correction, execute the test command again.

Creating test database for alias 'default'....
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK
Destroying test database for alias 'default'...

As mentioned above, the test was completed successfully and OK was displayed.

Summary

This automated test focused on testing the model, but of course there are also views and other tests.

I have briefly introduced the whole test and only the beginning of writing the test code.

I hope I can show you how to write other test code at another time.

Next time, in the final chapter, I'll explain how Django handles static files.

GitHub

series

-Get started with Django! ~ Tutorial ① ~ -Get started with Django! ~ Tutorial ② ~ -Get started with Django! ~ Tutorial ③ ~ -Get started with Django! ~ Tutorial ④ ~ -Get started with Django! ~ Tutorial ⑤ ~ -Get started with Django! ~ Tutorial ⑥ ~

Recommended Posts

Get started with Django! ~ Tutorial ⑤ ~
Get started with Django! ~ Tutorial ④ ~
Get started with Django! ~ Tutorial ⑥ ~
How to get started with Django
Django 1.11 started with Python3.6
Step notes to get started with django
Getting Started with Django 1
Get started with MicroPython
Get started with Mezzanine
Getting Started with Django 2
The easiest way to get started with Django
Get started with influxDB + Grafana
Getting Started with Python Django (1)
Getting Started with Python Django (4)
Getting Started with Python Django (3)
Getting Started with Python Django (6)
Get started with Python! ~ ② Grammar ~
Getting Started with Django with PyCharm
Getting Started with Python Django (5)
Get started with Python! ~ ① Environment construction ~
Link to get started with python
Get started with MicroPython (on macOS)
How to get started with Scrapy
How to get started with Python
Get started with machine learning with SageMaker
Get started with Python in Blender
Get started with the Python framework Django on Mac OS X
Python Django Tutorial (5)
Python Django Tutorial (2)
I tried to get started with Hy
CRUD GET with Nuxt & Django REST Framework ②
Internationalization with django
django tutorial memo
Here's a brief summary of how to get started with Django
Python Django Tutorial (8)
CRUD GET with Nuxt & Django REST Framework ①
Python Django Tutorial (6)
Start Django Tutorial 1
Get started with the documentation tool Sphinx
Get Started with TopCoder in Python (2020 Edition)
CRUD with Django
Python Django Tutorial (7)
Python Django Tutorial (1)
Python Django tutorial tutorial
How Python beginners get started with Python with Progete
How to get started with laravel (Linux)
Python Django Tutorial (3)
[Blender x Python] Let's get started with Blender Python !!
Python Django Tutorial (4)
Python hand play (let's get started with AtCoder?)
Django Getting Started Part 2 with eclipse Plugin (PyDev)
Get started with Python on macOS Big Sur
A layman wants to get started with Python
[Cloud102] # 1 Get Started with Python (Part 1 Python First Steps)
Authenticate Google with Django
Upload files with Django
Development digest with Django
Python Django tutorial summary
Output PDF with Django
Getting started with Android!
Markdown output with Django