django中的测试

279 阅读4分钟

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 脚本并且需要在该级别测试成功或失败,则此功能很有用。