我搭建了一个小环境尝试使用 appium 来自动运行我们的 APP,但是在环境搭建好之后使用 Appium 自带的 Contact Manager 这个小 APP 试运行了一次,全程通过,稍后切换成我们公司自己的 APP 来运行,然而 appium 启动时报错如下:
info: Welcome to Appium v1.3.4 (REV c8c79a85fbd6870cd6fc3d66d038a115ebe22efe)
info: Appium REST http interface listener started on 0.0.0.0:4723
info: Console LogLevel: debug
info: --> POST /wd/hub/session {"capabilities":{"desiredCapabilities":{"app":"D:
\\AppiumTest/apps/wcc9_0_0_17_20170109.apk","appPackage":"com.wochacha","appActi
vity":".StartupActivity","platformVersion":"4.4","browserName":"","platformName"
:"Android","udid":"127.0.0.1:6555","deviceName":"127.0.0.1:6555"},"requiredCapab
ilities":{}},"desiredCapabilities":{"app":"D:\\AppiumTest/apps/wcc9_0_0_17_20170
109.apk","appPackage":"com.wochacha","appActivity":".StartupActivity","platformV
ersion":"4.4","browserName":"","platformName":"Android","udid":"127.0.0.1:6555",
"deviceName":"127.0.0.1:6555"},"requiredCapabilities":{}}
info: Client User-Agent string: Apache-HttpClient/4.3.3 (java 1.5)
info: [debug] Using local app from desired caps: D:\AppiumTest\apps\wcc9_0_0_17_
20170109.apk
info: [debug] Creating new appium session 94e12953-dd11-41fa-b0b7-0010aa200644
info: Starting android appium
info: [debug] Getting Java version
info: Java version is: 1.8.0_05
info: [debug] Using fast reset? true
info: [debug] Preparing device for session
info: [debug] Checking whether app is actually present
info: [debug] Checking whether adb is present
info: [debug] Using adb from E:\Android-64-sdk\sdk\platform-tools\adb.exe
info: Retrieving device
info: [debug] Trying to find a connected android device
info: [debug] Getting connected devices...
info: [debug] executing cmd: E:\Android-64-sdk\sdk\platform-tools\adb.exe device
s
info: [debug] 1 device(s) connected
info: Found device 127.0.0.1:6555
info: [debug] Setting device id to 127.0.0.1:6555
info: [debug] Waiting for device to be ready and to respond to shell commands (t
imeout = 5)
info: [debug] executing cmd: E:\Android-64-sdk\sdk\platform-tools\adb.exe -s 127
.0.0.1:6555 wait-for-device
info: [debug] executing cmd: E:\Android-64-sdk\sdk\platform-tools\adb.exe -s 127
.0.0.1:6555 shell "echo 'ready'"
info: [debug] Starting logcat capture
info: [debug] Getting device API level
info: [debug] executing cmd: E:\Android-64-sdk\sdk\platform-tools\adb.exe -s 127
.0.0.1:6555 shell "getprop ro.build.version.sdk"
info: [debug] Device is at API Level 19
info: Device API level is: 19
info: [debug] executing cmd: E:\Android-64-sdk\sdk\platform-tools\adb.exe -s 127
.0.0.1:6555 shell "getprop persist.sys.language"
info: [debug] Current device persist.sys.language: zh_CN
info: [debug] java -jar "D:\nodejs\node_modules\appium\node_modules\appium-adb\j
ars\appium_apk_tools.jar" "stringsFromApk" "D:\AppiumTest\apps\wcc9_0_0_17_20170
109.apk" "C:\Users\ADMINI~1\AppData\Local\Temp\com.wochacha" zh_CN
info: [debug] No strings.xml for language 'zh_CN', getting default strings.xml
info: [debug] java -jar "D:\nodejs\node_modules\appium\node_modules\appium-adb\j
ars\appium_apk_tools.jar" "stringsFromApk" "D:\AppiumTest\apps\wcc9_0_0_17_20170
109.apk" "C:\Users\ADMINI~1\AppData\Local\Temp\com.wochacha"
info: [debug] executing cmd: E:\Android-64-sdk\sdk\platform-tools\adb.exe -s 127
.0.0.1:6555 push "C:\\Users\\ADMINI~1\\AppData\\Local\\Temp\\com.wochacha\\strin
gs.json" /data/local/tmp
info: [debug] Checking whether aapt is present
info: [debug] Using aapt from E:\Android-64-sdk\sdk\build-tools\android-4.4\aapt
.exe
info: [debug] Retrieving process from manifest.
info: [debug] executing cmd: E:\Android-64-sdk\sdk\build-tools\android-4.4\aapt.
exe dump xmltree D:\AppiumTest\apps\wcc9_0_0_17_20170109.apk AndroidManifest.xml
info: [debug] Set app process to: com.wochacha
info: [debug] Not uninstalling app since server not started with --full-reset
info: [debug] Checking app cert for D:\AppiumTest\apps\wcc9_0_0_17_20170109.apk.
info: [debug] executing cmd: java -jar D:\nodejs\node_modules\appium\node_module
s\appium-adb\jars\verify.jar D:\AppiumTest\apps\wcc9_0_0_17_20170109.apk
info: [debug] App not signed with debug cert.
info: [debug] Resigning apk.
info: [debug] executing cmd: java -jar D:\nodejs\node_modules\appium\node_module
s\appium-adb\jars\sign.jar D:\AppiumTest\apps\wcc9_0_0_17_20170109.apk --overrid
e
info: [debug] Stopping logcat capture
info: [debug] Logcat terminated with code null, signal SIGTERM
info: [debug] Sent shutdown command, waiting for UiAutomator to stop...
warn: UiAutomator did not shut down fast enough, calling it gone
info: [debug] Cleaning up android objects
info: [debug] Cleaning up appium session
error: Failed to start an Appium session, err was: Error: Command failed: Except
ion in thread "main" java.lang.RuntimeException: Unable to rename input apk. D:\
AppiumTest\apps\wcc9_0_0_17_20170109.apk
at s.Sign.sign(Sign.java:421)
at s.Sign.main(Sign.java:532)
info: [debug] Error: Command failed: Exception in thread "main" java.lang.Runtim
eException: Unable to rename input apk. D:\AppiumTest\apps\wcc9_0_0_17_20170109.
apk
at s.Sign.sign(Sign.java:421)
at s.Sign.main(Sign.java:532)
at ChildProcess.exithandler (child_process.js:658:15)
at ChildProcess.emit (events.js:98:17)
at maybeClose (child_process.js:766:16)
at Process.ChildProcess._handle.onexit (child_process.js:833:5)
info: [debug] Responding to client with error: {"status":33,"value":{"message":"
A new session could not be created. (Original error: Command failed: Exception i
n thread \"main\" java.lang.RuntimeException: Unable to rename input apk. D:\\Ap
piumTest\\apps\\wcc9_0_0_17_20170109.apk\r\n\tat s.Sign.sign(Sign.java:421)\r\n\
tat s.Sign.main(Sign.java:532)\r\n)","killed":false,"code":1,"signal":null,"orig
Value":"Command failed: Exception in thread \"main\" java.lang.RuntimeException:
Unable to rename input apk. D:\\AppiumTest\\apps\\wcc9_0_0_17_20170109.apk\r\n\
tat s.Sign.sign(Sign.java:421)\r\n\tat s.Sign.main(Sign.java:532)\r\n"},"session
Id":null}
info: <-- POST /wd/hub/session 500 11260.402 ms - 602
appium 本身的脚本如下:
public AppiumTest(String app, String reset) throws IOException {
this.appDir = System.getProperty("user.dir") + "/apps/" + app + ".apk";
this.packageName = (GetApkInfo.getApkInfoByFilePath(appDir).toString().split(",")[0]).split("=")[1];
this.appName = app;
this.resetable = reset;
this.setDevices();
this.setDrivers();
this.setDriversTimeouts();
}
/**
* 将所有已连接设
*
* 备的id放到数组deviceId中
* @throws IOException
*/
public void setDevices() throws IOException {
deviceId = new ArrayList<String>();
int unknownIdDevicesNum = 0;
int offlineDevicesNum = 0;
int unauthorizedDevicesNum = 0;
BufferedReader br = ExecCmd.execCmd("adb devices");
String line = null;
while ((line = br.readLine()) != null) {
if (line.matches(".*offline$")) {
offlineDevicesNum++;
} else if (line.matches(".*unauthorized$")) {
unauthorizedDevicesNum++;
} else if (line.matches(".*0123456789ABCDEF.*")) {
unknownIdDevicesNum++;
} else if (line.matches(".*device$")) {
String[] s = line.split("\t");
deviceId.add(s[0]);
}
}
if (unknownIdDevicesNum > 1) {
assertTrue("2台或2台以上设备id同为0123456789ABCDEF,请保证最多只有一台", false);
}
if (offlineDevicesNum > 0) {
assertTrue("1台或1台以上设备为离线状态,请检查", false);
}
if (unauthorizedDevicesNum > 0) {
assertTrue("1台或1台以上设备为未授权状态,请检查", false);
}
if (deviceId.isEmpty()) {
assertTrue("没有检测到设备,请检测设备连接是否正常", false);
} else {
deviceNum = deviceId.size();
}
}
/**
* 为所有连接上的设备创建各自的appiumdriver,并添加到appiumDrivers数组
* @throws IOException
*/
public void setDrivers() throws IOException {
appiumDrivers = new AndroidDriver[deviceNum];
for (int i = 0; i < deviceNum; i++) {
appiumDrivers[i] = this.getDriver(i);
}
}
public AndroidDriver getDriver(int index) throws MalformedURLException {
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME, "");
capabilities.setCapability("platformName", "Android");
capabilities.setCapability("deviceName", deviceId.get(index));
capabilities.setCapability("udid", deviceId.get(index)); // 设置device id
capabilities.setCapability("platformVersion", "4.4");
capabilities.setCapability("app", this.appDir);
ExecCmd.execCmd("cmd.exe /k start appium --port " + (4723 + 2 * index)
+" " + this.resetable + " --command-timeout " + COMMAND_TIMEOUT); // 启动appium server
// 等待10秒钟让appium server起来
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return new AndroidDriver(new URL("http://127.0.0.1:"
+ (4723 + 2 * index) + "/wd/hub"), capabilities);
}
诚然遇见问题首先自己解决,发现跟 resetable 参数有关系,因为之后排查发现我无论是否穿 no-reset 值过去都会重新安装。之后长达一个星期的时间我在 apk 包的权限(类似混淆、签名、加密等等情况做了排除)
本身脚本的问题(尝试不在启动安装 apk 包)我将
ExecCmd.execCmd("cmd.exe /k start appium --port " + (4723 + 2 * index)
+" " + this.resetable + " --command-timeout " + COMMAND_TIMEOUT); // 启动appium server
修改成如下:
capabilities.setCapability("appPackage", "com.wochacha");
capabilities.setCapability("appActivity", ".StartupActivity");
ExecCmd.execCmd("cmd.exe /k start appium");
来尝试直接运行脚本,第一次可以运行,第二次就报同样的错误,求各位大神帮忙指点一下迷津。