Django 中的测试
这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战
对现在的网络开发者来说,自动化测试是一个非常有用的发现漏洞的工具你可以使用一套测试-测试套件-去解决,避免一堆的问题:
- 当你写新代码时,你可以利用测试确保代码按照期望的方式运行。
- 当你不修改或修改旧代码,你可以利用测试来确保你的修改不会使应用运行出错。
一个 Web 应用是北极测试的工作,因为 Web 应用包含了真实的业务逻辑——从 HTTP 层响应请求,到表单状态检测和处理,再到模板渲染。利用 Django 的测试执行框架和配套的工具,你可以模拟它你去,插入测试数据,检查应用的输出,测试检验你的代码是否需要运行。
在 Django 中编写测试的首选方法是使用unittestPython 标准库的内置模块。
也可以使用另一个的Python测试框架
1、普通单元测试
一段代码测试另一段代码
from django.test import TestCase
import unittest
# Create your tests here.
def add(x, y):
return x + y
class My_test(unittest.TestCase):
def test1(self):
c = add(1, 3)
self.assertEqual(c, 4)
def test2(self):
c = add(2, 3)
self.assertEqual(c, 5)
def test3(self):
c = add(1.1, 3)
self.assertEqual(c, 4)
if __name__ == '__main__':
unittest.main()
2、django模型(models.py)测试
需要数据库的测试(即模型测试)不会使用您的“真实”(生产)数据库。为测试创建单独的空白数据库。
无论测试通过还是失败,当所有测试都执行完毕后,测试数据库就会被销毁。
Django 的单元测试采用 Python 的标准模块:unittest。该模块以类的形式定义测试。
from django.test import TestCase
from myapp.models import Animal
class AnimalTestCase(TestCase): # TestCase继承unittest
def setUp(self): # 添加测试用例
Animal.objects.create(name="lion", sound="roar")
Animal.objects.create(name="cat", sound="meow")
def test_animals_can_speak(self):
"""Animals that can speak are correctly identified"""
lion = Animal.objects.get(name="lion")
cat = Animal.objects.get(name="cat")
self.assertEqual(lion.sound, "roar"')
self.assertEqual(cat.sound, "meow")
python manage.py test
./manage.py test animals.tests.AnimalTestCase.test_animals_can_speak # 测试那个路径下的
注意
如果你的测试依赖数据库连接,例如创建或模型,请确保继承django.test.TestCase实现你的测试类,而不是unittest.TestCase。
使用unittest.TestCase可以避免在事务中运行每个测试和刷新数据库,但是如果您的测试与数据库交互,它们的行为将根据测试运行器执行它们的顺序而有所不同。这可能导致单元测试在单独运行时通过但在套件中运行时失败。
3、执行测试的顺序
为了保证所有TestCase代码都从一个干净的数据库开始,Django 测试运行器按以下方式重新排序测试:
TestCase首先运行所有子类。- 然后,所有其他基于 Django 的测试(基于
SimpleTestCase,包括 的 测试用例TransactionTestCase)在没有特定顺序保证或强制执行的情况下 运行。 - 然后
unittest.TestCase运行可能会更改数据库而不将其恢复到其原始状态的任何其他测试(包括 doctests)。
4、实例
from django.test import TestCase
import unittest
from .models import UserInfo
class UserTest(TestCase):
def setUp(self) -> None: # 添加测试用例
UserInfo.objects.create(username="abc", email="1992@qq.com", mobile_phone="111", password="123456")
UserInfo.objects.create(username="abc1", email="1992222@qq.com", mobile_phone="122211", password="12345678")
def test_create(self): # 创建测试
UserInfo.objects.create(username="abc2", email="199222@qq.com", mobile_phone="111111", password="123456")
p = UserInfo.objects.get(username="abc2")
self.assertEqual(p.username, "abc2")
self.assertEqual(p.mobile_phone, "111111")
def test_delete(self): # 删除测试
p = UserInfo.objects.get(username="abc2")
p.delete()
ret = UserInfo.objects.filter(username="abc2")
self.assertEqual(ret.username, "abc2")
def test_update(self): # 更新测试
p = UserInfo.objects.get(username="abc")
p.username = "cba"
p.save()
ret = UserInfo.objects.get(username="cba")
self.assertEqual(ret.username, "cba")
理解测试输出
当您运行测试时,您会在测试运行器自行准备时看到许多消息。您可以verbosity使用命令行上的选项控制这些消息的详细程度 :
Creating test database...
Creating table myapp_animal
Creating table myapp_mineral
这告诉您测试运行器正在创建一个测试数据库,如上一节所述。
创建测试数据库后,Django 将运行您的测试。如果一切顺利,您会看到如下内容:
----------------------------------------------------------------------
Ran 22 tests in 0.221s
OK
但是,如果存在测试失败,您将看到有关哪些测试失败的完整详细信息:
======================================================================
FAIL: test_was_published_recently_with_future_poll (polls.tests.PollMethodTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/dev/mysite/polls/tests.py", line 16, in test_was_published_recently_with_future_poll
self.assertIs(future_poll.was_published_recently(), False)
AssertionError: True is not False
----------------------------------------------------------------------
Ran 1 test in 0.003s
FAILED (failures=1)
此错误输出的完整解释超出了本文档的范围,但非常直观。您可以查阅 Pythonunittest库的文档 以了解详细信息。
请注意,对于任意数量的失败和错误测试,test-runner 脚本的返回码为 1。如果所有测试都通过,则返回码为 0。如果您在 shell 脚本中使用 test-runner 脚本并且需要在该级别测试成功或失败,则此功能很有用。