原创 智慧rdda大成 AI开发测试实战 1周前
Django 实战4
Django自动化测试
什么是自动化测试?
测试将节省您的时间
基本测试策略
测试有很多方法,TDD,手工测试,功能测试,接口测试,单元测试,集成测试等等,那么我们可能需要按照某种连路,或者说是策略来进行。
有些程序员遵循一种称为“测试驱动开发”的规程;他们实际上在编写代码之前编写测试。这似乎有悖常理,但事实上,这与大多数人通常会做的事情相似:他们描述一个问题,然后创建一些代码来解决它。测试驱动开发在Python测试用例中形式化了问题。更多的时候,测试新手会创建一些代码,然后决定应该进行一些测试。也许早一点编写一些测试会更好,但现在就开始永远不会太迟。
有时很难弄清楚从哪里开始写测试。如果您已经编写了几千行Python,那么选择要测试的内容可能并不容易。在这种情况下,在下次进行更改时编写第一个测试是很有成效的,无论是添加新特性还是修复bug。
我们发现了一个BUG
python manage.py shell
>>> 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
可以看出,查询语句中,因为未来的事情不是“最近的”,这显然是错误的。
那么我就开始编写一个python测试类tests.py
from django.test import TestCaseimport datetimefrom django.test import TestCasefrom django.utils import timezonefrom .models import Questionclass 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)
这里我们创建了一个django.test.TestCase测试用例使用一个方法创建一个问题实例,该实例的发布日期为将来。然后我们检查was_published_recently()的输出-应该是False
运行测试类
python manage.py test polls
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)
was_published_recently() returns False for questions whose pub_date
----------------------------------------------------------------------
Traceback (most recent call last):
File "D:\Users\dev\PycharmProjects\pythonProject\mysite\polls\tests.py", line 19, 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'...
F==Fail 失败1条记录
分析代码
Fix Bug
(): now timezonenow()
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'...
更全面的测试,意味着更多的测试用例需要编写,测试用例编写需要根据实际的需求进行编写。我们在tests.py 增加2个testcase,在我们有三个测试证实了这一点最近出版了吗()返回过去、最近和将来问题的合理值。
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)
测试视图
setup_test_environment()安装一个模板呈现程序,它允许我们检查响应中的一些附加属性,例如响应.上下文否则就不可能了。请注意,此方法不会设置测试数据库,因此将对现有数据库运行以下操作,并且根据您已经创建的问题,输出可能略有不同。如果你的时区在,你可能会得到意想不到的结果settings.py.py不正确。如果您不记得以前设置过,请在继续之前检查它。
接下来,我们需要导入测试客户机类(稍后在测试.py我们将使用django.test.TestCase测试用例类,它附带了自己的客户机,因此这不是必需的)
python manage.py shell
Python 3.8.6 (tags/v3.8.6:db45529, Sep 23 2020, 15:52:53) [MSC v.1927 64 bit (AMD64)] on win32
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() #实例化一个client
>>> response = client.get("/") #请求/
Not Found: /
>>> response.status_code #获取https 状态
404
>>> response = client.get(reverse('polls:index'))
Traceback (most recent call last):
File "<console>", line 1, in <module>
NameError: name 'reverse' is not defined ##没有定义
>>> from django.url import reverse
Traceback (most recent call last):
File "<console>", line 1, in <module>
ModuleNotFoundError: No module named 'django.url' ##没有发现module 单词拼写错误
>>> from django.urls import reverse
>>> response = client.get(reverse('polls:index'))
>>> response.content ##打印content 内容
b'\n <ul>\n \n <li><a href="/polls/6/">what do you do ?</a></li>\n \n <li><a href="/polls/5
/">\xe4\xbd\xa0\xe7\x9a\x84\xe7\x94\xb5\xe8\x84\x91\xe5\x90\x8d\xe7\xa7\xb0\xef\xbc\x9f</a></li>\n \n <l
i><a href="/polls/4/">\xe4\xbd\xa0\xe7\x9a\x84\xe5\x90\x8d\xe5\xad\x97\xef\xbc\x9f</a></li>\n \n <li><a
href="/polls/3/">\xe8\xaf\xb7\xe9\x97\xae\xe4\xbd\xa0\xe7\x9a\x84\xe5\xad\xa6\xe6\xa0\xa1\xe6\x98\xaf\xe5\x93\xaa\
xe9\x87\x8c?\xe4\xb8\xba\xe4\xbb\x80\xe4\xb9\x88\xe8\xbf\x99\xe4\xb9\x88\xe9\x97\xae?</a></li>\n \n <li>
<a href="/polls/2/">Who are you?</a></li>\n \n <li><a href="/polls/1/">What time is it?</a></li>\n \n
</ul>\n'
>>> response.context['lastst_question_list'] ## 获取最新额latest_question_list
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "d:\Users\dev\PycharmProjects\pythonProject\venv\lib\site-packages\django\template\context.py", line 83, in
__getitem__
raise KeyError(key) ##单词拼写错误
KeyError: 'lastst_question_list'
>>> response.context['latest_question_list'] ##获取list 所有记录 5条
<QuerySet [<Question: what do you do ?>, <Question: 你的电脑名称?>, <Question: 你的名字?>, <Question: 请问你的学
校是哪里?为什么这么问?>, <Question: Who are you?>, <Question: What time is it?>]>
>>>
return Question.objects.filter( pub_date__lte=timezone.now() ).order_by('-pub_date')[:5]
测试新的观点
添加tests.py 代码如下
from django.urls import reverse
def create_question(question_text, days):
"""
用给定的“问题文本”创建一个问题并发布
给定到现在的“天数”偏移量(对于已发布的问题为负数)
过去,对尚未发表的问题来说是积极的。
"""
time = timezone.now() + datetime.timedelta(days=days)
return Question.objects.create(question_text=question_text, pub_date=time)
class QuestionIndexViewTests(TestCase):
def test_no_questions(self):
"""
如果没有记录存在,有个消息提示!
"""
response = self.client.get(reverse('polls:index'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "没有问题记录!.")
self.assertQuerysetEqual(response.context['latest_question_list'], [])
def test_past_question(self):
"""
发布日期在过去的问题显示在,索引页。
"""
create_question(question_text="Past question.", days=-30)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question.>']
)
def test_future_question(self):
"""
带有未来发布日期的问题不会显示在屏幕上引页。
"""
create_question(question_text="Future question.", days=30)
response = self.client.get(reverse('polls:index'))
self.assertContains(response, "没有问题记录!.")
self.assertQuerysetEqual(response.context['latest_question_list'], [])
def test_future_question_and_past_question(self):
"""
即使过去和将来的问题都存在,也只有过去的问题将显示。
"""
create_question(question_text="Past question.", days=-30)
create_question(question_text="Future question.", days=30)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question.>']
)
def test_two_past_questions(self):
"""
问题索引页可能显示多个问题。
"""
create_question(question_text="Past question 1.", days=-30)
create_question(question_text="Past question 2.", days=-5)
response = self.client.get(reverse('polls:index'))
self.assertQuerysetEqual(
response.context['latest_question_list'],
['<Question: Past question 2.>', '<Question: Past question 1.>']
)
<p>没有问题记录!.</p>
也是时间没有加上判断,全运行python manage.py test polls
def get_queryset(self): return Question.objects.filter(pub_date__lte=timezone.now())
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
..........
----------------------------------------------------------------------
Ran 10 tests in 0.039s
OK
Destroying test database for alias 'default'...
总结
--END--