利用adb命令,启动Activity,同时输入账号密码,登录后捕捉指定元素,获得热启动时间(比较简单)
# encoding:'utf-8'
#安卓自动化和adb命令连接手机设备
import time
import subprocess
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from selenium.common import NoSuchElementException
import re
import pandas as pd
from logger.log_print_out import TestLogger
class Bar_Perf:
#执行adb命令
def run_adb_com(self,command):
# os.chdir(directory)
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
output, error = process.communicate()
return output.decode('utf-8'), error.decode('utf-8')
# #输出日志
# def run_adb_log(self):
# try:
# adb_process = subprocess.Popen("logcat", stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
# while adb_process.poll() is None: # 循环读取输出
# output = adb_process.stdout.readline()
# if output:
# print(output.decode('utf-8').strip()) # 打印输出日志
# except subprocess.CalledProcessError as e:
# print(f"执行adb命令出错:{e}")
# adb命令获取log--启动软件后
def get_log(self,log_file):
cmd = ['adb', 'logcat', '-d']
with open(log_file, 'w',encoding='UTF-8') as file:
subprocess.call(cmd, stdout=file)
TestLogger.log(debug="开始收集日志:adb logcat > {}".format(log_file))
# adb命令首先杀掉所有服务,然后adb连接ip
def connect_app(self):
kill_server = self.run_adb_com("adb kill-server")
print(kill_server)
TestLogger.log(debug="adb kill -server")
ip = self.run_adb_com("adb connect 127.0.0.1:62001")
print(ip)
TestLogger.log(debug="adb connect 127.0.0.1:62001")
device = self.run_adb_com("adb devices")
print(device)
TestLogger.log(debug="adb devices")
#模拟器:连接到手机界面
def get_screen(self):
driver_caps= {
'platformName': 'Android',
'deviceName': 'Android Emulator', #连接的三星安卓13设备
'automationName': 'Appium',
'noReset': True,
'unicodeKeyboard': True,
'resetKeyboard': True
}
self.driver = webdriver.Remote('http://127.0.0.1:4723/wd/hub', driver_caps)
TestLogger.log(debug="webdriver.Remote-远程连接手机屏幕")
#adb关闭屏幕 adb shell input keyevent 26
def close_screen(self):
self.run_adb_com("adb shell input keyevent 26")
TestLogger.log(debug="adb shell input keyevent 26-关闭屏幕")
#adb点击home键 adb shell input keyevent 3
def click_home(self):
self.run_adb_com("adb shell input keyevent 36")
TestLogger.log(debug="adb shell input keyevent 36-点击home键")
#adb点击返回键 adb shell input keyevent 4
def click_back(self):
self.run_adb_com("adb shell input keyevent 4")
TestLogger.log(debug="adb shell input keyevent 4-点击返回键")
#adb打开屏幕 adb shell input keyevent 224
def open_screen(self):
self.run_adb_com("adb shell input keyevent 224")
TestLogger.log(debug="db shell input keyevent 224-打开屏幕")
#adb启动apk--可以获取启动时间
def adb_open_time(self):
# adb命令启动app,到登录页面,获取时间
# ThisTime 该activity启动耗时
# 最后一个Activity启动耗时,如果关心应用有界面Activity启动耗时,参考ThisTime
# TotalTime 应用自身启动耗时=ThisTime+应用application等资源启动时间
# 所有Activity启动耗时,一般查看得到的TotalTime,即应用的启动时间,包括创建进程 + Application初始化 + Activity初始化到界面显示的过程。
# 如果只关心某个应用自身启动耗时,参考TotalTime
# WaitTime 系统启动应用耗时=TotalTime+系统资源启动时间
# AMS启动Activity的总耗时,如果关心系统启动应用耗时,参考WaitTime
out, error = self.run_adb_com("adb shell am start -W -n com.trackmeeasy.sit/com.trackmeeasy.MainActivity")
# print(out,error)
TestLogger.log(debug="启动activity耗时:adb shell am start -W -n com.trackmeeasy.sit/com.trackmeeasy.MainActivity")
self.get_log("D:/fsdownload/KTS_AutoTest/testcases/app_testing/applog/log.log")
return out,error
#appium自动化--是否登录成功--可以获取登录用时
def login_time(self):
# 冷启动:应用第一次启动
# 热启动:按back按键后再启动或非第一次启动切没有清除该应用后台或缓存数据
# 1、使用ID定位(点击搜索)
# self.driver.find_element(AppiumBy.XPATH, '//android.widget.TextView[@content-desc="全球小包"]').click()
time.sleep(6)
TestLogger.log(debug="time.sleep(6)")
try:
element = self.driver.find_element(AppiumBy.XPATH,
'//android.widget.TextView[@resource-id="com.trackmeeasy.sit:id/textView" and @text="包操作"]')
TestLogger.log(debug="find_element(XPATH,包操作)--查找元素")
text_value = element.text
if text_value == '包操作':
TestLogger.log(debug="包操作查找成功--不用输入密码,直接登录成功")
except:
#输入账号
self.driver.find_element(AppiumBy.XPATH, '//android.widget.EditText[@resource-id="username"]').send_keys(
"123")
TestLogger.log(debug="find_element(XPATH,username)--查找元素")
#输入密码
self.driver.find_element(AppiumBy.XPATH, '//android.widget.EditText[@resource-id="password"]').send_keys("123")
TestLogger.log(debug="find_element(XPATH,password)--查找元素")
#点击登录
self.driver.find_element(AppiumBy.XPATH, '//android.widget.Button[@resource-id="kc-login"]').click()
TestLogger.log(debug="find_element(XPATH,kc-login)--查找元素")
# 获取log
# self.get_log()
start_time=time.time()
TestLogger.log(debug="开始计时")
# // 若是通过找元素click来查找,因为定位要花费时间,明显比人眼查看时间花费多,所以使用循环查询源码
attempts = 0
max_attempts=5
interval=1
while attempts < max_attempts:
try:
element = self.driver.find_element(AppiumBy.XPATH,
'//android.widget.TextView[@resource-id="com.trackmeeasy.sit:id/textView" and @text="包操作"]')
TestLogger.log(debug="find_element(XPATH,操作)--查找元素")
text_value = element.text
print(text_value)
if text_value == '操作':
end_time = time.time()
TestLogger.log(debug="结束计时")
login_time = end_time - start_time
TestLogger.log(debug="登录到页面时间:{}, 秒".format(login_time))
else:
TestLogger.log(debug="登录失败,请检查")
# print("登录失败")
return element
except NoSuchElementException:
TestLogger.log(debug=f"元素未找到. Retrying in {attempts} seconds...")
time.sleep(interval)
TestLogger.log(debug="time.sleep({})".format(interval))
attempts += 1
raise NoSuchElementException(f"元素未找到 after {max_attempts} attempts")
# text_elem=self.driver.find_element(AppiumBy.XPATH, '//android.widget.TextView[@resource-id="com.trackmeeasy.sit:id/textView" and @text="操作"]')
#登录后获取性能--时间
def login_performace_time(self):
self.connect_app()
self.get_screen()
open, error = bar_perf.adb_open_time()
bar_perf.login_time()
pattern = r'TotalTime:\s(\d+)'
match = re.search(pattern, open)
if match:
total_time = match.group(1)
TestLogger.log(debug="Activty启动时间:{}".format(total_time) )
else:
TestLogger.log(debug="问题结果:未获取到TotalTime,请检查" )
#第一次下载,需要勾选允许访问
def click_allow(self):
self.adb_open_time()
time.sleep(2)
TestLogger.log(debug="time.sleep(2)")
#下面事xpath,要允许app访问您设备上的照片、媒体内容和文件吗?
#//android.widget.TextView[@resource-id="com.android.packageinstaller:id/permission_message"]
element1=self.driver.find_element(AppiumBy.ID,"com.android.packageinstaller:id/permission_message")
TestLogger.log(debug="AppiumBy.ID——要允许app访问您设备上的照片、媒体内容和文件吗?")
if element1.text:
#点击允许--//android.widget.Button[@resource-id="com.android.packageinstaller:id/permission_allow_button"]
self.driver.find_element(AppiumBy.ID, "com.android.packageinstaller:id/permission_allow_button")
TestLogger.log(debug="AppiumBy.ID——点击允许")
time.sleep(2)
TestLogger.log(debug="time.sleep(2)")
#要允许app拍摄照片和录制视频吗?
element2 = self.driver.find_element(AppiumBy.ID, "com.android.packageinstaller:id/permission_message")
TestLogger.log(debug="AppiumBy.ID——要允许app拍摄照片和录制视频吗?")
if element2.text:
# 点击允许--//android.widget.Button[@resource-id="com.android.packageinstaller:id/permission_allow_button"]
self.driver.find_element(AppiumBy.ID, "com.android.packageinstaller:id/permission_allow_button")
TestLogger.log(debug="AppiumBy.ID——点击允许")
time.sleep(2)
TestLogger.log(debug="time.sleep(2)")
# 要允许app获取此设备的位置信息吗?
element3 = self.driver.find_element(AppiumBy.ID, "com.android.packageinstaller:id/permission_message")
TestLogger.log(debug="AppiumBy.ID——要允许app获取此设备的位置信息吗?")
if element3.text:
# 点击允许--//android.widget.Button[@resource-id="com.android.packageinstaller:id/permission_allow_button"]
self.driver.find_element(AppiumBy.ID, "com.android.packageinstaller:id/permission_allow_button")
TestLogger.log(debug="AppiumBy.ID——点击允许")
time.sleep(2)
TestLogger.log(debug="time.sleep(2)")
#// android.widget.TextView[ @ resource - id = "android:id/title"]
#允许修改系统设置
allow_syste=self.driver.find_element(AppiumBy.ID, "android:id/title")
TestLogger.log(debug="AppiumBy.ID——允许修改系统设置")
if allow_syste.text:
#//android.widget.Switch[@resource-id="android:id/switch_widget"]
self.driver.find_element(AppiumBy.ID,"android:id/switch_widget")
TestLogger.log(debug="AppiumBy.ID——点击允许")
time.sleep(2)
TestLogger.log(debug="time.sleep(2)")
#adb命令,点击返回
self.run_adb_com("adb shell input keyevent BACK")
TestLogger.log(debug="adb shell input keyevent BACK——点击返回")
if __name__=="__main__":
bar_perf=Bar_Perf()
bar_perf.login_performace_time()
bar_perf.close_screen()
bar_perf.open_screen()
bar_perf.click_back()
time.sleep(2)
bar_perf.click_back()
#例子
# from appium.webdriver.common.appiumby import AppiumBy
# # 根据 resource-id 获取元素
# driver.find_element(AppiumBy.ID, 'expand_search')
# # 根据class_name 获取元素
# driver.find_element(AppiumBy.CLASS_NAME, 'android.widget.TextView')
# # 根据 content-desc 属性获取元素
# driver.find_element(AppiumBy.ACCESSIBILITY_ID, '请登录')
# # 根据 xpath 属性获取元素
# driver.find_element(AppiumBy.XPATH, '//ele1/ele2[@attr="value"]')