微信小程序
微信小程序其实也是正常的webview,但需要在微信里打开X5调试页面进行设置,脚本添加androidProcess参数才可以执行自动化测试。
本章示例为微信Android版本进行讲解(Windows与Mac环境下操作基本一致,此次示例为在Windows环境)。
1、编写脚本
1、首先获取真机设备标识,命令行输入命令 adb devices
2、真机设备里安装微信应用程序,输入安装命令 adb install -r 进行安装,或者使用手机助手进行安装。本章示例微信版本6.6.5
3、打开X5调试页面
打开微信,在任何聊天窗口内输入debugx5.qq.com,之后点击打开。
或者,通过微信扫一扫,扫描下面的二维码,进入X5调试页面。
4、信息页中,勾选“打开TBS内核Inspector调试功能”。
5、接下来开始使用查找元素定位工具来获取元素的属性值等信息,微信应用程序的原生例如可以使用Android SDK的uiautomatorviewer工具查找元素,小程序页面识别不到webview中的元素,例如显示android.webkit.WebView,那么要用什么工具查找定位呢?例如:京东购物。
接下来打开PC的Chrome浏览器,输入访问地址chrome://inspect/
如图所示,当前打开的小程序界面就是Webview。
点击页面链接(链接很多,要挨个点击查看哪个是),弹出新窗口,显示当前页面的Webview元素信息(由于国内网络问题,第一次页面加载可能需要FANQIANG)。元素定位方法同Selenium WebDriver一致。
6、获取当前小程序的进程
微信有很多的进程,每一个小程序都运行在不同的进程中。 微信打开小程序(例如:京东购物),查看当前运行在哪个进程中。
(1)查询pid,命令行输入 adb shell dumpsys activity top | findstr ACTIVITY
(2)查询当前小程序进程,命令行输入 adb shell ps 查询的pid
脚本参数添加:
代码语言:javascript复制// 启动微信小程序,要设置这里
// 查询pid,命令行输入 adb shell dumpsys activity top | findstr ACTIVITY
// 查询当前小程序进程,命令行输入 adb shell ps 查询的pid
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("androidProcess", "com.tencent.mm:appbrand0");
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
7、切换NATIVE_APP还是WEBVIEW_com.tencent.mm:tools,使用context方法。
8、脚本代码:
代码语言:javascript复制package com.test.weixin;
import java.net.URL;
import java.util.Set;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidElement;
import io.appium.java_client.android.AndroidKeyCode;
/**
* 微信小程序
*
* @author wangmcn
*
*/
public class Xiaochengxv {
public static void main(String[] args) throws Exception {
AndroidDriverdriver;
DesiredCapabilities capabilities = new DesiredCapabilities();
// 使用哪个自动化测试引擎
// 默认为Appium,或Selendroid或UiAutomator2或Espresso用于Android;或XCUITest用于IOS
capabilities.setCapability("automationName", "Appium");
// 使用哪个移动操作系统平台
// iOS, Android, FirefoxOS
capabilities.setCapability("platformName", "Android");
// 移动操作系统版本
capabilities.setCapability("platformVersion", "6.0");
// 使用的移动设备或模拟器的类型
// iPhone Simulator, iPad Simulator, iPhone Retina 4-inch, Android
// Emulator, Galaxy S4 等等
// 在IOS上,这个关键字的值必须是使用`instruments -s devices`得到的可使用的设备名称之一
// 在Android上,这个关键字目前不起作用
capabilities.setCapability("deviceName", "honor");
// 连接的物理设备的唯一设备标识
capabilities.setCapability("udid", "MYV0215825000026");
// 要运行Android应用的包名
capabilities.setCapability("appPackage", "com.tencent.mm");
// 要从包中启动的Android activity的活动名称
capabilities.setCapability("appActivity", "com.tencent.mm.ui.LauncherUI");
// 启用Unicode输入法,设置为true可以输入中文字符,默认为false
capabilities.setCapability("unicodeKeyboard", true);
// 在设定了`unicodeKeyboard`关键字运行Unicode测试结束后,将键盘重置为其原始状态
// 如果单独使用,将会被忽略,默认值`false`
capabilities.setCapability("resetKeyboard", true);
// 设置为true,每次启动时覆盖session,否则第二次运行会报错不能新建session
capabilities.setCapability("sessionOverride", true);
// 在此会话之前不要重置应用程序状态
// Android 不要停止应用程序,不要清除应用程序数据,也不要卸载apk
// IOS 测试后不要销毁或关闭SIM卡。开始测试运行在任何模拟运行,或设备插入
capabilities.setCapability("noReset", true);
// 执行完整的重置
// Android 停止应用程序,清除应用程序数据并在测试后卸载apk
// IOS 在真机设备测试后卸载应用程序,在模拟器测试后摧毁模拟器
capabilities.setCapability("fullReset", false);
// 设置命令超时时间,单位:秒
// 达到超时时间仍未接收到新的命令时Appium会假设客户端退出然后自动结束会话
capabilities.setCapability("newCommandTimeout", 60);
// 启动微信小程序,要设置这里
// 查询pid,命令行输入 adb shell dumpsys activity top | findstr ACTIVITY
// 查询当前小程序进程,命令行输入 adb shell ps 查询的pid
ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("androidProcess", "com.tencent.mm:appbrand0");
capabilities.setCapability(ChromeOptions.CAPABILITY, options);
driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
System.out.println("启动微信应用程序");
Thread.sleep(10000);
// 点击发现
driver.findElementByXPath("//*[@text='发现']").click();
Thread.sleep(5000);
// 向下滑动
driver.swipe(170, 530, 170, 230, 1000);
Thread.sleep(2000);
// 点击小程序
driver.findElementByXPath("//*[@text='小程序']").click();
Thread.sleep(2000);
// 点击京东购物
driver.findElementByXPath("//*[contains(@text, '京东购物')]").click();
Thread.sleep(8000);
Setcontexts = driver.getContextHandles();
for (String context : contexts) {
// 打印出来看看有哪些context
System.out.println(context);
}
// 切换到webview模式以便查找web元素
driver.context("WEBVIEW_com.tencent.mm:tools");
// 获取当前窗口的句柄
String Handle = driver.getWindowHandle();
System.out.println("当前句柄: " Handle);
// 获取所有窗口的句柄
SetHandles = driver.getWindowHandles();
for (String h : Handles) {
if (h.equalsIgnoreCase(Handle)) {
System.out.println("忽略句柄: " h);
} else {
driver.switchTo().window(h);
System.out.println("跳到句柄: " h);
// 打印当前网页源码
System.out.println("句柄 " h " 网页源码:" driver.getPageSource());
}
}
// 点击领优惠券
driver.findElementByXPath("//wx-view[text()='领优惠券']").click();
Thread.sleep(5000);
// 返回
driver.pressKeyCode(AndroidKeyCode.BACK);
// 切换到App模式
driver.context("NATIVE_APP");
Thread.sleep(5000);
// 点击分类
driver.findElementByXPath("//android.widget.TextView[@text='分类']").click();
Thread.sleep(5000);
driver.quit();
}
}
2、执行脚本
1、开启Appium服务(任选一种即可)
方式一:开启Appium Server
打开命令行,输入 appium --address 127.0.0.1 --port 4723 --no-reset --session-override
如图所示,Appium服务开启。
方式二:开启Appium Desktop
打开Appium Desktop
如服务IP和端口默认的情况下,直接点击Start Server v1.6.5来开启Appium服务,如图所示。
2、执行测试脚本,脚本执行步骤:
(1)启动微信应用程序
(2)点击发现
(3)向下滑动
(4)点击小程序
(5)点击京东购物
(6)打印出被测App的NATIVE_APP和WEBVIEW
代码语言:javascript复制NATIVE_APP
WEBVIEW_com.tencent.mm:appbrand1
WEBVIEW_com.tencent.mm:appbrand0
WEBVIEW_com.tencent.mm:support
WEBVIEW_com.tencent.mm:tools
WEBVIEW_com.huawei.wifiprobqeservice
WEBVIEW_com.iflytek.ringdiyclient
(7)切换到WEBVIEW_com.tencent.mm:tools(webview模式)以便查找web元素
(8)获取当前窗口的句柄
(9)获取所有窗口的句柄
因为有多个句柄,要跳到正确的句柄才可以操作页面元素,并且每次执行的时候,句柄值都是变化的,不固定。
第一次执行:
当前句柄: CDwindow-a7bc4687-2728-4d5b-af91-c310951d7247
忽略句柄: CDwindow-a7bc4687-2728-4d5b-af91-c310951d7247
跳到句柄: CDwindow-ac347a13-7a97-4c96-8867-901e1b8888f3
第二次执行:
当前句柄: CDwindow-8b216eef-9ccc-425b-af36-291ff4d98cc8
忽略句柄: CDwindow-8b216eef-9ccc-425b-af36-291ff4d98cc8
跳到句柄: CDwindow-27615809-988a-4533-a441-01ab63e0d968
(10)打印当前网页源码
(11)点击领优惠券
(12)返回
(13)切换到NATIVE_APP(App模式)
(14)点击分类
(15)关闭微信应用程序
脚本执行结束后,控制台打印的信息:
3、在执行测试脚本切换到WebView模式操作中,可能多多少少会遇到一些报错,排除元素定位不对的情况,大部分报错都是WebView与驱动的版本不匹配所产生的。
例如以下报错,提示An unknown server-side error occurred while processing the command. Original error: session not created exception
from unknown error: Runtime.executionContextCreated has invalid 'context': {"auxData":{"frameId":"22596.1","isDefault":true},"id":1,"name":"","origin":"://"}
解决方法就是让WebView版本与驱动版本匹配,让驱动进行降级或者升级。
那如何知道WebView与驱动是否匹配呢?
打开PC的Chrome浏览器,输入访问地址chrome://inspect/
在udid为MYV0215825000026的真机里,打开要操作的微信小程序webview页面,此时在PC的Chrome浏览器中可以看到访问链接,如图所示,真机里的WebView版本号为57.0.2987.132
被测应用的WebView版本号知道了,接下来开始确定要匹配的驱动版本,与chromedriver版本是否匹配。
chromedriver历史版本下载地址:https://chromedriver.storage.googleapis.com/index.html
chromedriver版本支持的Chrome版本对应列表:
选择指定的chromedriver版本(如图:WebView版本为57.0.2987.132,所以chromedriver版本选为2.28),可根据不同的平台(Win、Mac、Linux)下载指定的chromedriver。
指定的chromedriver下载完成后,双击可看此驱动版本号。
chromedriver应该放在哪里呢?根据所要使用的Appium服务,拷贝到Appium Server或者Appium Desktop的相应目录下即可。拷贝完成后,就可以正常使用了。
在Windows环境下:
Appium Server的chromedriver路径,例如:
C:UsersAdministratorAppDataRoamingnpmnode_modulesappiumnode_modulesappium-chromedriverchromedriverwinchromedriver.exe
Appium Desktop的chromedriver路径,例如:
C:UsersAdministratorAppDataLocalProgramsappium-desktopresourcesappnode_modulesappiumnode_modulesappium-chromedriverchromedriverwinchromedriver.exe
在Mac环境下:
注意,当Appium服务用的是Appium Server时,执行脚本报错为An unknown server-side error occurred while processing the command. Original error: Trying to use a chromedriver binary at the path /usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/chromedriver/mac/chromedriver, but it doesn't exist!
说明没有找到chromedriver驱动,按报错提示创建相应目录,并把chromedriver驱动拷贝到指定位置里。
Appium Server的chromedriver路径,例如:
/usr/local/lib/node_modules/appium/node_modules/appium-chromedriver/chromedriver/mac/chromedriver
Appium Desktop的chromedriver路径,例如:
/Applications/Appium.app/Contents/Resources/app/node_modules/appium/node_modules/appium-chromedriver/chromedriver/mac/chromedriver