微信公众号自动化测试

时下H5应用很火,微信公众号,微信小程序,支付宝服务窗等,其应用跟PC端的Web应用有共同也有区别之处,但其实H5应用跟pc端的web应用是差不多的,其本质都是web应用,都是要通过浏览器或者Webview浏览器进行操作,只不过H5应用更多的是运行在手机端而不是PC端。由于设备端不一样,H5应用是在手机端,没法像PC端的WEB应用那么简单,所以很多时候,可能是把H5划归到APP自动化进行管理的。既然有这么多共同之处,那么有没有办法把它封装成一种浏览器,归类到Web自动化测试中呢,达到跟WEB UI统一的操作入口?看了思寒的微信Webview自动化测试方法的帖子,给了我灵感,特分享出来

网上流传的H5自动化测试有两种方案,一种是利用PC端谷歌浏览器的设备UA模式,模拟手机浏览器,一种是利用Appium连接手机,进入应用切换到Webview;一种方案是比较简单的,但是没有办法完全模拟手机浏览器的环境,所以采用第二种方法。下面说下具体的过程
一、将apium注册到selenium gird
采用Appium 的方式,Appium Driver启动方式与Webdriver的启动方式略有不同,那么如何达到统一的入口呢?Selenium有一种分布式解决方案Selenium Grid,如果把Appium Server 注册到Selenium Grid hub上就实现了统一的入口了。appium 注册到selenium grid的方法,网上有很多例子,但经过实验发现,有几个地方需要特别注意:
1、注册node节点的时候需指定udid, 2、启动的时候要顺带启动appium 内置的chromedriver,3、appium 地址,grid hub地址不能指定为127.0.0.1,不然其他机器就没办法通过ip进行访问了。下面是我的appium 注册代码:
nodeconfig如下:

{  
    "capabilities": [  
        {  
            "browserName": "chrome",  
            "version": "5.0.1",  
            "maxInstances": 1,  
            "platform": "ANDROID",
       "udid":"127.0.0.1:62001",
       "deviceName":"127.0.0.1:62001"
        }  
    ],  
    "configuration": {  
        "cleanUpCycle": 2000,  
        "timeout":30000,  
        "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",  
    "hub":"192.168.1.103:4455/grid/register",
        "url":"http://192.168.1.103:4723/wd/hub",  
        "host": "192.168.1.103",  
        "port": 4723,  
        "maxSession": 1,  
        "register": true,  
        "registerCycle": 5000,  
        "hubPort": 4455,  
        "hubHost": "192.168.1.103"   
    }  
}  

appium 启动脚本:

appium --address 192.168.1.103 --port 4723  --bootstrap-port 4724 --chromedriver-port 8000  --session-override --nodeconfig D:\auto\appium-node\appium-node.json

二、设计testbase(浏览器启动和关闭)类

原理:由于微信浏览器没有像PC浏览器一样有网址输入口,所以需要通过文件传输助手输入自己设计的网址入口地址(类似hao123入口)

public class TestBaseCase {
    public static WebDriver driver;
    public static String description;
    public Log log=new Log(this.getClass().getSuperclass());
    public void  setup( String driver,String nodeURL) throws MalformedURLException {
        log.info("------------------开始执行测试---------------");
        log.info("读取xml配置:浏览器:"+driver+";gridNodeURL:"+nodeURL);
        try {
                this.driver=setRemoteDriver(driver,nodeURL);
        } catch (Exception e) {
                log.error("没有成功浏览器环境配置错误");
        }

        this.driver.manage().window().maximize();

    }

    @AfterTest
    public void tearDown() {
        try {
            this.driver.close();
            this.driver.quit();
        }catch (Exception e) {
            log.info("android driver 退出需切换会NATIVE_APP");
            AndroidDriver androidDriver=(AndroidDriver) driver;
            androidDriver.quit();
        }
    }
    private WebDriver setRemoteDriver(String browsername,String nodeURL) throws MalformedURLException
    {
        switch (browsername)
        {

            case "FirefoxDriver" :
                DesiredCapabilities capabilities=DesiredCapabilities.firefox();
                capabilities.setBrowserName("firefox");
                capabilities.setPlatform(Platform.WINDOWS);
                driver= new RemoteWebDriver(new URL(nodeURL), capabilities);
                break;
            case "ChormeDriver":
                DesiredCapabilities dcchorme=DesiredCapabilities.chrome();
                dcchorme.setBrowserName("chrome");
                dcchorme.setVersion("46.0.2490.86 m");
                dcchorme.setPlatform(Platform.WINDOWS);
                driver=new RemoteWebDriver(new URL(nodeURL), dcchorme);
                break;
            case "WeiXIN":
                DesiredCapabilities capability = new DesiredCapabilities();
                capability.setCapability("app", "");
                capability.setCapability("appPackage", "com.tencent.mm");
                capability.setCapability("appActivity", ".ui.LauncherUI");
                capability.setCapability("deviceName", "127.0.0.1:62001");
                capability.setCapability("fastReset", "false");
                capability.setCapability("fullReset", "false");
                capability.setCapability("noReset", "true");
                capability.setCapability("unicodeKeyboard", "True");
                                capability.setCapability("resetKeyboard", "True");
                //关键是加上这段
                ChromeOptions options2 = new ChromeOptions();
                options2.setExperimentalOption("androidProcess", "com.tencent.mm:tools");
                capability.setCapability(ChromeOptions.CAPABILITY, options2);
                //启动微信浏览器
                log.info("启动微信浏览器");
                 driver= new AndroidDriver(new URL(nodeURL), capability);
                driver.manage().timeouts().implicitlyWait(500, TimeUnit.MILLISECONDS);
                sleep(5);
                                log.info("点击微信搜索菜单");
                WebElement webElement=driver.findElement(By.xpath("//*[@content-desc='搜索']"));
                webElement.click();
                log.info("输入文件字符串");
                webElement=driver.findElement(By.xpath("//*[@text='搜索']"));
                webElement.click();
                webElement.clear();
                webElement.sendKeys("文件");
                sleep(4);
                log.info("点击文件传输助手");
                webElement=driver.findElement(By.xpath("//*[@text='文件传输助手']"));
                webElement.click();
                sleep(8);
                log.info("发送跳转网站的网页URL");
                   webElement= driver.findElement(By.xpath("//*[@resource-id='com.tencent.mm:id/z4']"));//不同微信版本,定位不一样
                webElement.sendKeys("http://192.168.1.103:8080/openurl/open.html");
                log.info("点击发送按钮");
                webElement=driver.findElement(By.xpath("//*[@text='发送']"));
                webElement.click();
                sleep(3);
                log.info("点击网址");
                webElement=driver.findElement(By.xpath("//*[@text='"+"http://192.168.1.103:8080/openurl/open.html"+"']"));
                webElement.click();
                  sleep(3);
                  log.info("切换到微信webView");
                               //Webdriver转AndroidDriver
                                AndroidDriver androidDriver=(AndroidDriver) driver;
                androidDriver.context("WEBVIEW_com.tencent.mm:tools");
                                 driver=androidDriver;

            case "HtmlUnitDriver":
                this.driver=new HtmlUnitDriver();
                break;
            default:
                this.driver=new FirefoxDriver();
                break;
        }
        return driver;
    }
}

三、设计网址入口网页

<html>
<head>
 <meta charset="GBK"/>
 <script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js">
</script>
</head>
<body style="text-align:center">
   <div>
      <input id="url" type="text"/>
      <input id="openurl" type="button" value="打开网页"/>
   </div>
   <script>
     $("#openurl").click(function(){
     var url=$("#url").val();
         location.href=url;
      }
     )
   </script>
</body>
</html>

四、设计open方法

//微信浏览器操作
public void openWeiXinBrowser(String url)  {
    WebElement webElement=driver.findElement(By.id("url"));
    log.info("输入网址:"+url);
    webElement.sendKeys(url);
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    webElement=driver.findElement(By.id("openurl"));
    log.info("点击打开网页");
    webElement.click();
}

五、设计截图方法

public class ScreenShot {
    public WebDriver driver;
    private String screenName;
    Log log =new Log(this.getClass());
    public void setscreenName(String screenName)
    {
        this.screenName=screenName;
    }
    public ScreenShot(WebDriver driver)
    {
        this.driver=driver;
    }
    private void takeScreenshot(String screenPath) {
        try{
            scrFile=((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
        }catch (Exception e)//关键就在于此
        {
            //appium 内chrome没法截图,需用原生app下进行截图
            System.out.println("进入到了webview 截图需切换回 NATIVE_APP content");
            AndroidDriver driver2=((AndroidDriver) driver);//关键就在于此
            log.info("contextName:"+driver2.getContext());
            System.out.println(driver2.getContextHandles());
//          log.info(driver2.getContextHandles().toString());
            log.info("切换到NATIVE_APP进行app截图");
            driver2.context("NATIVE_APP");
            scrFile=((TakesScreenshot) driver2).getScreenshotAs(OutputType.FILE);
            log.info("切换回微信webviw");
            driver2.context("WEBVIEW_com.tencent.mm:tools");
        }
        try {
            Files.copy(scrFile, new File(screenPath));
            log.error("错误截图:"+screenPath);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public  void takeScreenshot() {
        String screenName =this.screenName+ ".jpg";
        File dir = new File("test-output\\snapshot");
        if (!dir.exists())
        {dir.mkdirs();}
        String screenPath = dir.getAbsolutePath() + "\\" + screenName;
        this.takeScreenshot(screenPath);
    }

}

到此就完成了微信浏览器入口统一,这里面的坑是AndroidDriver的Contentext方法并没有在Webdriver里定义,而微信截图等很多地方需要切换Contentext才能操作,而要达到入口统一肯定需要通过Webdriver接口作为浏览器的管理;这个坑在网上也没有答案,冥思苦想后终于想出了类型转换的方法,我也是佩服自己能想出接口与实现类之间类型转换的方法。

扫描二维码关注公众号,回复: 3148947 查看本文章

猜你喜欢

转载自blog.csdn.net/baidu_37711332/article/details/82584928
今日推荐