如题。在运行代码前,需要使用cmd命令“appium -p xxxx(port号)”开启多个appium服务器,并且确保被测的设备与PC连接ok。
#此代码是为了封装APP启动配置信息,log存储配置信息,方便日后开发自动化测试程序时调用,而且方便代码的维护修改
import os
import yaml
from appium import webdriver
import multiprocessing
# import logging
import logging.config
CON_LOG = '../config/log.conf'
logging.config.fileConfig(CON_LOG)
logger = logging.getLogger()
devices_list = ['127.0.0.1:62001','127.0.0.1:62025']
def appium_desired(udid, port):
with open('../config/kyb_caps.yaml', 'r',encoding='utf-8') as file: #这种写法可以避免忘记写file.close()导致的文件被占用而打不开的情况
data = yaml.load(file, Loader=yaml.FullLoader) #注意缩进
desired_caps = {}
desired_caps['platformName']= data['platformName']
desired_caps['deviceName']= data['deviceName']
desired_caps['platformVersion']= data['platformVersion']
desired_caps['udid']= udid #同时控制多台设备时,这行代码要加上
base_path = os.path.dirname(os.path.dirname(__file__)) #os.path.dirname()方法可以获得其参数的当前路径
app_path = os.path.join(base_path, 'apps', data['appname']) #os.path.join()方法可以将其参数以路径的形式拼接在一起
desired_caps['app']= app_path #上面2行代码用app安装包文件名的方式获取了被测app的路径,省去在配置文件中敲路径的麻烦,也不担心路径变化后需要修改
desired_caps['appPackage']= data['appPackage']
desired_caps['appActivity']= data['appActivity']
desired_caps['noReset']= data['noReset']
desired_caps['unicodeKeyboard']= data['unicodeKeyboard']
desired_caps['resetKeyboard']= data['resetKeyboard']
driver=webdriver.Remote('http://'+str(data['ip'])+':'+str(port)+'/wd/hub',desired_caps) #appium服务器需要通过这个“WebDriver”来控制安卓设备
driver.implicitly_wait(2)
return driver #把driver 返回出来,方便后续其他脚本调用
#构建进程组
desired_process = []
#创建d进程(即在设备上启动kyb APP),并加载到进程组中
for i in range(len(devices_list)):
port = 4723+i*2
d = multiprocessing.Process(target=appium_desired,args=(devices_list[i],port)) #用for循环来创建2个子进程
desired_process.append(d)
if __name__ == "__main__":
# appium_desired(devices_list[0],4723)
# appium_desired(devices_list[1],4725)
for d in desired_process:
d.start() #开始所有的子进程
for d in desired_process:
d.join() #join方法作用是主进程等待调用join方法的子进程终止后再往下执行
在思考如何使用多进程同时测试不同设备上的同一款APP时,比如测试登录功能,摸索了很久,但始终没有得到如愿的结果。最开始的思路是,利用多进程同时创建2个运行在不同接口的webdriver,然后再“指挥”这2个driver完成各自的任务即可。但实际上,多进程创建好webdriver后,它并没有返回出那个driver,这直接导致后面的任务报错。于是又尝试了可以让多进程有返回值的方法(进程池Pool),不过依然不是那么正确(返回的driver要拿一个列表去接收,可是这样在后面的任务执行时,依次调用列表里的driver又变成了单进程执行)。现在想来,可能这样的思路不对。
按照网上多进程的教程,应该将要执行的任务封装到生成webdriver的方法里面,再在后面创建多进程执行这个方法时,就会把任务分别同时执行了。
理论上这个思路是可以实现所想的功能的,因为后面所有任务都需要driver作为参数(webdriver相当于appium服务器和APP之间的沟通桥梁),所以就在生成driver的地方创建多进程,把要执行的任务封装进来,这样就在生成driver的时候“顺便”给执行了,而且就是多进程同时执行的。
只不过这样的思路也似乎有不妥的地方,假如要执行更多更复杂的任务,难道也全部封装到这里吗?而且如何实现自动化测试呢?是否可以把创建多进程的步骤移到任务脚本那边呢?这需要日后再探索一番了。