I've covered Django's tutorials four times, Last time completed the entire app.
Part 5 will explain the introduction of automated testing.
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.
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.
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 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.
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.
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.
-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