django settings 定义的变量不存在_一篇文章搞定Django的单元测试

相关资源

Django官方文档  https://docs.djangoproject.com/en/1.10/topics/testing/unittest文档  http://pyunit.sourceforge.net/pyunit_cn.html

用例

from django.test import TestCasefrom app.models import Author# Django的单元测试基于unittest库class AuthorTestCase(TestCase):    # 测试函数执行前执行    def setUp(self):        print("this is setUp")    # 需要测试的内容    def test_add(self):        author = Author(name='Tom')        author.save()        self.assertEqual(author.name, 'Tom')        # 需要测试的内容    def test_check_exit(self):        self.assertEqual(0,  Author.objects.count())     # 测试函数执行后执行    def tearDown(self):        print("this is tearDown")

关于django的单元测试,需要知道的是

  1. 对于每一个测试方法都会将setUp()和tearDown()方法执行一遍
  2. 会单独新建一个测试数据库来进行数据库的操作方面的测试,默认在测试完成后销毁。
  3. 在测试方法中对数据库进行增删操作,最后都会被清除。也就是说,在test_add中插入的数据,在test_add测试结束后插入的数据会被清除。
  4. django单元测试时为了模拟生产环境,会修改settings中的变量,例如, 把DEBUG变量修改为True, 把ALLOWED_HOSTS修改为[*]。

执行单元测试

在单元测试中,可以指定测试粒度。这样可以专注于只测试还没测试的单元测试,而已经测试过的就不测试了。

# 测试整一个工程$ ./manage.py test # 只测试某个应用$ ./manage.py test app --keepdb# 只测试一个Case$ ./manage.py test animals.tests.AuthorTestCase# 只测试一个方法$ ./manage.py test animals.tests.AuthorTestCase.test_add

常见问题的解决

数据表多是创建数据库销毁过多时间

在单元测试时,若migrations的文档过多时,每次单元测试时间绝大部分都消耗在数据库的创建。不过,单元测试代码运行只要几十秒,而数据库的创建却用去了十几分钟。这是个让人感到不舒服,不过django提供了【--keepdb】命令可以在进行单元测试后不删除数据库。

指定测试数据库的默认字符集

在创建测试数据库时,数据库的默认字符集也许不是我们想要的例如latin1。可以通过在数据库配置中指定TEST_CHARSET, TEST_COLLATION 参数,来指定字符集以及排序规则

DATABASES = {    'default': {        'ENGINE': 'django.db.backends.mysql',        'NAME': 'xxxx',        'USER': 'xxxx',        'PASSWORD': '',        'HOST': '127.0.0.1',        'PORT': '3306',        'OPTIONS': {            'charset': 'utf8mb4',            'init_command': 'SET default_storage_engine=INNODB',        },        'TEST_CHARSET': 'utf8',        'TEST_COLLATION': 'utf8_general_ci',    }}

** settings变量的修改**

若需要在单元测试时修改setting配置。例如,django在单元测试时会将settings.DEBUG 设置为True, 而我们需要将其设置为False。

方式一:直接在修改

class BaseApiTest(TestCase):    def setUp(self):        settings.DEBUG = False            def test_arm(self):        self.assertEqual(100, 50+50)        def tearDown(self):        pass

方式2: 通过装饰器修改

from django.test.utils import override_settings    class BaseTest(TestCase):       def setUp(self):        pass        # 利用该装饰器,可以在但个测试函数内修改settings变量, 而不影响    @override_settings(DEBUG=False)    def test_arm(self):        self.assertEqual(100, 50+50)        def tearDown(self):        pass

API权限问题的解决

在测试API的时候,往往需要等等进行用户登录才有权限调用,此时需要指定登录用户来解决接口调用的权限问题

# 如果是API使用了rest_framework框架from rest_framework.test import APIClientfrom uuid import uuid1class BaseTest(TestCase):       def setUp(self):                # 创建一个用户        self.user = create_user(uuid1().hex, '123456789')        self.client = APIClient()                # 通过force_authenticate函数来执行用户        self.client.force_authenticate(self.user)        def test_arm(self):        self.assertEqual(100, 50+50)        def tearDown(self):        pass

Celery异步任务的测试

在代码中几乎肯定是会有celery异步任务,若想对异步任务进行单元测试。可以将CELERY_ALWAYS_EAGER=True, BROKER_BACKEND='memory'

from xxxxxx.celery import app@app.task(bind=True)def add(self,x, y):    return x + yclass TaskTest(TestCase):    def setUp(self):        settings.CELERY_ALWAYS_EAGER = True            def test_add(self):        self.assertEqual(2, add.apply_async((1,1)))        def tearDown(self):        pass

单元的等级

Grade_First:正常的逻辑可可以用,输入一个正常值,可以输出预定的输出Grade_Second:异常逻辑可以用,就是输入一个异常值,不会输出系统的报错,而是自己捕捉到的报错Grade_Third:极端情况和边界数据可以用,对输入参数的边界情况也要单独测试,确保输出是正确有效的Grade_Fourth:所有分支、循环的逻辑走通Grade_Fifth:输出数据的所有字段验证,确保每个字段都是正确的地方

#python##测试##程序员#

007819f6d3944318e954aaa8fb0d9549.png
d701ea8362f926a2fb24f0f5d3308a52.png
2027c1c4ad65e862ed209a983c3a425f.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值