Python Python3 结合 adb 测试应用启动时间

xiaoxiao · May 25, 2019 · Last by cheunghr replied at January 31, 2023 · 2084 hits
!/usr/bin/python
# -*- coding: utf-8 -*-
# @author: xiaoxiao
# @date  : 2018/12/13

import subprocess
import time

# 执行shell
def shell(cmd):
    p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True)
    (stdout_output, err_output) = p.communicate()
    if err_output != None and len(err_output) != 0:
        print("Shell err_output: " + str(err_output))
    # print("stdout_output: " + str(stdout_output))
    return stdout_output

# 启动app应用
def app_start(package_name, launch_activity, device_id = ''):
    if device_id != '':
        cmd_start = "adb -s %s shell am start -n %s" % (device_id, package_name + "/" + launch_activity)
    else:
        cmd_start = "adb shell am start -n %s" % (package_name + "/" + launch_activity)
    shell(cmd_start)
    time.sleep(3)
    # print("App start success: " + str(cmd_start))

# 退出app应用
def app_stop(package_name, device_id = ''):
    if device_id != '':
        cmd_stop = "adb -s %s shell am force-stop %s" % (device_id, package_name)
    else:
        cmd_stop = "adb shell am force-stop %s" % (package_name)
    shell(cmd_stop)
    time.sleep(1)
    # print("App stop finishes: " + str(cmd_stop))

# 判断app应用是否在前台
def is_activity_started(package_name, device_id = ''):
    if device_id != '':
        cmd_current_activity = "adb -s %s shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'" % device_id
    else:
        cmd_current_activity = "adb shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'"
    cmd_result = str(shell(cmd_current_activity))
    # 如果当前应用处于前台或resume后台状态,返回True
    if package_name in cmd_result:
        return True
    else:
        return False

# 设置app应用后台运行
def set_activity_backup(package_name, launch_activity, device_id = ''):
    if device_id != '':
        if not is_activity_started(package_name, device_id):
            app_start(package_name, launch_activity, device_id)
        cmd = 'adb -s %s shell input keyevent key 3' % device_id
    else:
        if not is_activity_started(package_name):
            app_start(package_name, launch_activity)
        cmd = 'adb shell input keyevent key 3'
    shell(cmd)

# 获取冷启动时间
def get_cold_boot_time(package_name, launch_activity, device_id = ''):
    if is_activity_started(package_name, device_id):
        app_stop(package_name, device_id)
    if device_id != '':
        cmd_start = "adb -s %s shell am start -W %s | grep 'WaitTime'" % (device_id, package_name + "/" + launch_activity)
    else:
        cmd_start = "adb shell am start -W %s | grep 'WaitTime'" % (package_name + "/" + launch_activity)
    cold_boot_time = shell(cmd_start)[10:].strip()
    return int(cold_boot_time)

# 获取热启动时间
def get_hot_boot_time(package_name, launch_activity, device_id = ''):
    set_activity_backup(package_name, launch_activity, device_id)
    if device_id != '':
        cmd_start = "adb -s %s shell am start -W %s | grep 'WaitTime'" % (device_id, package_name + "/" + launch_activity)
    else:
        cmd_start = "adb shell am start -W %s | grep 'WaitTime'" % (package_name + "/" + launch_activity)
    cold_boot_time = shell(cmd_start)[10:].strip()
    return int(cold_boot_time)

# 执行测试,times为次数,结果取平均值
def run_test(times):
    cold_time = []
    hot_time = []
    for i in range(times):
        cold_time.append(get_cold_boot_time('com.tencent.mobileqq', '.activity.SplashActivity'))
        hot_time.append(get_hot_boot_time('com.tencent.mobileqq', '.activity.SplashActivity', 'abbed25'))
    res_cold_time = 0
    res_hot_time = 0
    print("cold_time = " + str(cold_time))
    print("hot_time = " + str(hot_time))
    for i in cold_time:
        res_cold_time = res_cold_time + i
    print('average cold_time: ' + str(res_cold_time / times) + ' ms')
    for i in hot_time:
        res_hot_time = res_hot_time + i
    print('average hot_time: ' + str(res_hot_time/times) + ' ms')

# 执行10次
run_test(10)

测试结果:

cold_time = [395, 341, 312, 312, 324, 312, 321, 333, 332, 323]
hot_time = [46, 57, 64, 60, 40, 46, 25, 88, 53, 56]
average cold_time: 330 ms
average hot_time: 53 ms
共收到 10 条回复 时间 点赞
匿名 在 [Topic was deleted] 中提及了此贴 26 May 00:03

感谢感谢!刚好需要判断 APP 在前端还是后端

adb 时间差距比较大

很棒

windows 下貌似不能运行啊,sed 不是内部命令,我自己添加 sed.exe 后,cmd 内可以使用 sed,在代码运行依然不能成功

grep 也不是,考虑兼容性的话字符串处理都应该在 python 里做,而不是 shell

grep 这个可以把 shell 后的语句全部双引号就行,但是 sed 是真的不行

xiaoxiao #8 · June 26, 2019 Author
了不起的QA 回复

window 的我没试过呢,要不把得到的 adb 结果放在 Python 中处理咯?

楼主好,这个方法能封装直接调用吗

kuddyliu 回复

可以的,自己改成想要的样子就行了

调整了一下楼主的方案,使之能够在 windows10 下运行

import subprocess
import time

# 执行shell
def shell(cmd):
    p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    dt = p.stdout.read()
    return dt

# 启动app应用
def app_start(package_name, launch_activity, device_id = ''):
    if device_id != '':
        cmd_start = "adb -s %s shell am start -n %s" % (device_id, package_name + "/" + launch_activity)
    else:
        cmd_start = "adb shell am start -n %s" % (package_name + "/" + launch_activity)
    shell(cmd_start)
    time.sleep(3)
    # print("App start success: " + str(cmd_start))

# 退出app应用
def app_stop(package_name, device_id = ''):
    if device_id != '':
        cmd_stop = "adb -s %s shell am force-stop %s" % (device_id, package_name)
    else:
        cmd_stop = "adb shell am force-stop %s" % (package_name)
    shell(cmd_stop)
    time.sleep(1)
    # print("App stop finishes: " + str(cmd_stop))

# 判断app应用是否在前台
def is_activity_started(package_name, device_id = ''):
    if device_id != '':
        cmd_current_activity = "adb -s %s shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'" % device_id
    else:
        cmd_current_activity = "adb shell dumpsys activity activities | sed -En -e '/Running activities/,/Run #0/p'"
    cmd_result = str(shell(cmd_current_activity))
    # 如果当前应用处于前台或resume后台状态,返回True
    if package_name in cmd_result:
        return True
    else:
        return False

# 设置app应用后台运行
def set_activity_backup(package_name, launch_activity, device_id = ''):
    if device_id != '':
        if not is_activity_started(package_name, device_id):
            app_start(package_name, launch_activity, device_id)
        cmd = 'adb -s %s shell input keyevent key 3' % device_id
    else:
        if not is_activity_started(package_name):
            app_start(package_name, launch_activity)
        cmd = 'adb shell input keyevent key 3'
    shell(cmd)

# 获取冷启动时间
def get_cold_boot_time(package_name, launch_activity, device_id = ''):
    if is_activity_started(package_name, device_id):
        app_stop(package_name, device_id)
    if device_id != '':
        cmd_start = "adb -s %s shell am start -W %s | grep 'WaitTime'" % (device_id, package_name + "/" + launch_activity)
    else:
        cmd_start = "adb shell am start -W %s | grep 'WaitTime'" % (package_name + "/" + launch_activity)
    cold_boot_time = shell(cmd_start)[10:].strip()
    return int(cold_boot_time)

# 获取热启动时间
def get_hot_boot_time(package_name, launch_activity, device_id = ''):
    set_activity_backup(package_name, launch_activity, device_id)
    if device_id != '':
        cmd_start = "adb -s %s shell am start -W %s | grep 'WaitTime'" % (device_id, package_name + "/" + launch_activity)
    else:
        cmd_start = "adb shell am start -W %s | grep 'WaitTime'" % (package_name + "/" + launch_activity)
    cold_boot_time = shell(cmd_start)[10:].strip()
    return int(cold_boot_time)

# 执行测试,times为次数,结果取平均值
def run_test(times):
    cold_time = []
    hot_time = []
    for i in range(times):
        cold_time.append(get_cold_boot_time('com.tencent.mobileqq', '.activity.SplashActivity'))
        hot_time.append(get_hot_boot_time('com.tencent.mobileqq', '.activity.SplashActivity', 'abbed25'))
    res_cold_time = 0
    res_hot_time = 0
    print("cold_time = " + str(cold_time))
    print("hot_time = " + str(hot_time))
    for i in cold_time:
        res_cold_time = res_cold_time + i
    print('average cold_time: ' + str(res_cold_time / times) + ' ms')
    for i in hot_time:
        res_hot_time = res_hot_time + i
    print('average hot_time: ' + str(res_hot_time/times) + ' ms')

# 执行10次
#print(shell('adb devices'))
print(get_cold_boot_time('com.itic.maas.app', '.module.home.activity.WelcomeActivity'))
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up