appium+java(四)微信公众号自动化测试实践

前言

随着手机阅读的普遍应用,微信公众号阅读,更为普遍,微信和qq一样,都是基于腾讯自研X5内核,不是google原生webview(其实就是进行了二次定制)。实质上也是混合应用的一种,现在很多app产品也开始流行采用X5内核作为其内嵌web浏览服务,所以掌握X5内核混合应用自动化也是重中之重的一种技能

X5内核应用自动化方式和普通混合应用有非常多的差异,接下来以微信公众号举例介绍怎么来开展X5内核的自动化

准备工作

  1、java-client 3.4.16依赖包

  2、微信应用版本7.0.0

  3、手机端和PC端安装chrome浏览器(注意版本最好对应一致)

  4android手机(7.0+版本)

  5chromedriver 2.26

  6appium-desktop V1.10.0

步骤

1、打开微信,在任意窗口输入:debugx5.qq.com

在打开的界面中选择信息->勾选是否打开TBS内核Inspector调试功能

 

2、手机通过usb连接到电脑,打开USB调试模式,通过adb devices命令检测到设备

 

3、在chrome浏览器里面输入chrome://inspect#devices

 

显示的webview版本是57.xxx,这里就是微信X5内核的版本,不是android System webview版本,同样也可以点击inspect查看页面元素:

可以看到当前就是一个html页面,我们可以采取常规web元素定位方式来定位元素

注意事项:

页面空白加载不出来,这是因为Google的inspect工具需要访问到墙外的网站,所以需要有FQ工具或者VPN方式;

4、默认appium-desktop安装之后里面自带的chromedriver不是2.26的,需要手动去官网

将其放到appium的chromedriver对应目录中,或工程目录

chromedriver与chrome版本映射关系

chromedriver下载链接:
https://chromedriver.storage.googleapis.com/index.html

http://npm.taobao.org/mirrors/chromedriver/
根据映射关系,不同的chrome版本下载不同的chromedrive

5、如何查看公众号在微信中的运行进程
如何查看进程?
我们分别在打开微信不打开小程序和打开微信并打开小程序两种情况下查看当前活动的进程

通过以上可以看到,打开小程序后当前活动的进程号为7671,查看7671对应的进程是com.tencent.mm:toolsmp,因此toolsmp就是
ChromeOptions设置
上面我们查看到当前小程序的活动进程是com.tencent.mm:toolsmp,因此toolsmp就是ChromeOptions中的要设置的值
具体在初始化driver时要添加如下代码:

ChromeOptions options = new ChromeOptions();
options.setExperimentalOption("androidProcess", "com.tencent.mm:toolsmp");
caps.setCapability(ChromeOptions.CAPABILITY, options);

测试代码

package com.rong.appium.demo;

import io.appium.java_client.android.AndroidDriver;
import io.appium.java_client.android.AndroidKeyCode;
import io.appium.java_client.remote.AndroidMobileCapabilityType;
import io.appium.java_client.remote.MobileCapabilityType;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 测试微信公众号菜单
 *
 * @author rongrong
 */
public class WeixinDemo2 {

    AndroidDriver<WebElement> driver;

    @BeforeClass(alwaysRun = true)
    public void setUp() throws Exception {
        // set up appium
        DesiredCapabilities capabilities = new DesiredCapabilities();
        capabilities.setCapability(MobileCapabilityType.DEVICE_NAME, "WTK7N16C14006883");
        capabilities.setCapability("platformName", "Android");
        capabilities.setCapability("deviceName", "Android Emulator");
        capabilities.setCapability("platformVersion", "7.0");
        // 设置app的主包名和主类名(要启动应用包名和activity)
        capabilities.setCapability("appPackage", "com.tencent.mm");  //app包名
        capabilities.setCapability("appActivity", "com.tencent.mm.ui.LauncherUI");
        //要启动的Android Activity名
        capabilities.setCapability("appActivity", ".ui.LauncherUI");
        //不要在会话前重置应用状态
        capabilities.setCapability("noReset", true);
        //Android是否删除应用,IOS是否删除整个模拟器目录
        capabilities.setCapability("fullReset", false);
        capabilities.setCapability("sessionOverride", true);
        //输入配置,是否启动Unicode输入法
        capabilities.setCapability("unicodeKeyboard", true);
        //结束后是否切换回默认输入法
        capabilities.setCapability("resetKeyboard", true);
        File chromedriver = new File("chromedriver.exe");
        capabilities.setCapability(AndroidMobileCapabilityType.CHROMEDRIVER_EXECUTABLE, chromedriver.getAbsolutePath());
        ChromeOptions options = new ChromeOptions();
        options.setExperimentalOption("androidProcess", "com.tencent.mm:tools");
        capabilities.setCapability(ChromeOptions.CAPABILITY, options);
        driver = new AndroidDriver<WebElement>(new URL("http://127.0.0.1:4723/wd/hub"), capabilities);
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    }


    /**
     * webview线程切换
     *
     * @throws Exception
     */
    @Test
    public void testEduConsult() {
        //通讯录
        driver.findElementByName("通讯录").click();
        //公众号
        driver.findElementByName("公众号").click();
        //滚动到指定位置点击
        driver.scrollTo("51CTO学院").click();
        driver.findElementByName("热门课程").click();
        pause(10);
        Set<String> handles = driver.getContextHandles();
        for (String handle : handles) {
            System.out.println(handle);
        }
        //切换到webview的content
        driver.context("WEBVIEW_com.tencent.mm:tools");
        Set<String> windowHandles = driver.getWindowHandles();
        for (String handle : windowHandles) {
            driver.switchTo().window(handle);
            if (driver.getPageSource().contains("5CTO学院微职位")) {
                break;
            }
        }
        //选择linux
        driver.findElementByXPath("/html/body/div[2]/div[1]/div/div[9]/p/a").click();
        pause(2);
        driver.findElementByXPath("//div[@class='fr Ly']").click();
        pause(2);
        driver.switchTo().frame("doyoo_f_work");
        //进入对话框咨询三次
        driver.findElementById("message").click();
        for (int i = 0; i < 3; i++) {
            driver.findElementById("message").clear();
            //输入咨询价格
            driver.findElementById("message").sendKeys("how much?");
            pause(2);
            //点击发送
            driver.findElementById("btnSendMsg").click();
        }
        for (int i = 0; i < 4; i++) {
            driver.pressKeyCode(4);
            pause(3);
        }
    }

    @AfterClass
    public void afterTestStopDriver() {
        driver.quit();
    }

    /**
     * 程序暂停几秒
     *
     * @param i
     */
    public void pause(int i) {
        try {
            Thread.sleep(i * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

总结:

进入到公众号内,切换到小程序context后,还需要切换到当前的windowHandle,windowHandle切换成功,正确的webview页面自然就能找到
执行后查看获取到的页面源码,然后就可以愉快的玩耍了

运行效果

posted @ 2019-01-16 14:10  久曲健  阅读(3683)  评论(0编辑  收藏  举报