在AWS DeviceFarm用WebdriverIO+Appium执行E2E测试遇badging文件错误
AWS DeviceFarm 中 WebdriverIO 启动 Appium 失败排查方案
问题详情
在AWS DeviceFarm运行E2E测试时,WebdriverIO发起会话请求触发Appium报错:
2025-01-15T14:15:06.904Z WARN webdriver: WebDriverError: An unknown server-side error occurred while processing the command. Original error: Cannot read the manifest from '/tmp/devicefarm-workspace/execution-afszvhzs/uploads-c1qbmila/app-g56kvzrf.apk'. Update build tools to use a newer aapt2 version. Original error: W/ziparchive(19414): Unable to open 'badging': No such file or directory [0-0] badging: error: No such file or directory. [0-0] when running "http://localhost:4723/wd/hub/session" with method "POST" and args "{\"capabilities\":{\"alwaysMatch\":{\"platformName\":\"android\",\"appium:webviewConnectTimeout\":90000,\"appium:deviceName\":\"Testing Device\",\"appium:automationName\":\"UiAutomator2\",\"appium:appPackage\":\"com.my-app.app\",\"appium:appWaitActivity\":\"MainActivity\",\"appium:appWaitDuration\":20000,\"appium:newCommandTimeout\":360,\"appium:sessionOverride\":false,\"appium:autoGrantPermissions\":true,\"appium:fullReset\":false,\"appium:autoWebview\":false},\"firstMatch\":[{}]}}"
此前代码运行正常,本地环境无问题,但AWS端突然出现该错误,本地及Bitbucket流水线构建的APK在DeviceFarm上均触发相同故障,暂未找到公开解决方案。
相关配置文件
DeviceFarm 测试规范 YAML
version: 0.1 android_test_host: amazon_linux_2 phases: install: commands: - devicefarm-cli use node 20 - node --version - devicefarm-cli use appium 2 - npm i -g appium@2.15.0 - appium driver uninstall uiautomator2 - appium driver install uiautomator2@3.9.2 - appium -v - export APPIUM_BASE_PATH=/wd/hub # Install the NodeJS dependencies. - cd $DEVICEFARM_TEST_PACKAGE_PATH - npm i pre_test: commands: - |- appium --base-path=$APPIUM_BASE_PATH --log $DEVICEFARM_LOG_DIR --log-timestamp \ --log-no-colors --relaxed-security --default-capabilities \ "{\"appium:deviceName\": \"$DEVICEFARM_DEVICE_NAME\", \ \"platformName\": \"$DEVICEFARM_DEVICE_PLATFORM_NAME\", \ \"appium:app\": \"$DEVICEFARM_APP_PATH\", \ \"appium:udid\":\"$DEVICEFARM_DEVICE_UDID\", \ \"appium:platformVersion\": \"$DEVICEFARM_DEVICE_OS_VERSION\", \ \"appium:chromedriverExecutableDir\": \"$DEVICEFARM_CHROMEDRIVER_EXECUTABLE_DIR\", \ \"appium:automationName\": \"UiAutomator2\", \ \"appium:autoGrantPermissions\": true }" \ >> $DEVICEFARM_LOG_DIR/appiumlog.txt 2>&1 & # This code will wait until the Appium server starts. - |- appium_initialization_time=0; until curl --silent --fail "http://0.0.0.0:4723${APPIUM_BASE_PATH}/status"; do if [[ $appium_initialization_time -gt 30 ]]; then echo "Appium did not start within 30 seconds. Exiting..."; exit 1; fi; appium_initialization_time=$((appium_initialization_time + 1)); echo "Waiting for Appium to start on port 4723..."; sleep 1; done; grep -i "Appium REST http interface listener started on 0.0.0.0:4723" $DEVICEFARM_LOG_DIR/appiumlog.txt >> /dev/null 2>&1; # The test phase contains commands for running your tests. test: commands: - cd $DEVICEFARM_TEST_PACKAGE_PATH - echo "Starting the Appium NodeJS test" - npm run test post_test: commands: - cp $DEVICEFARM_TEST_PACKAGE_PATH/test-report/* $DEVICEFARM_LOG_DIR/ - ls -l $DEVICEFARM_LOG_DIR artifacts: - $DEVICEFARM_LOG_DIR
WebdriverIO 共享配置
import { type Options } from '@wdio/types'; import * as helper from "../helpers/basic-helper"; import {constants} from "../constants/constants"; import axios from "axios"; import moment = require("moment"); import {Auth0Api} from "../apis/auth0Api"; export const config: Options.Testrunner = { runner: 'local', port: 4723, path: '/wd/hub/', specs: [ '../specs/auth.e2e.ts', '../specs/tracker.e2e.ts', // '../specs/remove.e2e.ts', ], exclude: [ // 'path/to/excluded/files' ], maxInstances: 1, logLevel: 'info', bail: 1, baseUrl: 'http://localhost:8100', waitforTimeout: 20000, connectionRetryTimeout: 120000, connectionRetryCount: 3, services: [], framework: 'jasmine', reporters: [ 'spec', ['junit', { outputDir: './test-report/', outputFileFormat: function(options) { // optional return `test-output.xml` } }], ], suites: { authentication: ['../specs/auth.e2e.ts'], tracker: ['../specs/tracker.e2e.ts'], }, jasmineOpts: { defaultTimeoutInterval: 60000, stopOnSpecFailure: true, stopSpecOnExpectationFailure: true, expectationResultHandler: function(passed: any, assertion: any) { // do something }, }, afterTest: async function(test, context, { error, result, duration, passed, retries }) { if(!passed) { const fileName = `./test-report/${test.fullName}-${moment().unix()}-screenshot.png`; const screenshotName = await browser.saveScreenshot(fileName); } }, };
排查修复步骤
升级DeviceFarm环境的AAPT2版本
错误提示明确要求更新AAPT2,在DeviceFarm的install阶段手动安装高版本Android Build Tools:# 添加到install阶段commands中 - wget https://dl.google.com/android/repository/build-tools-34.0.0-linux.zip - unzip build-tools-34.0.0-linux.zip -d $ANDROID_HOME/build-tools - export PATH=$ANDROID_HOME/build-tools/34.0.0:$PATH调整UIAutomator2驱动版本
当前使用的uiautomator2@3.9.2可能与DeviceFarm环境存在兼容性问题,降级至3.8.0版本测试:# 替换install阶段的驱动安装命令 - appium driver install uiautomator2@3.8.0移除重复的App路径配置
DeviceFarm已通过默认capabilities传入appium:app,确保WDIO配置中未重复设置该参数,避免冲突。校验APK完整性
在pre_test阶段添加APK校验命令,确认APK未损坏:# 添加到pre_test阶段commands中 - aapt dump badging $DEVICEFARM_APP_PATH若该命令报错,说明APK存在问题,需重新构建并上传。
升级Appium至最新稳定版
当前使用的Appium 2.15.0可能存在已知兼容性问题,尝试升级:# 替换install阶段的Appium安装命令 - npm i -g appium@latest
内容的提问来源于stack exchange,提问作者Pablo
相关产品推荐
相关产品推荐

