Pytest系列(17)- pytest-xdist分布式測試的原理和流程


如果你還想從頭學起Pytest,可以看看這個系列的文章哦!

https://www.cnblogs.com/poloyy/category/1690628.html

 

pytest-xdist分布式測試的原理

前言

  • xdist的分布式類似於一主多從的結構,master機負責下發命令,控制slave機;slave機根據master機的命令執行特定測試任務
  • 在xdist中,主是master,從是workers

 

大致原理

  1. xdist會產生一個或多個workers,workers都通過master來控制
  2. 每個worker負責執行完整的測試用例集,然后按照master的要求運行測試,而master機不執行測試任務

 

pytest-xdist分布式測試的流程

第一步:創建worker

  1. master會在總測試會話(test session)開始前產生一個或多個worker
  2. master和worker之間是通過execnet和網關來通信的
  3. 實際編譯執行測試代碼的worker可能是本地機器也可能是遠程機器

 

第二步:收集測試項用例

  1. 每個worker類似一個迷你型的pytest執行器
  2. worker會執行一個完整的test collection過程【收集所有測試用例的過程】
  3. 然后把測試用例的ids返回給master
  4. master是不會執行任何測試用例集的

注意

所以為什么上面通過分布式測試的結果截圖是沒有輸出用例的print內容,因為主機並不執行測試用例,pycharm相當於一個master

 

第三步:master檢測workers收集到的測試用例集

  1. master接收到所有worker收集的測試用例集之后,master會進行一些完整性檢查,以確保所有worker都收集到一樣的測試用例集(包括順序)
  2. 如果檢查通過,會將測試用例的ids列表轉換成簡單的索引列表,每個索引對應一個測試用例的在原來測試集中的位置
  3. 這個方案可行的原因是:所有的節點都保存着相同的測試用例集
  4. 並且使用這種方式可以節省帶寬,因為master只需要告知workers需要執行的測試用例對應的索引,而不用告知完整的測試用例信息

 

第四步:測試用例分發

--dist-mode選項

each:master將完整的測試索引列表分發到每個worker

load:master將大約25%的測試用例以輪詢的方式分發到各個worker,剩余的測試用例則會等待workers執行完測試用例以后再分發

 

注意

可以使用  pytest_xdist_make_scheduler  這個hook來實現自定義測試分發邏輯。

 

第五步:測試用例的執行

  1. workers 重寫了   pytest_runtestloop  :pytest的默認實現是循環執行所有在test session這個對象里面收集到的測試用例
  2. 但是在xdist里, workers實際上是等待master為其發送需要執行的測試用例
  3. 當worker收到測試任務, 就順序執行  pytest_runtest_protocol 
  4. 值得注意的一個細節是:workers 必須始終保持至少一個測試用例在的任務隊列里, 以兼容  pytest_runtest_protocol(item, nextitem)   hook的參數要求,為了將 nextitem傳給hook
  5. worker會在執行最后一個測試項前等待master的更多指令
  6. 如果它收到了更多測試項, 那么就可以安全的執行   pytest_runtest_protocol  , 因為這時nextitem參數已經可以確定
  7. 如果它收到一個 "shutdown"信號, 那么就將 nextitem 參數設為 None, 然后執行 pytest_runtest_protocol

 

第六步:測試用例再分發(--dist-mode=load)

  1. 當workers開始/結束執行時,會把測試結果返回給master,這樣其他pytest hook比如:  pytest_runtest_protocol  和  pytest_runtest_protocol  就可以正常執行
  2. master在worker執行完一個測試后,基於測試執行時長以及每個work剩余測試用例綜合決定是否向這個worker發送更多的測試用例

 

第七步:測試結束

  1. 當master沒有更多執行測試任務時,它會發送一個“shutdown”信號給所有worker
  2. 當worker將剩余測試用例執行完后退出進程
  3. master等待所有worker全部退出
  4. 然此時仍需要處理諸如  pytest_runtest_logreport  等事件


免責聲明!

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



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