微信公众号自动化测试

转载:https://blog.youkuaiyun.com/baidu_37711332/article/details/82584928

时下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如下:


 
  1. {
  2. "capabilities": [
  3. {
  4. "browserName": "chrome",
  5. "version": "5.0.1",
  6. "maxInstances": 1,
  7. "platform": "ANDROID",
  8. "udid": "127.0.0.1:62001",
  9. "deviceName": "127.0.0.1:62001"
  10. }
  11. ],
  12. "configuration": {
  13. "cleanUpCycle": 2000,
  14. "timeout": 30000,
  15. "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
  16. "hub": "192.168.1.103:4455/grid/register",
  17. "url": "http://192.168.1.103:4723/wd/hub",
  18. "host": "192.168.1.103",
  19. "port": 4723,
  20. "maxSession": 1,
  21. "register": true,
  22. "registerCycle": 5000,
  23. "hubPort": 4455,
  24. "hubHost": "192.168.1.103"
  25. }
  26. }

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入口)


 
  1. public class TestBaseCase {
  2. public static WebDriver driver;
  3. public static String description;
  4. public Log log= new Log( this.getClass().getSuperclass());
  5. public void setup( String driver,String nodeURL) throws MalformedURLException {
  6. log.info( "------------------开始执行测试---------------");
  7. log.info( "读取xml配置:浏览器:"+driver+ ";gridNodeURL:"+nodeURL);
  8. try {
  9. this.driver=setRemoteDriver(driver,nodeURL);
  10. } catch (Exception e) {
  11. log.error( "没有成功浏览器环境配置错误");
  12. }
  13. this.driver.manage().window().maximize();
  14. }
  15. @ AfterTest
  16. public void tearDown () {
  17. try {
  18. this.driver.close();
  19. this.driver.quit();
  20. } catch (Exception e) {
  21. log.info( "android driver 退出需切换会NATIVE_APP");
  22. AndroidDriver androidDriver=(AndroidDriver) driver;
  23. androidDriver.quit();
  24. }
  25. }
  26. private WebDriver setRemoteDriver(String browsername,String nodeURL) throws MalformedURLException
  27. {
  28. switch (browsername)
  29. {
  30. case "FirefoxDriver" :
  31. DesiredCapabilities capabilities=DesiredCapabilities.firefox();
  32. capabilities.setBrowserName( "firefox");
  33. capabilities.setPlatform(Platform.WINDOWS);
  34. driver= new RemoteWebDriver( new URL(nodeURL), capabilities);
  35. break;
  36. case "ChormeDriver":
  37. DesiredCapabilities dcchorme=DesiredCapabilities.chrome();
  38. dcchorme.setBrowserName( "chrome");
  39. dcchorme.setVersion( "46.0.2490.86 m");
  40. dcchorme.setPlatform(Platform.WINDOWS);
  41. driver= new RemoteWebDriver( new URL(nodeURL), dcchorme);
  42. break;
  43. case "WeiXIN":
  44. DesiredCapabilities capability = new DesiredCapabilities();
  45. capability.setCapability( "app", "");
  46. capability.setCapability( "appPackage", "com.tencent.mm");
  47. capability.setCapability( "appActivity", ".ui.LauncherUI");
  48. capability.setCapability( "deviceName", "127.0.0.1:62001");
  49. capability.setCapability( "fastReset", "false");
  50. capability.setCapability( "fullReset", "false");
  51. capability.setCapability( "noReset", "true");
  52. capability.setCapability( "unicodeKeyboard", "True");
  53. capability.setCapability( "resetKeyboard", "True");
  54. //关键是加上这段
  55. ChromeOptions options2 = new ChromeOptions();
  56. options2.setExperimentalOption( "androidProcess", "com.tencent.mm:tools");
  57. capability.setCapability(ChromeOptions.CAPABILITY, options2);
  58. //启动微信浏览器
  59. log.info( "启动微信浏览器");
  60. driver= new AndroidDriver( new URL(nodeURL), capability);
  61. driver.manage().timeouts().implicitlyWait( 500, TimeUnit.MILLISECONDS);
  62. sleep( 5);
  63. log.info( "点击微信搜索菜单");
  64. WebElement webElement=driver.findElement(By.xpath( "//*[@content-desc='搜索']"));
  65. webElement.click();
  66. log.info( "输入文件字符串");
  67. webElement=driver.findElement(By.xpath( "//*[@text='搜索']"));
  68. webElement.click();
  69. webElement.clear();
  70. webElement.sendKeys( "文件");
  71. sleep( 4);
  72. log.info( "点击文件传输助手");
  73. webElement=driver.findElement(By.xpath( "//*[@text='文件传输助手']"));
  74. webElement.click();
  75. sleep( 8);
  76. log.info( "发送跳转网站的网页URL");
  77. webElement= driver.findElement(By.xpath( "//*[@resource-id='com.tencent.mm:id/z4']")); //不同微信版本,定位不一样
  78. webElement.sendKeys( "http://192.168.1.103:8080/openurl/open.html");
  79. log.info( "点击发送按钮");
  80. webElement=driver.findElement(By.xpath( "//*[@text='发送']"));
  81. webElement.click();
  82. sleep( 3);
  83. log.info( "点击网址");
  84. webElement=driver.findElement(By.xpath( "//*[@text='"+ "http://192.168.1.103:8080/openurl/open.html"+ "']"));
  85. webElement.click();
  86. sleep( 3);
  87. log.info( "切换到微信webView");
  88. //Webdriver转AndroidDriver
  89. AndroidDriver androidDriver=(AndroidDriver) driver;
  90. androidDriver.context( "WEBVIEW_com.tencent.mm:tools");
  91. driver=androidDriver;
  92. case "HtmlUnitDriver":
  93. this.driver= new HtmlUnitDriver();
  94. break;
  95. default:
  96. this.driver= new FirefoxDriver();
  97. break;
  98. }
  99. return driver;
  100. }
  101. }

三、设计网址入口网页


 
  1. <html>
  2. <head>
  3. <meta charset="GBK"/>
  4. <script src="http://cdn.static.runoob.com/libs/jquery/1.10.2/jquery.min.js">
  5. </script>
  6. </head>
  7. <body style="text-align:center">
  8. <div>
  9. <input id="url" type="text"/>
  10. <input id="openurl" type="button" value="打开网页"/>
  11. </div>
  12. <script>
  13. $( "#openurl").click( function(){
  14. var url=$( "#url").val();
  15. location.href=url;
  16. }
  17. )
  18. </script>
  19. </body>
  20. </html>

 

四、设计open方法


 
  1. //微信浏览器操作
  2. public void openWeiXinBrowser(String url) {
  3. WebElement webElement=driver.findElement(By.id( "url"));
  4. log.info( "输入网址:"+url);
  5. webElement.sendKeys(url);
  6. try {
  7. Thread.sleep( 1000);
  8. } catch (InterruptedException e) {
  9. e.printStackTrace();
  10. }
  11. webElement=driver.findElement(By.id( "openurl"));
  12. log.info( "点击打开网页");
  13. webElement.click();
  14. }

五、设计截图方法


 
  1. public class ScreenShot {
  2. public WebDriver driver;
  3. private String screenName;
  4. Log log = new Log( this.getClass());
  5. public void setscreenName(String screenName)
  6. {
  7. this.screenName=screenName;
  8. }
  9. public ScreenShot(WebDriver driver)
  10. {
  11. this.driver=driver;
  12. }
  13. private void takeScreenshot(String screenPath) {
  14. try{
  15. scrFile=((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
  16. } catch (Exception e) //关键就在于此
  17. {
  18. //appium 内chrome没法截图,需用原生app下进行截图
  19. System.out.println( "进入到了webview 截图需切换回 NATIVE_APP content");
  20. AndroidDriver driver2=((AndroidDriver) driver); //关键就在于此
  21. log.info( "contextName:"+driver2.getContext());
  22. System.out.println(driver2.getContextHandles());
  23. // log.info(driver2.getContextHandles().toString());
  24. log.info( "切换到NATIVE_APP进行app截图");
  25. driver2.context( "NATIVE_APP");
  26. scrFile=((TakesScreenshot) driver2).getScreenshotAs(OutputType.FILE);
  27. log.info( "切换回微信webviw");
  28. driver2.context( "WEBVIEW_com.tencent.mm:tools");
  29. }
  30. try {
  31. Files.copy(scrFile, new File(screenPath));
  32. log.error( "错误截图:"+screenPath);
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. public void takeScreenshot() {
  38. String screenName = this.screenName+ ".jpg";
  39. File dir = new File( "test-output\\snapshot");
  40. if (!dir.exists())
  41. {dir.mkdirs();}
  42. String screenPath = dir.getAbsolutePath() + "\\" + screenName;
  43. this.takeScreenshot(screenPath);
  44. }
  45. }

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值