环境:Appium v2.0.1 + python
以Python的unittest框架为例,实现测试用例执行过程的屏幕录制并保存至PC
一、iOS测试
在测试用例类的setUp中,调start_recording_screen接口开始录屏
import unittest
class iOSTestCase(unittest.TestCase):
def setUp(self):
... (此处忽略其他初始化过程,以及appium webdriver的初始化过程)
self.driver.implicitly_wait(30)
self.driver.start_recording_screen() # 调appium相关接口开始录屏
在tearDown中结束录屏并保存到PC(注意,由于需要将录屏数据保存成视频文件,需要进行数据读写,视频过大时可能会导致失败,非必要时不需要设置过高的视频质量,保持默认的就可以了)
def tearDown(self):
...
video_data =self.driver.stop_recording_screen() # 调appium相关接口结束录屏
base64_to_mp4(video_data, 'filename.mp4') # 保存为视频文件,存储到PC,base64_to_mp4函数见后面部分
self.driver.quit()
# 单独写一个base64数据转(mp4)视频文件的函数
import base64
def base64_to_mp4(base64_string, output_file):
binary_data = base64.b64decode(base64_string)
with open(output_file, 'wb')as file:
file.write(binary_data)
至此,每一个测试用例执行过程均会对应一个录屏文件,录屏文件名称最好是以用例名称以及测试执行时间来命名,方便查找。例外情况:如果webdriver没有成功启动,则无法录屏,不会输出录屏文件
二、安卓测试
安卓端可以尝试使用与iOS端相同的方法,但如果报错的话,大概率是国内厂商阉割了部分特性导致的失败,可以尝试以下替换方案
import unittest
import subprocess
class AndroidTestCase(unittest.TestCase):
def setUp(self):
...
self.driver.implicitly_wait(30)
try:
self.driver.execute_script('mobile:startMediaProjectionRecording')
except Exception as e:
# 使用startMediaProjectionRecording需要先在手机授权,通过adb执行命令授权,此处在代码中处理,也可以手动在终端执行命令授权
# 若之前从未授权,则调startMediaProjectionRecording会报异常,捕获异常后授权再调startMediaProjectionRecording
print('录屏报错,正在尝试授权后重试')
# 分别执行命令(device_id可从adb devices 命令中获取):
# adb -s [device_id] shell pm grant io.appium.settings android.permission.RECORD_AUDIO
# adb -s [device_id] shell appops set io.appium.settings PROJECT_MEDIA allow
cmd1 =f'adb -s {self.device_id} shell pm grant io.appium.settings android.permission.RECORD_AUDIO'
subprocess.Popen(cmd1, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
shell=True)
cmd2 =f'adb -s {self.device_id} shell appops set io.appium.settings PROJECT_MEDIA allow'
subprocess.Popen(cmd2, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
shell=True)
sleep(0.3)
# 授权后重新执行
self.driver.execute_script('mobile:startMediaProjectionRecording')
def tearDown(self):
...
video_data =self.driver.execute_script('mobile: stopMediaProjectionRecording')
base64_to_mp4(video_data, 'filename.mp4')
self.driver.quit()
完~