Django mysql 多线程_【实例:利用Django管理后台管理IP地址】(四)Django test+多线程+数据库+(踩坑)...
準(zhǔn)備在views.py編寫函數(shù),多線程檢測每個(gè)IP地址的占用情況。胡亂一通寫完之后,哦豁,怎么測試寫得對(duì)不對(duì)呢?
一開始想單獨(dú)測試views.py文件,結(jié)果要引入各種包和配置文件,還要注意各種順序,各種按照網(wǎng)上指導(dǎo)折騰了兩三個(gè)小時(shí)還是一堆報(bào)錯(cuò)。
喝了口茶細(xì)想,最后函數(shù)是要放進(jìn)框架里用的,現(xiàn)在的各種設(shè)置和引入還要注釋掉的,長嘆一口氣,大可不必呀。
于是繼續(xù)翻書,原來django有內(nèi)置的單元測試框架unittest,真是有刀🔪不用非要用手劈柴。。。
坑🕳概述:在test.py中直接調(diào)用主函數(shù),主函數(shù)里啟用了多線程調(diào)用子函數(shù),主線程能獲取數(shù)據(jù)庫數(shù)據(jù),子線程卻獲取不到數(shù)據(jù)庫數(shù)據(jù)。
梳理django默認(rèn)測試行為:
1、執(zhí)行全局的測試準(zhǔn)備工作
2、在當(dāng)前目錄中查找名稱匹配test*.py模式的測試文件
3、創(chuàng)建測試數(shù)據(jù)庫
4、運(yùn)行遷移,把模型和初始數(shù)據(jù)填充到測試數(shù)據(jù)庫中
5、運(yùn)行找到的測試
6、銷毀測試數(shù)據(jù)庫
7、執(zhí)行全局的測試后的清理工作
簡單描述我的代碼實(shí)現(xiàn):
1 #《views.py》
2 frommysiteapp.models3 importipaddr_infoimport subprocess4 importthreading5
6 #子函數(shù)
7 defip_status_alarm(ip):8 print("子函數(shù)", ipaddr_info.objects.all())9
10 #主函數(shù)
11 defstart_ping(ip):12 print("主函數(shù)", ipaddr_info.objects.all())13 item=threading.Thread(target=ip_status_alarm, args=(ip,))14 item.start()15 item.join()16
17 #《test.py》
18 from django.test importTestCase19 from mysiteapp importviews20 from mysiteapp.models importipaddr_info21
22 #Create your tests here.
23 classstart_ping_test(TestCase):24 defsetUp(self):25 ipaddr_info.objects.create(ipaddr="1.1.1.1", ipstatus="0", disconnect_alarm_num=5)26 ipaddr_info.objects.create(ipaddr="2.2.2.2", ipstatus="1", connect_alarm_num=5)27 print("開始", ipaddr_info.objects.all())28
29 deftest_ping(self):30 ip='1.1.1.1'
31 views.start_ping(ip) #從主函數(shù)進(jìn)去,調(diào)用子函數(shù)的時(shí)候查無數(shù)據(jù)
32 # views.ip_status_alarm(ip) #直接從子函數(shù)進(jìn)去,才有數(shù)據(jù)
33
34 deftearDown(self):35print("結(jié)束", ipaddr_info.objects.all())
執(zhí)行31行views.start_ping(ip),注釋掉32行輸出結(jié)果:
開始 , ]>
主函數(shù) , ]>
子函數(shù)
結(jié)束 , ]>
執(zhí)行32行views.ip_status_alarm(ip),注釋掉31行輸出結(jié)果:
開始 , ]>
子函數(shù) , ]>
結(jié)束 , ]>
解決方法:
替換23行class start_ping_test(TestCase):? ,并按照提示導(dǎo)入包
class start_ping_test(TransactionTestCase):
原因:
真正的問題是這樣的,start_ping_test繼承自TestCase,TestCase將數(shù)據(jù)保留在內(nèi)存中,并且不向數(shù)據(jù)庫發(fā)出COMMIT(或者不會(huì)立即commit)。線程可能正在嘗試直接連接到DB,而數(shù)據(jù)尚未提交到那里。所以在另外一個(gè)線程中看不到這些數(shù)據(jù)。Django提供的另一個(gè)測試基類(TransactionTestCase)可以解決這個(gè)問題。
1 TransactionTestCase和TestCase相同,除了將數(shù)據(jù)庫重置為已知狀態(tài)的方式以及測試代碼測試提交和回滾的效果的能力。2 TransactionTestCase通過截?cái)嗨斜聿⒅匦录虞d初始數(shù)據(jù)來在測試運(yùn)行之前重置數(shù)據(jù)庫。3 TransactionTestCase可以調(diào)用提交和回滾,并觀察這些調(diào)用對(duì)數(shù)據(jù)庫的影響。
附:執(zhí)行測試命令
1. 測試項(xiàng)目中所有的應(yīng)用
python3 manage.py test
2. 測試項(xiàng)目中單獨(dú)的應(yīng)用
python3 manage.py test app01
3. 運(yùn)行項(xiàng)目中某個(gè)應(yīng)用的測試文件中的一個(gè)Case
python3 manage.py test app01.test2.AuthorTestCase
4. 運(yùn)行項(xiàng)目中某個(gè)應(yīng)用的測試文件中的一個(gè)Case中的其中一個(gè)測試方法
python3 manage.py test app01.test2.AuthorTestCase.test_insert_data
5. 運(yùn)行單元測試結(jié)束時(shí)不自動(dòng)刪除測試數(shù)據(jù)庫(保留測試數(shù)據(jù)庫)
python3 manage.py test app01 --keepdb
總結(jié)
以上是生活随笔為你收集整理的Django mysql 多线程_【实例:利用Django管理后台管理IP地址】(四)Django test+多线程+数据库+(踩坑)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java opencv 环境_基于jav
- 下一篇: java单循环 比较得分_java –