python+appium自動化測試-Appium并發(fā)測試之多設備啟動

來自APP Android端自動化測試初學者的筆記,寫的不對的地方大家多多指教哦

一、啟動appium服務器

1.通過命令行窗口啟動單個appium服務器

appium  --  直接打開默認的4723端口號
appium -p 4723  --  使用-p來啟動固定端口號的appium服務器

2.通過命令行窗口啟動多個appium服務器

appium -p 4723
appium -p 4726

二、啟動多個設備

1.在yaml文件配置Capability參數(shù)

desired_caps.yaml

platformName: Android
platformVersion: '9'
deviceName: U4AIUKFAL7W4MJLR
appPackage: com.sina.weibo
appActivity: com.sina.weibo.SplashActivity
automationName: UiAutomator2
autoGrantPermissions: True
noReset: True
url: 127.0.0.1

注意:

  • 手機系統(tǒng)版本號屬于字符串格式,需要加''引號
  • url為appium服務器的地址
  • 啟動多個設備需要啟動多個appium服務,所以這邊不設置端口號

2.代碼實現(xiàn)

from time import ctime
import yaml
from appium import webdriver

devices_list = ['U4AIUKFAL7W4MJLR', 'U4AIUKFAL7W4MHUHUDS']
with open(r"E:\\\\study\\\\Fork\\\\WeiboDemo\\\\Weibo\\\\config\\\\desired_caps.yaml", 'r') as file:
    data = yaml.load(file, Loader=yaml.FullLoader)

def multi_app_start(udid, port):
    desired_caps = {'platformName': data['platformName'],
                    'platformVersion': data['platformVersion'],
                    'deviceName': data['deviceName'],
                    'udid': udid,
                    'appPackage': data['appPackage'],
                    'appActivity': data['appActivity'],
                    'automationName': data['automationName'],
                    'autoGrantPermissions': data['autoGrantPermissions'],
                    'noReset': data['noReset']
                    }
    print('appium port:%s start run %s at %s' % (port, udid, ctime()))

    driver = webdriver.Remote('http://' + str(data['url']) + ':' + str(port) + '/wd/hub', desired_caps)
    driver.implicitly_wait(10)
    return driver

# 測試函數(shù),在實際運行過程中可以注釋
if __name__ == '__main__':
    multi_app_start(devices_list[0], 4723)
    multi_app_start(devices_list[1], 4725)

注意:

  • 需要開啟兩個appium服務,且端口號不能一樣
  • 連接的設備主要根據(jù)udid連接,而不是根據(jù)yaml文件中的deviceName,所以在yaml文件中的deviceName可以隨意設置
  • ctime()表示當前時間
  • 以上為成功啟動一個后才會啟動另外一個,不是同步啟動兩個設備

最后運行結果為:

image.png

對以上代碼封裝成類:

class MultiDevices:
    driver: webdriver = None
    devices_list = ['U4AIUKFAL7W4MJLR', 'U4AIUKFAL7W4MHUHUDS']

    def appium_desire(self, udid, port):
        with open(r"E:\\study\\Fork\\WeiboDemo\\Weibo\\config\\desired_caps.yaml", 'r') as file:
            data = yaml.load(file, Loader=yaml.FullLoader)

        desired_caps = {'platformName': data['platformName'],
                        'platformVersion': data['platformVersion'],
                        'deviceName': data['deviceName'],
                        'udid': udid,
                        'appPackage': data['appPackage'],
                        'appActivity': data['appActivity'],
                        'automationName': data['automationName'],
                        'autoGrantPermissions': data['autoGrantPermissions'],
                        'noReset': data['noReset']
                        }
        print('appium port:%s start run %s at %s' % (port, udid, ctime()))

        self.driver = webdriver.Remote('http://' + str(data['url']) + ':' + str(port) + '/wd/hub', desired_caps)
        self.driver.implicitly_wait(10)
        return self.driver

# 測試函數(shù),在實際運行中可以注釋
if __name__ == '__main__':
    mas1 = MultiDevices()
    mas2 = MultiDevices()
    mas1.appium_desire(MultiDevices.devices_list[0], 4723)
    mas2.appium_desire(MultiDevices.devices_list[1], 4725)

三、多進程并發(fā)啟動設備

  • 多進程中,同一個變量,各自有拷貝一份存在于每個進程中,互不影響
  • 多線程中,所有變量都由所有線程共享,任意一個比那輛都可以被任何一個線程修改,因此,線程之間共享數(shù)據(jù)最大的危險在于多個線程同時改一個變量,容易把內(nèi)容改亂了

所以我使用的是多進程并發(fā)啟動設備

yaml文件同上,代碼實現(xiàn)如下:

import multiprocessing
from time import ctime
import yaml
from appium import webdriver

devices_list = ['U4AIUKFAL7W4MJLR', 'U4AIUKFAL7W4MHUHUDS']
with open(r"E:\\\\study\\\\Fork\\\\WeiboDemo\\\\Weibo\\\\config\\\\desired_caps.yaml", 'r') as file:
    data = yaml.load(file, Loader=yaml.FullLoader)

def multi_app_start(udid, port):
    desired_caps = {'platformName': data['platformName'],
                    'platformVersion': data['platformVersion'],
                    'deviceName': data['deviceName'],
                    'udid': udid,
                    'appPackage': data['appPackage'],
                    'appActivity': data['appActivity'],
                    'automationName': data['automationName'],
                    'autoGrantPermissions': data['autoGrantPermissions'],
                    'noReset': data['noReset']
                    }
    print('appium port:%s start run %s at %s' % (port, udid, ctime()))

    driver = webdriver.Remote('http://' + str(data['url']) + ':' + str(port) + '/wd/hub', desired_caps)
    driver.implicitly_wait(10)
    return driver

# 構建desired進程組
desired_process = []

# 加載desired進程
for i in range(len(devices_list)):
    port = 4723 + 2 * i
    # target="調(diào)用的方法",args="傳入的參數(shù)"
    desired = multiprocessing.Process(target=multi_app_start, args=(devices_list[i], port))
    desired_process.append(desired)

if __name__ == '__main__':
    # 啟動多設備執(zhí)行測試
    for desired in desired_process:
        desired.start()
    # 等所有進程結束后關閉
    for desired in desired_process:
        desired.join()

結果同上,但同時啟動,控制臺輸出的日志中時間一致

對以上代碼封裝成類

class MultiDevicesSync:
    driver: webdriver = None
    devices_list = ['U4AIUKFAL7W4MJLR', 'U4AIUKFAL7W4MHUHUDS']

    def multi_devices_sync(udid, port):
        with open(r"E:\\study\\Fork\\WeiboDemo\\Weibo\\config\\desired_caps.yaml", 'r') as file:
            data = yaml.load(file, Loader=yaml.FullLoader)

        desired_caps = {'platformName': data['platformName'],
                        'platformVersion': data['platformVersion'],
                        'deviceName': data['deviceName'],
                        'udid': udid,
                        'appPackage': data['appPackage'],
                        'appActivity': data['appActivity'],
                        'automationName': data['automationName'],
                        'autoGrantPermissions': data['autoGrantPermissions'],
                        'noReset': data['noReset']
                        }
        print('appium port:%s start run %s at %s' % (port, udid, ctime()))

        driver = webdriver.Remote('http://' + str(data['url']) + ':' + str(port) + '/wd/hub', desired_caps)
        driver.implicitly_wait(10)
        return driver

    # 構建desired進程組
    desired_process = []

    # 加載desired進程
    for i in range(len(devices_list)):
        port = 4723 + 2 * i
        # target="調(diào)用的方法",args="傳入的參數(shù)"
        desired = multiprocessing.Process(target=multi_devices_sync, args=(devices_list[i], port))
        desired_process.append(desired)

if __name__ == '__main__':
    multi_devices_sync = MultiDevicesSync()
    # 啟動多設備執(zhí)行測試
    for desired in multi_devices_sync.desired_process:
        desired.start()
    # 等所有進程結束后關閉
    for desired in multi_devices_sync.desired_process:
        desired.join()

補充:

1.進程和線程的區(qū)別?

進程是計算機中的程序關于某數(shù)據(jù)集合上的一次運行活動,是系統(tǒng)進行資源分配和調(diào)度的基本單位,是操作系統(tǒng)結構的基礎。

線程有時也被稱為輕量級進程,是程序執(zhí)行流的最小單元。線程是進程中的一個實體,一個進程可以包含多個線程,但是線程不能包含多個進程。線程自己不擁有系統(tǒng)資源,在單個程序中同時運行多個線程完成不同的工作,成為多線程。

區(qū)別:

數(shù)據(jù)空間的分配,子進程和父進程有不同的代碼和數(shù)據(jù)空間,而多個線程則共享數(shù)據(jù)空間,每個線程有自己的執(zhí)行堆棧和程序計數(shù)器為其執(zhí)行上下文。

可以將進程看成是一個工廠,多個進程就是多個工廠;把線程看成是工廠里面的流水線,一個工廠中可以同時有多個流水線。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容