app自动化测试----使用Python代码启动和关闭 一个/多个设备Appium
1.说明
之前在做手机app 自动化的时候,每次在自动化测试脚本运行之前,需要手动启动appium 服务器,在开发环境中这样做没有什么问题,但是在服务器端执行自动化代码,这样就有有欠妥当。
所有,在实际的开发过程中,我们就需要python代码通过 python的方式启动 appium 服务。
2.Python执行cmd面板中命令行代码
os.system 方法可以模拟执行命令行命令。但是缺点是:它是同步的,当命令行中的命令执行完成之后,才会接着往下执行。
但是,我们使用appium需要的是,后台开启一个进程之后,可以继续执行我们的其他测试用例代码,当前方法不满足
import os os.system('ping www.baidu.com')
执行python代码,运行结果:
3.查进程号,杀掉进程的cmd命令
# Windows命令 netstat -ano | findstr 4723 # 根据进程使用的端口号,查找进程的进程号 taskkill -f -pid 22668 # 根据进程号,杀掉进程 # mac命令 lsof -i tcp:4723 kill 22668
4. Python使用subprocess 子进程的方式启动单个appium
""" appium启动/关闭处理类 """ import subprocess import os,sys import time def stop_appium(port): mac_cmd = f"lsof -i tcp:{port}" win_cmd = f"netstat -ano | findstr {port}" # 判断操作系统 os_platform = sys.platform print('操作系统:',os_platform) # #windows 系统 if os_platform == "win32": win_p = subprocess.Popen(win_cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) for line in win_p.stdout.readlines(): if line: line = line.decode('utf8') if "LISTENING" in line: win_pid = line.split("LISTENING")[1].strip() os.system(f"taskkill -f -pid {win_pid}") else: # unix系统 p = subprocess.Popen(mac_cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) for line in p.stdout.readlines(): line = line.decode('utf8') if "node" in line: stdoutline = line.split(" ") # print(stdoutline) pid = stdoutline[4] os.system(f"kill {pid}") def start_appium(port): """ 启动appium 服务 :param port: 服务的端口号 :return: """ stop_appium(port) cmd = f"appium -p {port}" logsdir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "logs") appium_logs = os.path.join(logsdir,"appium-logs") if not os.path.exists(appium_logs): os.mkdir(appium_logs) log_name = str(port) + '-' + time.strftime('%Y_%m_%d') +".log" appium_logs_dirName = os.path.join(appium_logs,log_name) subprocess.Popen(cmd, shell=True, stdout=open(appium_logs_dirName, mode='a', encoding="utf8"), stderr=subprocess.PIPE) # # 单个方法调试代码 if __name__ == '__main__': start_appium(4723) stop_appium(4723)
5.Python使用multiprocessing 多进程的方式并行启动多个设备appium
""" 并行 运行两台设备 """ import os import subprocess import sys from appium import webdriver import multiprocessing # 获取所有的连接设备 def get_connect_devices(): devices = [] port = 4723 proc = subprocess.Popen('adb devices',stdout=subprocess.PIPE,shell=True) for line in proc.stdout.readlines(): # 将字节类型转换为字符串 line_str = line.decode(encoding='utf8') if '\tdevice' in line_str: # 字符串分割 提取 deviceid值 device_id = line_str.strip().split('\tdevice')[0] devices.append((device_id,port)) port += 2 print('devices连接设备----》', devices) return devices # 使用命令行的方式启动appium def start_appium(port): print('port----要启动的appium端口》', port) start_cmd=f'appium -p {port}' with open(f'./{port}.log',mode='w',encoding='utf8') as file: subprocess.Popen(start_cmd,shell=True,stdout=file) # 使用命令行的方式关闭appium def stop_appium(port): mac_cmd = f"lsof -i tcp:{port}" win_cmd = f"netstat -ano | findstr {port}" print('port----要关闭的进程端口》', port) # 判断操作系统 os_platform = sys.platform print('操作系统:',os_platform) # #windows 系统 if os_platform == "win32": win_p = subprocess.Popen(win_cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) for line in win_p.stdout.readlines(): if line: line = line.decode('utf8') if "LISTENING" in line: win_pid = line.split("LISTENING")[1].strip() os.system(f"taskkill -f -pid {win_pid}") else: # unix系统 p = subprocess.Popen(mac_cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) for line in p.stdout.readlines(): line = line.decode('utf8') if "node" in line: stdoutline = line.split(" ") # print(stdoutline) pid = stdoutline[4] os.system(f"kill {pid}") def start_driver(device_id,port): print("在所有的测试用例执行之前创建driver") # 先开启appium 再连接, 启动之前 先结束之前启动的apppium stop_appium(port) start_appium(port) chromedriver = os.path.join(os.path.dirname(os.path.abspath(__file__)),'driver/chrome/75.0.3770.140/chromedriver.exe') desired_caps = { 'platformName': 'Android', # 测试Android系统 'udid': device_id, # adb devices 命令查看 设置为自己的设备 'automationName': 'UiAutomator2', # 自动化引擎 'noReset': True, # 不要重置app的状态 'fullReset': False, # 不要清理app的缓存数据 # 'chromedriverExecutable': chromedriver, # chromedriver 对应的绝对路径 'appPackage': "org.cnodejs.android.md", # 应用的包名 'appActivity': ".ui.activity.MainActivity" # 应用的活动页名称 } driver = webdriver.Remote(f'http://127.0.0.1:{port}/wd/hub', desired_capabilities=desired_caps) driver.implicitly_wait(5) # 全局的隐式等待时间 if __name__ == '__main__': devices = get_connect_devices() # [('127.0.0.1:62001', 4723),('127.0.0.1:62025',4725)] processes = [] for device in devices: p = multiprocessing.Process(target=start_driver,args=(device[0],device[1],)) p.start() processes.append(p) for proc in processes: proc.join()