微信公众号自动化测试

转载:https://blog.csdn.net/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接口作为浏览器的管理;这个坑在网上也没有答案,冥思苦想后终于想出了类型转换的方法,我也是佩服自己能想出接口与实现类之间类型转换的方法。

 

本文链接:https://my.lmcjl.com/post/12704.html

展开阅读全文

4 评论

留下您的评论.