Django First APP automated testing and the introduction of static files

Personal study notes, refer to the official django documentation: https://docs.djangoproject.com/zh-hans/3.2/This
article is published on my personal blog: https://sunguoqi.com/2021/12/10/Django_02 /

1. Automated testing

  To test your code is to check that your code works (nonsense)

  To be honest, so far, I have written programs to run --> report errors --> then look at the error messages --> printinput and output to test. But the project is a whole project after all, so the test is too unprofessional.

  Automated testing has the following advantages:

  • Testing will save you time
  • Testing not only finds bugs, but prevents them
  • Tests make your code more attractive
  • Testing facilitates teamwork

Sounds good, then try it!

1. First, there must be a bug

  Following this application logic we wrote earlier, when we visit indexthis page, we should get the five most recently posted votes, if there are five.

  But now there is a small bug that if our vote is scheduled to be released tomorrow, our idea is that users can only see this vote tomorrow, the indexpage should not display this data, but according to the current logic, indexit will be displayed immediately. Article data.

  注意: The above description is indeed a bug, but there is another important bug, that is, when we wrote the data model before, we did not define any method to display the data within one day. Forgive me for not seeing this requirement: Question was posted within a day.

Below is the current state of the model layer.

# django框架的接口模块,默认已经引入
from django.db import models

import datetime
from django.utils import timezone


# Create your models here.

# 创建了一个“问题”类(表),表里有两个字段。
class Question(models.Model):
    # 问题描述字段
    question_text = models.CharField(max_length=200)
    # 创建日期字段
    pub_date = models.DateTimeField('date published')

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

    # python魔法方法,显示调用该对象的时候的返回内容
    def __str__(self):
        return self.question_text


# 创建了一个选项类(表),表中包含三个字段。
class Choice(models.Model):
    # 这个表里定义了一个外键字段,因为一个问题可以有多个选项,每个问题对应每个问题的选项。
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    # 选项描述字段
    choice_text = models.CharField(max_length=200)
    # 是否选取字段
    votes = models.IntegerField(default=0)

    # python魔法方法,显示调用该对象的时候的返回内容
    def __str__(self):
        return self.choice_text

2. Expose this bug

  The text description of this BUG is indeed a bit pale. Let's use the pythonmanage.pyshell command to expose this BUG.

  Open the terminal in the project root directory and enter python manage.py shellinto the interactive compilation environment.

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

  Obviously now the application will open future votes, so we have to fix this bug, oh right, this is not an automated test, we are just testing it in an interactive environment, we should write it into a file, when the project runs, Execute automated tests.

3. Automated testing

  By convention, tests for Django applications should be written in the application's tests.pyfiles . The test system will automatically find and execute test code in all files testsstarting with .

polls/tests.py

# Django自带的测试接口,默认已经引入
from django.test import TestCase
# Create your tests here.
# 引入datatime模块
import datetime
from django.utils import timezone
# 引入我们的数据表
from .models import Question


class QuestionModelTests(TestCase):

    def test_was_published_recently_with_future_question(self):
        """
        未来的一个时间他的返回值应该是False
        """
        time = timezone.now() + datetime.timedelta(days=30)
        future_question = Question(pub_date=time)
        self.assertIs(future_question.was_published_recently(), False)

4. Run the test

  Execute test command in terminalpython manage.py test polls

PS J:\study_django\mysite> python manage.py test polls
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E
======================================================================
ERROR: test_was_published_recently_with_future_question (polls.tests.QuestionModelTests)
未来的一个时间他的返回值应该是False
----------------------------------------------------------------------
Traceback (most recent call last):
  File "J:\study_django\mysite\polls\tests.py", line 19, in test_was_published_recently_with_future_question
    self.assertIs(future_question.was_published_recently(), False)
AttributeError: 'Question' object has no attribute 'was_published_recently'

----------------------------------------------------------------------
Ran 1 test in 0.003s

FAILED (errors=1)
Destroying test database for alias 'default'...
PS J:\study_django\mysite>

  Here's how the automated test runs:

  • python manage.py test pollswill look for test code in the pollsapp

  • It found a subclass of django.test.TestCase

  • It creates a special database for testing to use

  • It looks for test methods in the class - methods teststarting with .

  • In the test_was_published_recently_with_future_questionmethod , it creates an instancepub_date with a value of 30 days later .Question

  • Then use the assertls()method and find that it was_published_recently()returns True, and we expect it to return False.

5. Fix this bug

Should be returned   when pub_dateis a future date . Modify the method in to only return if the date is in the past tense :Question.was_published_recently()Falsemodels.pyTrue

polls/models.py

...
def was_published_recently(self):
    now = timezone.now()
    return now - datetime.timedelta(days=1) <= self.pub_date <= now
...

6. More comprehensive testing

  It's best to test the past, the recent, and the future. So modify the test code as follows.

# Django自带的测试接口,默认已经引入
from django.test import TestCase
# Create your tests here.
# 引入datatime模块
import datetime
from django.utils import timezone
# 引入我们的数据表
from .models import Question


class QuestionModelTests(TestCase):

    def test_was_published_recently_with_future_question(self):
        """
        未来的一个时间他的返回值应该是False
        """
        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):
        """
        最近一天的
        """
        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):
        """
        过去的
        """
        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)

7. Other solutions

  Another solution is that we should not display future votes, then we should filter them out when the view is displayed 过去and 未来I have not continued to study this.

Second, the introduction of static files

  First polls, create a directory named under staticthe directory. Django will look in this directory for static files, in a similar way to how Diango looks for templates in the polls/templates/directory .

1. Create a new css style

Create a new style in the static file directory.

static/style.css

li a {
    
    
  color: green;
}

2. Introduce static files

Introduce static files in templates.

index.html

{% load static %}

<link rel="stylesheet" type="text/css" href="{% static 'style.css' %}" />

3. Run the project

Guess you like

Origin blog.csdn.net/weixin_50915462/article/details/121866880