Django testcases for polls
Description
 You might have created a brilliant piece of software, but you will find that many other developers will refuse to look at it because it lacks tests; without tests, they won’t trust it. Jacob Kaplan-Moss, one of Django’s original developers, says “Code without tests is broken by design.”
In 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):
time = timezone.now() + datetime.timedelta(days=30)
future_question = Question(pub_date=time)
self.assertIs(future_question.was_published_recently(), False)
test polls
(dj-env) [dj_adm@localhost mysite]$ python manage.py test polls
Found 0 test(s).
System check identified no issues (0 silenced).
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
(dj-env) [dj_adm@localhost mysite]$ python manage.py test polls
Found 1 test(s).
Creating test database for alias 'default'...
Got an error creating the test database: (1044, "Access denied for user 'dj_adm'@'localhost' to database 'test_prod_app'")
Found 0 test(s).
System check identified no issues (0 silenced).
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
(dj-env) [dj_adm@localhost mysite]$ python manage.py test polls
Found 1 test(s).
Creating test database for alias 'default'...
Got an error creating the test database: (1044, "Access denied for user 'dj_adm'@'localhost' to database 'test_prod_app'")
root@localhost ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 150
Server version: 8.0.28 Source distribution
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database test_prod_app character set utf8;
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> GRANT ALL PRIVILEGES ON test_prod_app.* TO 'dj_adm'@'localhost'
-> ;
Query OK, 0 rows affected (0.01 sec)
mysql>
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 150
Server version: 8.0.28 Source distribution
Copyright (c) 2000, 2022, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> create database test_prod_app character set utf8;
Query OK, 1 row affected, 1 warning (0.01 sec)
mysql> GRANT ALL PRIVILEGES ON test_prod_app.* TO 'dj_adm'@'localhost'
-> ;
Query OK, 0 rows affected (0.01 sec)
mysql>
Running test cases
(dj-env) [dj_adm@localhost mysite]$ python manage.py test polls
Found 1 test(s).
Creating test database for alias 'default'...
Got an error creating the test database: (1007, "Can't create database 'test_prod_app'; database exists")
Type 'yes' if you would like to try deleting the test database 'test_prod_app', or 'no' to cancel: yes
Destroying old 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 "/home/dj_adm/dj-practice/mysite/polls/tests.py", line 14, 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'...
(dj-env) [dj_adm@localhost mysite]$
Found 1 test(s).
Creating test database for alias 'default'...
Got an error creating the test database: (1007, "Can't create database 'test_prod_app'; database exists")
Type 'yes' if you would like to try deleting the test database 'test_prod_app', or 'no' to cancel: yes
Destroying old 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 "/home/dj_adm/dj-practice/mysite/polls/tests.py", line 14, 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'...
(dj-env) [dj_adm@localhost mysite]$
Action Item
- We have to correct the was_published_recently function to handle the future dates
 
In Models.py
from django.db import models
from django.utils import timezone
import datetime
# Create your models here.
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date_published')
def __str__(self):
return self.question_text
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.pub_date <= now
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
Running testcases now
(dj-env) [dj_adm@localhost mysite]$ python manage.py test polls
Found 1 test(s).
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'...
(dj-env) [dj_adm@localhost mysite]$
Found 1 test(s).
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'...
(dj-env) [dj_adm@localhost mysite]$
Testcases for views
A conventional place for an application’s tests is in the application’s tests.py file; the testing system will automatically find tests in any file whose name begins with test.
(dj-env) [dj_adm@localhost mysite]$ python manage.py shell
Python 3.9.10 (main, Feb 9 2022, 00:00:00)
[GCC 11.2.1 20220127 (Red Hat 11.2.1-9)] on linux
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
>>> client = Client()
>>> response = client.get('/')
Not Found: /
>>> response.status_code
404
>>> from django.urls import reverse
>>> response = client.get(reverse('polls:index'))
>>> response.status_code
200
>>> response.content
b'<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <meta http-equiv="X-UA-Compatible" content="IE=edge" />\n <meta name="viewport" content="width=device-width, initial-scale=1.0" />\n <title>Polls</title>\n </head>\n <body>\n \n <ul>\n \n <li>\n <!-- <a href="/polls/6/">What is your favourite food?</a> -->\n <a href="/polls/6/">What is your favourite food?</a>\n </li>\n \n <li>\n <!-- <a href="/polls/5/">Do you know swimming?</a> -->\n <a href="/polls/5/">Do you know swimming?</a>\n </li>\n \n <li>\n <!-- <a href="/polls/4/">what is your favourite place?</a> -->\n <a href="/polls/4/">what is your favourite place?</a>\n </li>\n \n <li>\n <!-- <a href="/polls/3/">What is the plan for weekend?</a> -->\n <a href="/polls/3/">What is the plan for weekend?</a>\n </li>\n \n <li>\n <!-- <a href="/polls/2/">How are you?</a> -->\n <a href="/polls/2/">How are you?</a>\n </li>\n \n </ul>\n \n </body>\n</html>\n'
>>> response.context['latest_question_list']
<QuerySet [<Question: What is your favourite food?>, <Question: Do you know swimming?>, <Question: what is your favourite place?>, <Question: What is the plan for weekend?>, <Question: How are you?>]>
>>>
(dj-env) [dj_adm@localhost mysite]$ python manage.py shell
Python 3.9.10 (main, Feb 9 2022, 00:00:00)
[GCC 11.2.1 20220127 (Red Hat 11.2.1-9)] on linux
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
>>> client = Client()
>>> response = client.get('/')
Not Found: /
>>> response.status_code
404
>>> from django.urls import reverse
>>> response = client.get(reverse('polls:index'))
>>> response.status_code
200
>>> response.content
b'<!DOCTYPE html>\n<html lang="en">\n <head>\n <meta charset="UTF-8" />\n <meta http-equiv="X-UA-Compatible" content="IE=edge" />\n <meta name="viewport" content="width=device-width, initial-scale=1.0" />\n <title>Polls</title>\n </head>\n <body>\n \n <ul>\n \n <li>\n <!-- <a href="/polls/6/">What is your favourite food?</a> -->\n <a href="/polls/6/">What is your favourite food?</a>\n </li>\n \n <li>\n <!-- <a href="/polls/5/">Do you know swimming?</a> -->\n <a href="/polls/5/">Do you know swimming?</a>\n </li>\n \n <li>\n <!-- <a href="/polls/4/">what is your favourite place?</a> -->\n <a href="/polls/4/">what is your favourite place?</a>\n </li>\n \n <li>\n <!-- <a href="/polls/3/">What is the plan for weekend?</a> -->\n <a href="/polls/3/">What is the plan for weekend?</a>\n </li>\n \n <li>\n <!-- <a href="/polls/2/">How are you?</a> -->\n <a href="/polls/2/">How are you?</a>\n </li>\n \n </ul>\n \n </body>\n</html>\n'
>>> response.context['latest_question_list']
<QuerySet [<Question: What is your favourite food?>, <Question: Do you know swimming?>, <Question: what is your favourite place?>, <Question: What is the plan for weekend?>, <Question: How are you?>]>
>>>
Tests.py
import datetime
from django.test import TestCase
from django.utils import timezone
from django.urls import reverse
from .models import Question
# models Testing
class QuestionModelTests(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)
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)
def create_question(question_text, days):
time = timezone.now() + datetime.timedelta(days=days)
return Question.objects.create(question_text=question_text, pub_date=time)
# views Testing
class IndexViewTests(TestCase):
def test_no_questions(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'], [])
def test_past_question(self):
question = create_question(question_text="Past question.", days=-30)
response = self.client.get(reverse('polls:index'))
print("test_past_question:-{0}".format(response.context))
self.assertQuerysetEqual(
response.context['latest_question_list'],
[question],
)
(dj-env) [dj_adm@localhost mysite]$ python manage.py test polls
Found 5 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.test_past_question:-[{'True': True, 'False': False, 'None': None}, {'csrf_token': <SimpleLazyObject: <function csrf.<locals>._get_val at 0x7f83949033a0>>, 'request': <WSGIRequest: GET '/polls/'>, 'user': <SimpleLazyObject: <function AuthenticationMiddleware.process_request.<locals>.<lambda> at 0x7f8394903310>>, 'perms': PermWrapper(<SimpleLazyObject: <function AuthenticationMiddleware.process_request.<locals>.<lambda> at 0x7f8394903310>>), 'messages': <FallbackStorage: request=<WSGIRequest: GET '/polls/'>>, 'DEFAULT_MESSAGE_LEVELS': {'DEBUG': 10, 'INFO': 20, 'SUCCESS': 25, 'WARNING': 30, 'ERROR': 40}}, {}, {'latest_question_list': <QuerySet [<Question: Past question.>]>}]
....
----------------------------------------------------------------------
Ran 5 tests in 0.039s
OK
Destroying test database for alias 'default'...
Found 5 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.test_past_question:-[{'True': True, 'False': False, 'None': None}, {'csrf_token': <SimpleLazyObject: <function csrf.<locals>._get_val at 0x7f83949033a0>>, 'request': <WSGIRequest: GET '/polls/'>, 'user': <SimpleLazyObject: <function AuthenticationMiddleware.process_request.<locals>.<lambda> at 0x7f8394903310>>, 'perms': PermWrapper(<SimpleLazyObject: <function AuthenticationMiddleware.process_request.<locals>.<lambda> at 0x7f8394903310>>), 'messages': <FallbackStorage: request=<WSGIRequest: GET '/polls/'>>, 'DEFAULT_MESSAGE_LEVELS': {'DEBUG': 10, 'INFO': 20, 'SUCCESS': 25, 'WARNING': 30, 'ERROR': 40}}, {}, {'latest_question_list': <QuerySet [<Question: Past question.>]>}]
....
----------------------------------------------------------------------
Ran 5 tests in 0.039s
OK
Destroying test database for alias 'default'...
Comments
Post a Comment