django单元测试使用正确数据库(django框架的特点)

1. 单元测试的基本概念

单元测试是软件工程中降低开发成本,提高软件质量常用方式之一,单元测试是一项由开发人员或者测试人员来对程序模块的正确性进行检验测试的工作,用于检查被测试代码的功能是否正确,养成单元测试的习惯,不但可以提高代码的质量,还可以提升自己的编程和技巧。Django 单元测试使用的是 Python 标准库 unittest 模块来定义相应的测试用例。在本节我们先了解什么是单元测试以及作为开发人员在这个环节应该注意什么。单元测试其实就是对模块、类、函数实现的功能执行检测,看看是否满足预期,是否达到功能要求,它是一次检查检验的过程。如果某个模块或者函数满足预期,则表示测试通过,否则表示失败,比如工厂在组装一台电视机之前,会对每个元件都进行测试看是否合格,这就是单元测试,是不是很好理解。如果不局限于 Django 框架的话,除了单元测试以外,还有系功能测试、组件测试、系统集成测试等、测试是一项很重要的工作,有专门的职位比如软件测试人员、测试工程师等。

2. 为什么编写单元测试

其实这个问题就像你问为什么有质量检测员一样,所以可以看出编写单元测试的重要性,俗话说“人无完人,金无足赤”,开发人员也有犯错误的时候,这就需要编写单元测试来完成对自己代码的检查工作,那编写单元测试对于整个项目以及个人而言到底有哪些益处呢?下面就给大家进行一下总结:

1) 降低开发成本

单元测试可以快速的提供反馈,将问题在开发阶段就暴露出来。这样就可以减少向下游传递的问题,比如说在系统集成阶段出现了问题,这不就很麻烦吗?因为模块、组件太多,会给你无从下手的感觉。所以做好单元测试无疑是降低了软件的开发成本。有数据表明尽早地对软件产品进行测试将使效率和质量都得到最好的保证。Bug 发现的越晚,修改它所需的费用就越高,因此从费用成本角度来看, 应该尽可能早的查找和修改 Bug。在修改费用变的过高之前,单元测试是一种在早期抓住 Bug 的有效途径。

2) 边界检测提高代码质量

边界值检测方法是单元测试中常用的方法之一,举个例子,比如 1<x<10,那么边界值就是 0、2、9、11,因为在实际的使用中,我们不容易发现边界问题,比如注册用户名一般使用字母数字下划线等,那么如果使用特殊的符号又会怎么样呢?这就需要我们去检验。通过边界值检测的方法就能很好的解决这个问题,从而提高代码的质量。

3) 提高开发人员职业素养

由于互联网的发展,促使了软件行业的发展,企业在遵守行业标的同时也制定相关的企业标准使软件开发集成上线更加精细化,形成了一套完成的流程。对于部分开发者来说一旦编码完成,他们总是会迫切希望进行软件的集成工作,这样就能够看到系统的启动了。这在外表上看来确实是明显的进步,但实际而言只是为了进度而进步,严重忽略了单元测试的重要性,若出现问题只会浪费更多的时间成本。所以编写单元测试,不仅可以提升企业的效率,而且可以使开发人员站在用户的角度重新调整自己的代码,进行代码重构,代码的优化等,这也培养了开发人员的职业素养,提升的他们的编码能力,对于企业的长远发展是非常有利的。

3. 单元测试对象有哪些

通常情况下,项目开发的周期是比较紧张的,要想 100% 全覆盖地编写单元测试代码需要花费大量的时间。这时,就需要有选择地编写测试代码,对于功能实现很简单的函数,就可以考虑忽略。那么哪些代码应该做测试呢?在这里我们进行了简单的总结,如下所示:

1) 核心的业务层代码

对于项目中最核心的部分也就是业务层代码,这是单元测试不可忽视,且非常重要的一项,所以开发人员要保证不会错误。

2) 需要经常修改的代码

对于产品迭代或代码重构而言,可能有些模块需要经常被修改,它们也需要被单元测试所覆盖,这样可以检验修改后的代码是否存在问题。

3) 逻辑复杂的代码

涉及到逻辑层代码,也需要开发人员进行单元测试,做到零纰漏。尤其对于那些至关重要的逻辑代码,需要使用单元测试验证它的可用性,易用性。总之在单元测试有一个原则,即能够有效的完成有效的检验,又能把珍贵时间合理利用,不至于浪费,这就需要我们在单元测试环节中,做到灵活变通,不死板。作为开发人员,当我们完成一个功能的时候,就应该针对性的考虑是否要测试该功能,这样就避免了项目后期工作中的应接不暇。才能够更好的完成单元测试环节。

4.不是所有开发人员都会写单元测试

这里要理解一个误解、不是所有的开发工程师都会(这个会不是会去写而是会不会的意思)?

为什么这么说、可能一个开发人员他写完自己的功能模块时、只是简单的自测一下、而不是特定的去写单元测试用例、可能是他们并不知道怎么去写单元测试用例。单元测试主要采用白盒测试策略进行对自己的功能模块、方法、条件语句覆盖等进行测试输入输出是否正常。

一般单元测试会采用当前项目所使用的编程语言及开发框架中的单元测试模块进行测试,我们所用到的Django也是可以做单元测试的、基本上每个开发框架都会有单元测试的功能、我们今天要讲的就是Django 中的unittest。

5、进行单元测试

为了进一步提高提测质量,了解到Django有自带的单元测试,一行简单的代码就能测试所有(或指定)app下tests.py文件中的测试逻辑。

Django单元测试也是使用了python自带的unittest,Django的testTestCase继承了python的unittest.TestCase、因此我们学会django也可以用来做自动化测试框架的设计与搭建。

其实当我们使用 startapp 命令创建 app 应用的时候,你就会发现有一个 tests.py 文件,这个文件就是 Django 提供给开发者做单元测试的,在这个文件中给出了测试类需要继承的基类 TestCase,其中 django.test.TestCase 是 unittest.TestCase 的一个子类,实现了数据库访问以及 HTTP 请求等测试功能。

针对一个项目而言,因为它的模块众多,所以在做测试的时候为了更加直观、方便,我们通常在应用下创建一个测试目录用来承载不同模块的测试用例,按照模块的类别为不同的功能函数定义测试代码,如 test_models.py、test_vierws.py 分别指的是模层与视图层,以这样的命名方式来对文件命名。本节为了方便演示,我们只在 tests.py 中编写测试单元代码。

针对一个项目而言,因为它的模块众多,所以在做测试的时候为了更加直观、方便,我们通常在应用下创建一个测试目录用来承载不同模块的测试用例,按照模块的类别为不同的功能函数定义测试代码,如 test_models.py、test_vierws.py 分别指的是模层与视图层,以这样的命名方式来对文件命名。本节为了方便演示,我们只在 tests.py 中编写测试单元代码。

django单元测试使用正确数据库(django框架的特点)

1.项目单元测试常用方法接下来介绍不同场景下 Django 项目单元测试的实现方法以及执行测试用例的命令。我们以 user 应用为例,介绍三类最常见的测试场景:基础功能测试、模型测试、视图测试。

基础功能测试

基础功能测试即不涉及 Django 模块的逻辑功能,它和《Python unittest模块实现单元测试》一节中使用 unittest 模块实现的测试用例基本是类似的,只不过我们在这里继承的是 Django 中的测试模块即 unittest.TestCase 的子类 django.test.TestCase 。当然如果你愿意也可以继承 unittest.TestCase,不过不推荐。我们在 index/tests.py 中编写如下代码,实现两数加和的测试用例:

fromdjango.testimportTestCaseclassExampleTest(TestCase):deftest_addition(self):defaddition(x,y):returnx yself.assertEqual(addition(1,1),2,’assisfailed’)#断言函数加和运算

模型测试模型测试就是对 Model 的增删改查进行测试,测试类必须继承自 django.test.TestCase,它会在执行测试用例之前创建数据库,并在执行测试用例之后销毁。下面我们进行简单的测试用例代码说明,如下所示:

fromuser.modelsimportUserclassUserModelsTestCase(TestCase):defsetUp(self)->None:passdeftearDown(self)->None:passdeftest_create_user(self):create_user=User.objects.create(id=”unittest01″,username=”roottest”,nickname=”testcase”,password=”python”,)#创建一个用户self.assertTrue(create_userisnotNone)#进行断言创建的用户实例是正常被创建了而不是没有被创建

上述代码,我们做一下简单剖析,我们定义了 test_create_user函数,并创建了普通用户实例对象,之后还是和之前操作一样,我们是使用断言的方式对测试代码进行了有效的测试。虽然这里涉及到了数据库操作,但是该操作并不会影响数据库中原有数据。这些测试用例是相互隔离的,每一个测试用例都运行在一个事务中。

视图层测试视图层测试相比其他的项目单元测试方法略显复杂一点点,在这里需要引入测试客户端,它提供了 get、post 等方法实现了对视图的访问,测试客户端被封装在了如下模块中即 django.test.Client。测试类的每一个测试方法都可以直接使用测试客户端 self.client。每一个测试方法都会新建一个测试客户端,并且彼此之间互不影响,下面我们编写如下示例:

我们以这个视图接口为例

classUserViewTestCase(TestCase):defsetUp(self)->None:self.find=resolve(‘/api/cms/userInfo’)print(self.find.url_name)

resolve

运用resolve 函数解析Url 网站路径(”/api/cms/userInfo”)检查是否能够找到视图中的 home_page 函数及其他对象属性、上面我们看到可以拿到url的name。

下面我们就要解决的是如何进行传递token、这里是不能像requests一样加headers参数就可以解决的。

这个时候就要登场 Client类了:

Client 类

使用django.test.client.Client()来执行请求。

可以使用关键字参数来指定默认的请求报头:Client(HTTP_USER_AGENT=’Mozilla/5.0′)记得在USER_AGENT前加HTTP_。

接口是已经拿到了token了、只是token过期了而已、这样我们就能正常的向接口进行传递不同的请求header了。

我们使用 self.client.get 方法实现了对相应视图函数的访问,然后使用断言的方法,并调用 response 响应对象的方法或者属性进行了相关的测试。

项目中执行测试用例命令Django 提供了专门的命令用来执行测试,命令如下所示:

pythonmanage.pytest#执行的是整个项目下的tests.py文件下的脚本

这一看完全和unittest没啥区别、肯定啊django 是继承了unittest TestCase类、如何自己进行了封装了一些自己的方法而已、那么这样说的话、如果公司使用的是django开发的web后端、我们完全可以直接使用django来搭建自动化测试进行单元测试及集成测试。测试框架的原理都是一样的只是各个测试框架有自己的一套编码规范而已、其底部的运行原理都是与Junit一套原理罢了。

我们可以在项目的 manage.py 文件目录下直接执行此命令,但是该命令会将所有的测试结果都输出,如果你的每个应用下都做了单元测试,这显然会给你造成很错乱的感觉,所以我们可以使用下面的命令进行相关的测试输出:执行 user 应用下的所有测试用例:

pythonmanage.pytestuser

这里可以看见、都是只有user app下的文件被初始化了。。。

执行 user 应用下的具体测试模块:

pythonmanage.pytestuser.tests

执行 user 应用下 tests 模块下定义的测试类:

pythonmanage.pytestuser.tests.UserViewTestCase#user代表app目录#tests代表测试用例的文件#UserViewTestCase为模块下的测试用例类

直接执行 tests.py 文件下测试类下的具体测试方法:

pythonmanage.pytestuser.tests.UserViewTestCase.test_view

由此可见 test 命令之后可以提供指定的参数来执行测试用例,比如一个 Python 包、模块、测试类或者一个测试方法。我们还可以加上 -v 参数来更加详细的显示测试过程,不仅如此可以使用数字 0、1、2、3 来指定详细程度,数字越大表示输出越详细,只有这 4 个级别可选择,命令如下所示:

pythonmanage.pytest-v2user.tests

执行结果

<module’user.tests’from’F:\\code\\stackCMSAPI\\user\\tests.py’>Creatingtestdatabaseforalias’default'(‘test_stack_mall’)…Operationstoperform:Synchronizeunmigratedapps:drf_yasg,messages,staticfilesApplyallmigrations:admin,auth,contenttypes,goods,sessions,system,userSynchronizingappswithoutmigrations:Creatingtables…RunningdeferredSQL…Runningmigrations:Applyingcontenttypes.0001_initial…OKApplyingauth.0001_initial…OKApplyingadmin.0001_initial…OKApplyingadmin.0002_logentry_remove_auto_add…OKApplyingadmin.0003_logentry_add_action_flag_choices…OKApplyingcontenttypes.0002_remove_content_type_name…OKApplyingauth.0002_alter_permission_name_max_length…OKApplyingauth.0003_alter_user_email_max_length…OKApplyingauth.0004_alter_user_username_opts…OKApplyingauth.0005_alter_user_last_login_null…OKApplyingauth.0006_require_contenttypes_0002…OKApplyingauth.0007_alter_validators_add_error_messages…OKApplyingauth.0008_alter_user_username_max_length…OKApplyingauth.0009_alter_user_last_name_max_length…OKApplyingauth.0010_alter_group_name_max_length…OKApplyingauth.0011_update_proxy_permissions…OKApplyingauth.0012_alter_user_first_name_max_length…OKApplyinguser.0001_initial…OKApplyinggoods.0001_initial…OKOKApplyingsessions.0001_initial…OKApplyingsystem.0001_initial…OKApplyinguser.0002_auto_20210725_2122…OKApplyinguser.0003_filesave_isdelete…OKApplyinguser.0004_auto_20210802_1509…OKSystemcheckidentifiednoissues(0silenced).test_view(user.tests.UserViewTestCase)验证创建用户并使用查询接口获取用户信息…MTYyNzkwODMxMC42MzI0NzQ0OmFlYWYzNjEzZGE4N2EzZDU0MGNhYzMxOWFkZGI3MjQzYjA1MTE0Mzc=string{‘code’:1,’message’:’Token过期’,’messageCode’:2006}ok———————————————————————-Ran1testin0.056sOKDestroyingtestdatabaseforalias’default'(‘test_stack_mall’)…

Django 项目的单元测试到这里大概就讲解完毕了,让大家认识了什么是单元测试、单元测试模块 unittest 是如何应用的以及 Python unittest 模块如何在 Django 中进行使用,希望大家通过这些介绍掌握知识的精髓。这里我就不带着大家进行做全面的单元测试了、大家可以下载项目源码进行自行去练习。。。

由于项目实战阶段需要调整、上面的这些接口是原本打算使用之前确定好的项目来进行整个系列的教程演示的,

目前考虑需要换项目或者调整项目因此开启了”超前推送”先例后面的教程继续更新、项目阶段将以全新的姿态进行

后续补充。。。

非常的遗憾我这个项目已经cms 接口都已经开写完了。。。

发表评论

登录后才能评论