首页 > 其他分享 >“Code without tests is broken by design.”

“Code without tests is broken by design.”

时间:2023-01-07 14:44:36浏览次数:69  
标签:__ tests Code recently question broken published test was

https://docs.djangoproject.com/en/4.1/intro/tutorial05/

it’s never too late to get started.

今天主要接上一章节~从testing这篇官方文档开始看起。
image

这一个测试讲述了很多至理名言,包括标题和第一句。
而第一个测试从这里开始:

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):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

这个Question类是前几章节建立的,而was_published_recently则是问是否是最近发布的。
最后这个

self.pub_date >= timezone.now() - datetime.timedelta(days=1)

则是判断返回True和False的判定。
这一句的判定是当前的发布时间是否大于或等于 当前时间减去一天。
也就是起码是昨天的新发布数据才是recently发布的。

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

Now, do the testing.
通过python manage.py shell进行shell命令模式执行以上命令。
而这里的timedelta被+了30天,也就是创建了一个pub_date时间是未来30天的一个
future_question,而执行was_published_recently()如果没有问题则
肯定会返回True。

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.

这里命令也是很关键,比如以上说明建立test开头的py文件,系统会自动找到并进行测试。

import datetime
from time import timezone

from django.test import TestCase

from polls.models import Question


# Create your tests here.

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)

注意:本类记录中python命令都是以MacOs为准。

python manage.py test polls
Found 1 test(s).
Creating 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 "/Users/x/PycharmProjects/djangoProject1/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'...

官方教程中这里就是判定是否是False,而实际上我感觉测试
是应该判定Ture才对的,也许这里只是演示测试失败的结果。

… and using the assertIs() method, it discovered that its was_published_recently() returns True, though we wanted it to return False

实际上官方教程说明,was_published_rencetly()这个看似DDD的方法是有逻辑缺陷的。
应该改为:

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

这里的判定则改为了

当前时间 - 1天时间 <= 发布时间 <= 当前时间

也就是发布时间必须是在发布之后1天时间(包括)之内的时间,并且加强判定为
发布时间不能超过当前时间,那样会有逻辑问题。

fix这个问题之后再测 assert False

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

番外篇:
The Django test client
这里我通过这篇test client测试了跟着官方做的项目,
是可以的:

>>> from django.urls import reverse
>>> response = client.get(reverse('polls:index'))
>>> response.status_code
200
>>> response.content
b'\n    <ul>\n        \n            <li><a href="/polls/1/">What&#x27;s up?</a></li>\n        \n    </ul>\n'
>>> response.context['latest_question_list']
<QuerySet [<Question: What's up?>]>

那么测试下t项目如何:
答案也是可以的,只不过t项目的shell经过定制化一样,
每打一行都是会有个自增的序列出现。

Improving our view

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'
    def get_queryset(self):
        # Return the last five published questions.
        # return Question.objects.order_by('-pub_date')[:5]
        return Question.objects.filter(pub_date__lte=timezone.now()).order_by('-pub_date')[:5]

更改view层,像是springboot的controller层,
这里在Django中有很多关键字,比如template_name,context_object_name,
queryset,serializer_class,lookup_field,lookup_url_kwarg,filter_backends,
pagination_class.
具体可以看到rest_framework-stubs/generics.pyi这个源码文件。
而rest framework就是django框架提供的:

r"""
______ _____ _____ _____    __
| ___ \  ___/  ___|_   _|  / _|                                           | |
| |_/ / |__ \ `--.  | |   | |_ _ __ __ _ _ __ ___   _____      _____  _ __| |__
|    /|  __| `--. \ | |   |  _| '__/ _` | '_ ` _ \ / _ \ \ /\ / / _ \| '__| |/ /
| |\ \| |___/\__/ / | |   | | | | | (_| | | | | | |  __/\ V  V / (_) | |  |   <
\_| \_\____/\____/  \_/   |_| |_|  \__,_|_| |_| |_|\___| \_/\_/ \___/|_|  |_|\_|
"""

import django

__title__ = 'Django REST framework'
__version__ = '3.12.4'
__author__ = 'Tom Christie'
__license__ = 'BSD 3-Clause'
__copyright__ = 'Copyright 2011-2019 Encode OSS Ltd'

image

休息一下,马上回来!

标签:__,tests,Code,recently,question,broken,published,test,was
From: https://www.cnblogs.com/ukzq/p/17032599.html

相关文章