app自動化11 執行緒實現多個指令碼在多個手機執行
阿新 • • 發佈:2020-10-13
執行緒
多工簡單介紹
- 有很多事情在現實生活的場景中是同時進行的,比如開車的時候 手和腳共同來駕駛汽車,再比如唱歌跳舞也是同時進行的。- 多工,就是能夠在同一時間同時進行多個任務。這樣同時進行多個任務,有一個極大的好處,那就是節省時間程式碼舉例import time import threading def sing(): for i in range(5): print("唱歌") time.sleep(1) def dance(): for i in range(5): print("跳舞") time.sleep(1) t1 = threading.Thread(target=sing) t2 = threading.Thread(target=dance) t1.start() t2.start()
import time
import threading
def sing():
for i in range(5):
print("唱歌")
time.sleep(1)
def dance():
for i in range(5):
print("跳舞")
time.sleep(1)
sing()
dance()
第一段程式碼開啟3個執行緒,分別是主執行緒,子執行緒t1,子執行緒t2,耗時一共是5秒第二段程式碼開啟1個執行緒,那就是主執行緒,耗時一共是10秒為什麼第一段程式碼耗時只要5秒,而第二段程式碼耗時要10秒呢?
下面就由sunt來為大家說下原因吧,先分析第一段程式碼:主執行緒先開始執行,然後讓兩個小弟,也就是子執行緒t1,t2。分別去執行sing()和dance()程式碼,這兩個小弟是並行執行的,並不是說小弟t1先執行完,小弟t2才去執行,而是兩個小弟同時執行,故耗時為5秒,圖解如下:打印出來結果:
唱歌
跳舞
跳舞
唱歌
跳舞
唱歌
跳舞
唱歌
跳舞
唱歌
這是因為當他們從休眠到喚醒是同時的,故資源掠奪的不確定性,有可能跳舞先執行,也有可能唱歌先執行,不過一定是成對出現的。並行執行耗時總時間為5秒。接下來分析第二段程式碼:主執行緒先開始執行,然後主執行緒執行sing()程式碼塊,等待sing()程式碼塊執行完之後,才開始執行dance()程式碼塊。故耗時為sing()程式碼塊的時間加dance()程式碼塊的時間,一共為10秒。圖解如下:
多工的原理
執行緒的兩張建立方式
- 直接使用threading模組的Thread類,指定要執行的方法,再呼叫start- 使用繼承的方式,繼承Thread類,重新run方法,建立這個物件後,再呼叫start檢視當前程式執行緒數量
threading.enumerate()- 獲取所有執行緒,返回的是一個列表。- 如果需要個數,使用len(threading.enumerate())
為子執行緒傳遞引數
target方式import time
import threading
def sing(nums):
for i in range(nums):
print("唱歌")
time.sleep(1)
def dance():
for i in range(5):
print("跳舞")
time.sleep(1)
t1 = threading.Thread(target=sing, args=(3,))
t2 = threading.Thread(target=dance)
t1.start()
t2.start()
類繼承方式import threading
class Work1(threading.Thread):
def __init__(self, nums):
super().__init__()
self.nums = nums
def run(self):
for i in range(self.nums):
print("haha")
def main():
w = Work1(2)
w.start()
if __name__ == "__main__":
main()
Appium多埠
目標,讓一個指令碼去跑到多臺手機。注意點: appium sever埠要不同,開啟多個。bootstrap埠要不同,開啟多個。udid需要指定,udid表示裝置的唯一表示符號,通過 adb devices 檢視。 前半部分都是,比如模擬器的(192.168.57.101:5555)。appium server 和 bootstrap 和 udid 應該是成對出現的。
命令:
appium -p 4723 -bp 4724 -U 192.168.57.101:5555
-p 表示 appium的埠-bp 表示 bootstrap的埠-U 表示裝置的識別符號
修改init_driver讓,init_driver接受port的引數。並且進行對應的連線。
記得,建立的是不同的driver物件。
因為如果使用threading.Thread的這種形式,需要指定執行的函式,所以,把需要執行的程式碼,封裝成一個函式。然後使用
ports = ["4723", "4725"]
for i in ports:
threading.Thread(target=do, args=(i,)).start()
來去執行建立多個driver並且進行指令碼的操作。下面看圖解就知道appium多埠的工作原理了。依照上圖可以知道,如果要想讓一段指令碼操作兩個手機,那麼我要做的就是,開啟兩個appium服務和兩個bootstrap服務,並且埠號不能相同,appium和bootstrap是一對,並且有兩個手機,還要指定手機裝置號,故命令如下appium -p 4723 -bp 4724 -U 192.168.57.101:5555
appium -p 4725 -bp 4726 -U 192.168.57.102:5555
程式碼實現
命令列先啟動appium並指定埠,並指定bootstrap埠和手機裝置號appium -p 4723 -bp 4724 -U 192.168.57.101:5555
appium -p 4725 -bp 4726 -U 192.168.57.102:5555
base_driver.pyfrom appium import webdriver
def init_driver(port="4723"):
# server 啟動引數
desired_caps = dict()
# 裝置資訊
desired_caps['platformName'] = 'Android'
desired_caps['platformVersion'] = '5.1'
desired_caps['deviceName'] = '192.168.164.101:5555'
# app資訊
desired_caps['appPackage'] = 'com.android.settings'
desired_caps['appActivity'] = '.Settings'
# 中文
desired_caps['unicodeKeyboard'] = True
desired_caps['resetKeyboard'] = True
# 不重置應用
desired_caps['noReset'] = True
# toast
# desired_caps['automationName'] = 'Uiautomator2'
# 宣告物件
driver = webdriver.Remote('http://localhost:' + port + '/wd/hub', desired_caps)
return driver
login_page.pyfrom base_action import BaseAction
class LoginPage(BaseAction):
pass
demo.pyimport threading
from selenium.webdriver.common.by import By
from base_driver import init_driver
from base_action import BaseAction
from login_page import LoginPage
def do(port):
driver = init_driver(port)
login_page = LoginPage(driver)
if "4723" == port:
login_page.click((By.XPATH, "text,更多"))
else:
login_page.click((By.XPATH, "text,WLA"))
def main():
//根據ports不同,driver可以連線不同的手機
ports = ["4723", "4725"]
for i in ports:
threading.Thread(target=do, args=(i,)).start()
if __name__ == '__main__':
main()