日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

django 单元测试小结

發(fā)布時(shí)間:2025/3/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 django 单元测试小结 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

測(cè)試的場(chǎng)景

框架Django1.8 測(cè)試工具 unittest, 要記得給test設(shè)置一個(gè)獨(dú)特的settings。

  • 測(cè)試請(qǐng)求 也就是測(cè)試整個(gè)view部分?官方案例?其中可能會(huì)遇到登錄,或者時(shí)session怎么模擬的問(wèn)題

  • 測(cè)試帶有orm的模塊

  • 需要mock的測(cè)試,比較多的情況是有第三方API調(diào)用, 發(fā)郵件,發(fā)短信這種
  • unittest提供的斷言種類挺多,但是經(jīng)常用的也就幾個(gè)?self.assertContains,?self.assertEqual,?self.assertTrue

    順便提下有用的選項(xiàng)(我這里是單獨(dú)給測(cè)試寫了一個(gè)settings), 為了提高測(cè)試速度,可以把用不到的中間件,installed_apps之類的多余配置給去掉。

    測(cè)試全部用例 python manage.py test --setting settings_test測(cè)試某個(gè)APP python manage.py test appname --setting settings_test測(cè)試某個(gè)app下的TeseCase類 python manage.py test alarm.tests.ModelTestCase --setting settings_test -v {1,2,3} 數(shù)字越大,顯示的輸出越詳細(xì),測(cè)試的日志信息 python manage.py test --setting settings_test -v3 其他的選項(xiàng)請(qǐng)查看 --help python manage.py test --help
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    用請(qǐng)求測(cè)試 views函數(shù)

    DJANGO中提供了Client類來(lái)模擬http請(qǐng)求,可以模擬不同的method,然后就是請(qǐng)求參數(shù)的模擬,用起來(lái)很方面。

    #coding:utf-8 from django.test import TestCase, Clientfrom sendviews import * from core.tests import create_user class SendviewsTestCase(TestCase): def setUp(self): self.user = create_user() self.device = Device(hostname="CN-BJ-0000-00", mac="ff:ff:ff:ff:ff:ff", user=self.user).save() def test_creat_sms(self): c = Client() rep = c.post("/acquireportal/createsms",{"phone": "13988902345", "ssid": "erya", "dmac": "ff:ff:ff:ff:ff:ff"}) # 測(cè)試http請(qǐng)求的返回碼是否正確 self.assertEqual(rep.status_code, 200) # 測(cè)試response的內(nèi)容是否包含字符串 self.assertContains(rep, "OK") # 測(cè)試response的內(nèi)容是否包含字符串 方法二 self.assertTrue('OK' in rep.content)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 操作 session,例如用戶登錄,特殊的session值
    from django.test import Clientdef init_client(user): client = Client() client.login(username=user.username, password="lzz") s = client.session s['cur_user_id'] = user.id s.save() return client
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 增加header
    from django.test.utils import setup_test_environment setup_test_environment() from django.test.client import Client c = Client()# get 請(qǐng)求,帶參數(shù),并增加header c.get('/some/path/', {'qs_param':'foo'}, **{'HTTP_USER_AGENT':'silly-human', 'REMOTE_ADDR':'127.0.0.1'}) #get 請(qǐng)求,沒(méi)有帶參數(shù),自定義headers c.get('/some/path/', **{'HTTP_USER_AGENT':'silly-human', 'REMOTE_ADDR':'127.0.0.1'})
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 使用 RequestFactory 對(duì)象來(lái)進(jìn)行測(cè)試,不是從 http client來(lái)發(fā)起,某些情況會(huì)用到
    from django.test import TestCase, RequestFactory from django.http import HttpResponse from util.sign import generate_sign, validate_sign from util.decorators import apiauth_required, SIGN_KEY @apiauth_required() def simpleapi(request): return HttpResponse('ok') class DecoratorsTestCase(TestCase): def setUp(self): self.factory = RequestFactory() def test_apiauth(self): # create request object key = SIGN_KEY query_string = {u"name": u"lzz", u"age": u"20", u"data": u"[python, java, golang, lua]"} token = generate_sign(query_string, key) query_string.update({u"sign": token}) req = self.factory.post("/api/test", data=query_string) response = simpleapi(req) self.assertEqual(response.status_code, 200)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • HTML 文本測(cè)試,使用 constants 來(lái)判斷并不是個(gè)好的選擇,可以用render之后的字符串對(duì)比。

    對(duì)于需要登陸的view,有client也比較容易操作,還有一些特殊的session的檢測(cè)等, 我這里做了一個(gè)簡(jiǎn)單的封裝

    from django.test import Clientdef init_client(user): client = Client() client.login(username=user.username, password="lzz") s = client.session s['cur_user_id'] = user.id s.save() return client
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    帶有mock的測(cè)試

    對(duì)模塊中的方法mock或者是對(duì)一個(gè)對(duì)象中的方法進(jìn)行mock。真對(duì)測(cè)試函數(shù)中一些無(wú)法直接測(cè)試的函數(shù)設(shè)置默認(rèn)的返回值, py3標(biāo)準(zhǔn)庫(kù)中已經(jīng)有了mock模塊,py2需要自己安裝, 推薦教程?使用Pyhton Mock進(jìn)行單元測(cè)試1。 下面是個(gè)實(shí)際的代碼片段。

    import mock from django.test import TestCase from core.models import Tenant from alarm.models import * from .controler import TenantAlarm class ModelTestCase(TestCase): def setUp(self): self.tenant = Tenant.objects.create(domainname="erya", comname=u"爾雅") @mock.patch.object(TenantAlarm, "sendAlarm") def test_record_alarm(self, mock_method): # record_alarm 這個(gè)中會(huì)調(diào)用sendAlarm方法 mock_method.return_value = None content = "ccccc" atype = 0 rec_uid = 0 Alarm().record_alarm(content=content, atype=0, rec_tid=self.tenant.id) class TenantAlarmTestCase(TestCase): def setUp(self): self.tenant = Tenant.objects.create(domainname="erya", comname=u"爾雅") @mock.patch.object(TenantAlarm, "sendSMS", return_value=None) @mock.patch.object(TenantAlarm, "sendEmail", return_value=None) def test_send_alarm(self, method1, method2): content = u"報(bào)警了" ta = TenantAlarm(self.tenant.id, content, {u'SMS': 0, u'EMAIL': 0}) ta.sendAlarm() @mock.patch('util.sendsms_com.send', return_value=1) def test_sendsms(self, send): ta = TenantAlarm(self.tenant.id, self.content, {u'SMS': 0, u'EMAIL': 0}) ta.sendSMS() self.assertEqual(0, Account.objects.get(tenant=self.tenant).sms_num) self.account.sms_num = 100 self.account.save() ta.sendSMS() self.assertEqual(99, Account.objects.get(tenant=self.tenant).sms_num)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    coverage

    coverage是一個(gè)檢查單元測(cè)試覆蓋率的工具,django的文檔中也有簡(jiǎn)要的說(shuō)明coverage的集成?文檔地址

    #測(cè)試并收集測(cè)試信息 coverage run --source='.' manage.py test --setting mandela.settings_test #查看測(cè)試結(jié)果 coverage report -m Name Stmts Miss Cover Missing ---------------------------------------------------------------------------------------- acquireportal/__init__.py 0 0 100% acquireportal/controler.py 65 47 28% 22-56, 60-71, 76-79 acquireportal/migrations/0001_initial.py 6 0 100% acquireportal/migrations/0002_auto_20160622_1059.py 6 0 100% acquireportal/migrations/0003_auto_20160622_1100.py 5 0 100% .... ---------------------------------------------------------------------------------------- TOTAL 8013 5858 27%
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    覆蓋率挺低的��

    其他

    測(cè)試?Exception, 被測(cè)試的代碼有拋異常的情況,單元測(cè)試中需要觸發(fā)這個(gè)異常來(lái)測(cè)試。

    又個(gè)函數(shù)中可能會(huì)出現(xiàn) queryset get 返回多個(gè)結(jié)果

    from django.test import TestCase from django.core.exceptions import MultipleObjectsReturnedclass ControlerTest(TestCase): def setUp(self): self.user = User(username='test', email='lebing.zhou@cc.com', password='asdfadf') self.user.save() self.mac_addr = "ff:ff:ff:ff:ff:ff" self.mac = Mac(mac=self.mac_addr, user=self.user) self.mac.save() self.plan = BasePlan(name="包月", plan_type=1, month_price=19.9, goods=200) self.plan.save() def test_do_action3(self): self.mac2 = Mac(mac="ff:ff:ff:ff:ff:11", user=self.user) self.mac2.save() order = Order.objects.create_order(self.user, self.plan, 1, 1, "ff:ff:ff:ff:ff:fd") with self.assertRaises(MultipleObjectsReturned): do_action(order) #在出現(xiàn)這種異常的情況下,進(jìn)行后面的邊界測(cè)試 self.assertNotEqual(Mac.objects.get(mac=self.mac_addr).timeleft, 200)

    轉(zhuǎn)載于:https://www.cnblogs.com/1204guo/p/8059239.html

    總結(jié)

    以上是生活随笔為你收集整理的django 单元测试小结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。