teprunner測試平台定時任務這次終於穩了


teprunner測試平台已經有一個多月沒有更新了,主要原因是定時任務不夠穩定,經過反復試錯,找到了解決辦法,這次終於穩定了。

本文開發內容

作為測試平台而言,定時任務算是必備要素了,只有跑起來的自動化,才能算是真正的自動化。本文將給測試計划添加定時任務功能,具體如下:

  • 前端添加測試計划的定時任務開關
  • 采用crontab表達式設置計划時間
  • 后端集成django-apschedule,在數據庫中記錄任務明細和執行詳情。
  • 定時清理執行記錄。

前端效果圖:

image-20210528222640069

前端開發內容

編輯src/views/teprunner/plan/PlanEditor.vue文件:

image-20210528222823663

運行環境用el-select實現了下拉框,用el-switch實現了開關按鈕。

image-20210528223000259

el-pophover實現了幫助描述,可以參考編寫crontab表達式。

image-20210528223141339

在data中添加了表單項taskRunEnv、taskStatus、taskCrontab,必填規則,以及其他變量。

image-20210528223326133

頁面創建時讀取localStorage中的計划信息。

image-20210528223407162

並獲取運行環境下拉框選項。

image-20210528223437261

開關按鈕的文字是根taskStatus進行設置的。

image-20210528223522132

在保存時,給請求添加上新的這3個參數。

后端開發內容

第一步是安裝django-apscheduler,要么直接安裝:

pip install django-apscheduler

要么更新項目代碼后通過requirements.txt安裝:

pip install -r requirements.txt

然后編輯teprunnerbackend/settings.py文件:

image-20210528223904507

在INSTALLED_APPS中添加django_apscheduler。

接着遷移數據庫,創建兩張任務表,一張任務明細表,一張任務執行情況表

python manage.py migrate

image-20210528224044201

編輯teprunner/models.py文件:

image-20210528224148248

給Plan模型添加3個字段。

編輯teprunner/serializers.py文件:

image-20210528224243250

同樣的,給PlanSerializer添加3個字段。

新建teprunner/views/task.py文件:

image-20210528224352704

創建BackgroundScheduler的對象實例,Background指的是在后台運行。並添加DjangoJobStore,把任務通過Django保存到數據庫中。

image-20210528224622874

添加一個定時刪除執行記錄的任務,max_age是最大保存時間,這里設置為7天。scheduler.add_job()用來添加定時任務,trigger是觸發器,也就是計划時間,這里設置為每周一0點。id是任務的標識符。max_instances指同時最多只有一個實例。replace_existing設置為True,每次都更新已存在的任務,防止重啟服務導致scheduler.add_job()報錯。

image-20210528225020524

啟動任務。

編輯teprunner/views/run.py文件:

image-20210528225152787

為了手動執行測試計划和定時任務執行測試計划共用,這里把執行代碼抽取了部分作為run_plan_engine()函數。

編輯teprunner/views/plan.py文件:

image-20210528225455141

重寫create方法,先根據測試計划的名字判斷是否已存在,如果存在就直接返回500。接着判斷開關如果開啟,那么就通過scheduler.add_job()添加任務。跟剛才添加任務的有點區別是,通過args參數指定了func函數的參數。最后把任務添加日志寫到響應中返回。

image-20210528225724696

重寫update方法,先判斷測試計划是否已經存在,判斷規則是根據名字去查找已存在記錄,如果找到同名計划,且id不是自己,那么就認為已存在同名計划,直接返回500。

image-20210528225911350

然后判斷如果開關打開,就新增任務;如果開關關閉,就刪除任務,刪除任務使用scheduler.remove_job()。

image-20210528230002678

最后重寫destroy方法,在刪除測試計划時,一並刪除定時任務。

猴子補丁解決pymysql連接問題

為什么定時任務會不穩定?因為我用的pymysql庫,它不會進行數據庫連接斷開后重試。Django和MySQL建立建立后,何時斷開連接通過CONNECT_MAX_AGE來設置,默認是0,表示使用完馬上斷開連接。Django只會對Web請求采取這個策略,使用signals.request_started.connect(close_old_connections)和signals.request_finished.connect(close_old_connections)來關閉舊連接。但定時任務不是Web請求,而是直接連接數據庫,Django並不會去主動斷開這個連接。而MySQL默認8小時會把連接斷掉,於是當Django拿着已經被MySQL斷開的連接對象去請求MySQL,就報錯了。

當我在本地安裝了MySQL后,重啟MySQL就能復現這個問題。

解決辦法一是把舊連接復活,進行斷線重連,但是會導致連接占用可能越來越多,耗費資源。解決辦法二是像Django處理Web請求一樣,每次用完就斷開,下次使用再重新連接,占用資源少。

猴子補丁是指不修改第三方庫的基礎上,對庫的功能進行擴展。我給django-apscheduler寫了個猴子補丁,實現第二個解決辦法,用完就斷開連接:

image-20210528231438135

並且通過issue方式,告訴了它的作者:

image-20210528231757896

這開啟了我在GitHub上英文交流技術的大門。

比如我又給loguru提了個bug,此時已經和loguru的作者英文交流了5個回合。

小結

本文給測試計划添加了定時任務功能,為teprunner測試平台補上了一塊重要拼圖。從此它不但能批量執行用例了,還能按照計划時間,定時執行,實現了真正的自動化。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM