在django中的测试架构

本文涉及的产品
性能测试 PTS,5000VUM额度
云原生网关 MSE Higress,422元/月
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
简介: 【6月更文挑战第13天】该文主要讨论Django项目的测试数据查询和测试架构。文中展示了如何创建`TestCase`子类进行测试,并提供了执行测试的不同选项,如增加详细信息、并行运行和选择性运行特定测试。

1 测试数据的查询

测试的目的是什么?

文章指出,测试的目的是验证自定义代码,而非Django本身的功能。并且建议,虽然无需测试Django的默认行为,如模型的存储和验证,但应检查自定义字段标签、大小及自定义方法。测试架构应组织在以test*.py命名的文件中,每个文件针对模型、视图等不同部分。

question_ans.png

我们可能需要测试你自己代码的所有方面,而不是作为Python或Django的一部分提供的任何库或功能。

例如,考虑下面定义的模型。

你不需要显式测试它,并且已经像在数据库中一样正确存储,因为这是 Django 定义的东西(当然在实践中你会不可避免地在开发过程中测试此功能)。

你也不需要测试它是否已经被验证为日期字段,因为这又是在 Django 中实现的东西。
比如

  Author first_name last_name CharFie ld date_of_birth

但是,您应该检查用于标签的文本(名字、姓氏、出生日期、死亡)以及为文本分配的字段大小(100 个字符),因为这些是您设计的一部分,将来可能会被破坏/更改。

class Author(models.Model):
        first_name = models.CharField(max_length=100)
        last_name = models.CharField(max_length=100)
        date_of_birth = models.DateField(null=True, blank=True)
        date_of_death = models.DateField('Died', null=True, blank=True)

        def get_absolute_url(self):
            return reverse('author-detail', args=[str(self.id)])

        def __str__(self):
            return '%s, %s' % (self.last_name, self.first_name)

同样,您应该检查自定义方法并按要求运行,因为它们是您的代码/业务逻辑。

在这种情况下,你可以相信 Django方法已经正确实现,所以你正在测试的是关联的视图实际上已经被定义。

精明的读者可能会注意到,我们也希望将出生和死亡的日期限制在合理的值上,并检查死亡是否在出生后发生。

在 Django 中,这个约束将被添加到你的表单类中,尽管你可以为模型字段和模型验证器定义验证器,这些验证器只有在模型的方法调用时才在表单级别使用。

这需要 ,或者需要专门调用模型的方法,比如

 clean(),ModelFormclean()。

考虑到这一点,让我们开始研究如何定义和运行测试。

2 测试的架构

在我们详细介绍“测试什么”之前,让我们先简要了解一下测试的定义位置和方式。

Django 使用 unittest 模块的内置测试发现,它将在任何以模式 test*.py 命名的文件中发现当前工作目录下的测试。

只要您正确命名文件,您就可以使用您喜欢的任何结构。
我们建议您为测试代码创建一个模块,并为模型、视图、窗体和需要测试的任何其他类型的代码提供单独的文件。例如:

    blog/
      /tests/
        __init__.py
        test_models.py
        test_forms.py
        test_views.py

在 posts 项目中创建如上所示的文件结构。

init.py应该是一个空文件(这告诉 Python 该目录是一个包)。

您可以通过复制并重命名框架测试文件 /posts/tests.py 来创建三个测试文件。

架构文件 /blog/tests.py 是我们在构建 Django 主干网站时自动创建的。
将所有测试都放在里面是完全“合法的”,但是如果您测试得当,您很快就会得到一个非常大且难以管理的测试文件。

可以删除骨架文件,因为我们不需要它。

打开 /blog/tests/test_models.py。

该文件应导入,如下所示:django.test.TestCase。

    from django.test import TestCase

在这里创建测试集.

通常,您将为要测试的每个 models/views/windwos添加一个测试类,并使用单独的方法来测试特定功能。

在其他情况下,您可能希望有一个单独的类来测试特定用例,其中包含测试该用例各个方面的单个测试函数(例如,一个用于测试模型字段是否经过正确验证的类,其中包含用于测试每个可能的失败案例的函数)。

同样,结构在很大程度上取决于您,但最好是保持一致。

将下面的测试类添加到文件底部。该类演示如何通过派生自TestCase 来构造测试用例类。

    class PostsTestClass(TestCase):
        @classmethod
        def setUpTestData(cls):
            print("setUpTestData: Run once to set up non-modified data for all class methods.")
            pass

        def setUp(self):
            print("setUp: Run once for every test method to setup clean data.")
            pass

        def test_false_is_false(self):
            print("Method: test_false_is_false.")
            self.assertFalse(False)

        def test_false_is_true(self):
            print("Method: test_false_is_true.")
            self.assertTrue(False)

        def test_one_plus_one_equals_two(self):
            print("Method: test_one_plus_one_equals_two.")
            self.assertEqual(1 + 1, 2)

新类定义了两个可用于预测试配置的方法(例如,创建测试所需的任何模型或其他对象):

setUpTestData()在测试运行开始时为类级设置调用一次。您可以使用它来创建不会在任何测试方法中修改或更改的对象。

setUp()在每个测试函数之前调用,以设置测试可能修改的任何对象(每个测试函数都将获得这些对象的“全新”版本)。

测试类也有一个我们没有使用过的方法tearDown()。此方法对于数据库测试不是特别有用,因为基类TestCase会为您处理数据库拆解。

在这些下面,我们有许多测试方法,它们使用函数来测试条件是真、假还是相等 (AssertTrue,AssertFalse,AssertEqual)。
如果条件未按预期评估,则测试将失败并将错误报告给主机。

Assert是 unittest 提供的标准断言。框架中还有其他标准断言。

以及特定于 Django 的断言来测试视图是否重定向 (AssertEqualassertRedirects),以测试是否使用了特定模板 (AssertTrueAssertFalseassertTemplateUsed) 等。

您通常不应该在测试中包含 print() 函数,如上所示。
我们在这里这样做只是为了让您可以看到在控制台中调用设置函数的顺序(在下一节中)。

3 执行测试

运行所有测试的最简单方法是使用以下命令:

    python3 manage.py test

这将发现当前目录下所有以模式 test*.py 命名的文件,并运行使用适当的基类定义的所有测试,

这里我们有许多测试文件,但目前只有 /blog/tests/test_models.py 包含任何测试。

默认情况下,测试将仅单独报告测试失败,然后是测试摘要。

如果您收到类似于以下内容的错误,这可能是因为默认情况下测试不运行 collectstatic,

并且您的应用正在使用需要它的存储类(有关详细信息,请参阅manifest_strict)。

有许多方法可以解决此问题 - 最简单的方法是在运行测试之前运行

    collectstatic:ValueError: Missing staticfiles manifest entry...

    python3 manage.py collectstatic

在本地库的根目录中运行测试。您应该会看到如下所示的输出。

     python3 manage.py test

输出:

    Creating test database for alias 'default'...
    setUpTestData: Run once to set up non-modified data for all class methods.
    setUp: Run once for every test method to setup clean data.
    Method: test_false_is_false.
    setUp: Run once for every test method to setup clean data.
    Method: test_false_is_true.
    setUp: Run once for every test method to setup clean data.
    Method: test_one_plus_one_equals_two.
    .
    ======================================================================
    FAIL: test_false_is_true (blog.tests.tests_models.YourTestClass)
    ----------------------------------------------------------------------
    Traceback (most recent call last):
      File "D:\django_tmp\libt_2\blog\tests\tests_models.py", line 22, in test_false_is_true
        self.assertTrue(False)
    AssertionError: False is not true

    ----------------------------------------------------------------------
    Ran 3 tests in 0.075s

    FAILED (failures=1)
    Destroying test database for alias 'default'...

在这里,我们看到我们有一个测试失败,我们可以确切地看到哪个函数失败以及为什么(这个失败是意料之中的,因为不是true或false!

从上面的测试输出中学到的最重要的事情是,如果您为对象和方法使用描述性/信息性名称,它会更有价值。

函数print()的输出显示如何为类调用一次方法,以及如何在每个方法之前调用setUpTestData()该方法。 同样,通常您不会将setUp()这种添加到测试中。

4 控制测试信息量

接下来的部分将介绍如何运行特定测试,以及如何控制测试显示的信息量。

  • 更多测试信息

如果要获取有关测试运行的详细信息,可以更改详细程度。

例如,要列出测试成功和失败(以及有关如何设置测试数据库的一大堆信息),您可以将详细程度设置为“2”,如下所示:

    python3 manage.py test --verbosity 2

允许的详细级别为 0、1、2 和 3,默认值为“1”。

  • 加快测试执行速度

如果您的测试是独立的,则在多处理器计算机上,您可以通过并行运行它们来显著加快测试速度。 下面使用以下命令为每个可用内核运行一个测试过程。

这是可选的,您还可以指定要使用的特定数量的内核。--parallel autoauto

    python3 manage.py test --parallel auto
  • 运行特定测试

如果要运行测试的子集,可以通过指定包、模块、子类或方法的完整点路径来实现:TestCase

执行特定的测试集

    python3 manage.py test blog.tests

执行特定的测试用例模块

    python3 manage.py test blog.tests.test_models

执行特定的测试用例模块的测试类

    python3 manage.py test blog.tests.test_models.YourTestClass

执行特定的测试用例模块的测试类的测试方法

    python3 manage.py test blog.tests.test_models.BlogTestClass.test_one_plus_one_equals_two

5 小结

其他测试运行程序选项,django为测试运行程序提供了许多其他选项,

包括随机执行测试(--shuffle)、
在调试模式下运行测试(--debug-mode)以及使用 Python 记录器捕获结果的功能。

有关更多信息,请参阅最后的参考内容 Django 测试运行程序文档。

https://docs.djangoproject.com/en/4.0/ref/django-admin/#test
目录
相关文章
|
2月前
|
数据采集 机器学习/深度学习 大数据
行为检测代码(一):超详细介绍C3D架构训练+测试步骤
这篇文章详细介绍了C3D架构在行为检测领域的应用,包括训练和测试步骤,使用UCF101数据集进行演示。
71 1
行为检测代码(一):超详细介绍C3D架构训练+测试步骤
|
4月前
|
存储 监控 数据库
Django 后端架构开发:高效日志规范与实践
Django 后端架构开发:高效日志规范与实践
82 1
|
2月前
|
缓存 Devops jenkins
专家视角:构建可维护的测试架构与持续集成
【10月更文挑战第14天】在现代软件开发过程中,构建一个可维护且易于扩展的测试架构对于确保产品质量至关重要。本文将探讨如何设计这样的测试架构,并将单元测试无缝地融入持续集成(CI)流程之中。我们将讨论最佳实践、自动化测试部署、性能优化技巧以及如何管理和扩展日益增长的测试套件规模。
53 3
|
4月前
|
Kubernetes Cloud Native 测试技术
探索软件测试的奥秘:从理论到实践深入理解云原生架构:从基础到实践
【8月更文挑战第28天】在软件开发的世界中,测试不仅是质量的守护者,也是创新的催化剂。本文将带你穿越软件测试的迷宫,从基础概念到高级策略,揭示如何通过测试提升软件质量和用户体验。我们将一起解码测试的核心原则,探索自动化测试的魅力,并学习如何设计有效的测试案例。无论你是测试新手还是资深开发者,这篇文章都将为你提供宝贵的见解和实用的技巧,让你在软件测试的道路上更加从容不迫。 【8月更文挑战第28天】本文旨在为读者揭示云原生技术的核心概念、优势以及如何在实际项目中应用。通过深入浅出的方式,我们将探索云原生的多个方面,包括容器化、微服务架构、持续集成和持续部署(CI/CD)、以及如何利用Kubern
|
4月前
|
存储 缓存 前端开发
Django 后端架构开发:存储层调优策略解析
Django 后端架构开发:存储层调优策略解析
67 2
|
4月前
|
存储 安全 数据安全/隐私保护
Django 后端架构开发:富文本编辑器权限管理与 UEditor 、Wiki接入,实现 Markdown 文本编辑器
Django 后端架构开发:富文本编辑器权限管理与 UEditor 、Wiki接入,实现 Markdown 文本编辑器
172 0
|
2月前
|
存储 消息中间件 运维
架构升级的救星!流量回放自动化测试的必备指南
大家好,我是小米,一名29岁的技术宅。今天分享一个物联网领域的实用技能——流量回放自动化测试。系统重构后,测试工作量巨大,本文介绍如何通过日志收集和数据回放进行自动化测试,包括离线、实时和并行回放模式,帮助快速定位Bug,提升测试效率和系统稳定性。欢迎关注我的微信公众号“软件求生”,获取更多技术干货!
58 3
|
4月前
|
负载均衡 应用服务中间件 网络安全
Django后端架构开发:Nginx服务优化实践
Django后端架构开发:Nginx服务优化实践
65 2
|
4月前
|
消息中间件 存储 监控
Django后端架构开发:Celery异步调优,任务队列和调度
Django后端架构开发:Celery异步调优,任务队列和调度
77 1
|
4月前
|
存储 缓存 关系型数据库
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
Django后端架构开发:缓存机制,接口缓存、文件缓存、数据库缓存与Memcached缓存
86 0