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