• 20200824_小程序自动化测试与失败用例截图


    1、微信小程序自动化

    由于腾讯系QQ、微信是基于腾讯自研X5内核-类似webview,不是谷歌原生webview,所以调试会有些
    许差异(有很多app厂商也开始采用X5内核)
    微信小程序自动化测试只能够支持手机,模拟器是不行的

    • step1:打开微信小程序webview调试开关

    聊天窗口输入如下URL,然后点击即打开调试开关:
    http://debugmm.qq.com/?forcex5=true
    http://debugx5.qq.com

    • step2:UC开发者工具识别小程序的web元素信息
    • step3:确认微信小程序对应的进程名 --com.tencent.mm:appbrand0

    微信有很多的进程,我们要确定当前小程序是位于哪个进程中:

    adb shell dumpsys activity top | findstr ACTIVITY 查询前台运行的所有进程

    • step4:X5内核启动参数配置
      // 支持X5内核应用自动化配置
      desiredCapabilities.setCapability("recreateChromeDriverSessions", true);
      // ChromeOptions使用来定制启动选项,因为在appium中切换context识别webview的时候,
      // 由于小程序是在一个单独的进程中,所以需要加上androidProcess:
      com.tencent.mm:appbrand0
      ChromeOptions options = new ChromeOptions();
      // 第二个参数要改成你查询到的小程序进程名
      options.setExperimentalOption("androidProcess", "com.tencent.mm:appbrand0");
      desiredCapabilities.setCapability(ChromeOptions.CAPABILITY, options);
      // 初始化会默认将chrome浏览器打开,需要将Browser置为空
      desiredCapabilities.setBrowserName("");
    • step5:一定记得加!!!不清除微信的数据
      //不清除掉微信的数据
      capabilities.setCapability("noReset",true);
    • step6:编写脚本
    //微信启动需要时间,所以这里需要等待
    Thread.sleep(15000);
    //下拉,滑动,展示出来小程序列表
    swipeDown();
    androidDriver.findElementByAndroidUIAutomator("new UiSelector().text("柠檬班软件…
    ")").click();
    //小程序加载需要时间,再等待
    Thread.sleep(15000);
    //切换到小程序对应的context中
    androidDriver.context("WEBVIEW_com.tencent.mm:appbrand0");
    //获取到所有的窗口 -- 句柄
    Set<String> handles = androidDriver.getWindowHandles();
    //对所有的窗口进行遍历,满足条件: 只要这个窗口包含特定的:URL/标题
    for (String handle : handles) {
    //否则我们就去切换handle句柄 窗口
    androidDriver.switchTo().window(handle);
    if(androidDriver.getTitle().equals("腾讯课堂柠檬班软件测试")){
    //说明当前我们确实是在对应的窗口中
    break;
    }
    }
    //点击课程
    androidDriver.findElement(By.xpath("//a[contains(text(),
    '课程')]")).click();

    2、微信小程序测试强调几点

    1. 真机测试
    2. 两个url点击,开启开关
    3. 进程名自己输入查看
    4. 页面下滑,选中名字,名字有可能缩写,按工具的缩写写
    5. 切换context到webview,另外小程序会打开三个页面,所以要遍历,进行窗口切换确认,什么时候用app的元素定位,什么时候用网页的元素定位,参数别搞错
    6. 微信小程序兼容的chromeDriver是V2.40,不按给出的版本选择
    import com.lemon.data.Constants;
    import io.appium.java_client.MobileBy;
    import io.appium.java_client.TouchAction;
    import io.appium.java_client.android.AndroidDriver;
    import io.appium.java_client.touch.WaitOptions;
    import io.appium.java_client.touch.offset.PointOption;
    import org.openqa.selenium.By;
    import org.openqa.selenium.chrome.ChromeOptions;
    import org.openqa.selenium.remote.DesiredCapabilities;
    import org.testng.annotations.BeforeTest;
    import org.testng.annotations.Test;
    
    import java.net.MalformedURLException;
    import java.net.URL;
    import java.sql.Time;
    import java.time.Duration;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    
    
    public class SmallProgramTest {
        public AndroidDriver androidDriver;
        @BeforeTest
        public void setUp() throws MalformedURLException {
            //启动微信
            DesiredCapabilities desiredCapabilities = new DesiredCapabilities();
            desiredCapabilities.setCapability("deviceName", "08e7c5997d2a");
            desiredCapabilities.setCapability("platformName","Android");
            desiredCapabilities.setCapability("appPackage","com.tencent.mm");
            desiredCapabilities.setCapability("appActivity","com.tencent.mm.ui.LauncherUI");
            //一定要注意!!!此配置一定要加 不清楚微信的数据
            desiredCapabilities.setCapability("noReset",true);
            // 支持X5内核应用自动化配置
            desiredCapabilities.setCapability("recreateChromeDriverSessions", true);
            // ChromeOptions使用来定制启动选项,因为在appium中切换context识别webview的时候,
            // 由于小程序是在一个单独的进程中,所以需要加上androidProcess: com.tencent.mm:appbrand0
            ChromeOptions options = new ChromeOptions();
            // 第二个参数要改成你查询到的小程序进程名
            options.setExperimentalOption("androidProcess", "com.tencent.mm:appbrand0");
            desiredCapabilities.setCapability(ChromeOptions.CAPABILITY, options);
            // 初始化会默认将chrome浏览器打开,需要将Browser置为空
            desiredCapabilities.setBrowserName("");
    
            URL url= new URL("http://127.0.0.1:4723/wd/hub");//http://127.0.0.1:4723/wd/hub
            androidDriver = new AndroidDriver(url,desiredCapabilities);
            //设置全局的隐式等待
            androidDriver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        }
    
        @Test
        public void testLemon() throws InterruptedException {
            //在微信的首页向下滑动进入到小程序列表
            Thread.sleep(8000);
            swipeDown(800);
            //选择对应的小程序-柠檬班软件测试
            androidDriver.findElement(MobileBy.AndroidUIAutomator("new UiSelector().text("柠檬班软件…")")).click();
            Thread.sleep(10000);
            //进入到小程序页面之后-切换context
            Set<String> contexts = androidDriver.getContextHandles();
            System.out.println(contexts);
            //切换context
            androidDriver.context("WEBVIEW_com.tencent.mm:appbrand0");
            //坑·· 小程序打开后会有三个窗口,必须要切换窗口才可以在对应的页面找元素/操作元素
            //获取打开的所有web窗口句柄
            Set<String> handles = androidDriver.getWindowHandles();
            //循环遍历集合切换正确的窗口
            for(String handle : handles){
                //条件判断:什么时候下才是正确的句柄--根据当前窗口的标题来判断
                if(androidDriver.getTitle().equals("腾讯课堂柠檬班软件测试")){
                    //符合的,跳出循环
                    break;
                }else{
                    //切换句柄
                    androidDriver.switchTo().window(handle);
                }
            }
            //坑:微信使用的是77版本webview(X5内核),不能按照常规匹配模式去找对应的chromeDriver
            //微信小程序兼容的chromeDriver是V2.40
            //定位元素
            androidDriver.findElement(By.partialLinkText("课程")).click();
            //web定位方式找元素/操作元素
    
        }
    
        //向下滑动方法
        public void swipeDown(int time){
            //获取屏幕宽和高
            int width = androidDriver.manage().window().getSize().getWidth();
            int height = androidDriver.manage().window().getSize().getHeight();
            //滑动的距离Or效果由什么决定??
            //1、由起始点和终止点的距离
            //2、滑动时间快慢
            //起始点坐标:435 610  终止点坐标:435 1206  向下滑动
            //(1)、创建touchAction对象
            TouchAction touchAction = new TouchAction(androidDriver);
            //(2)把原始坐标转换成PointOption类型的对象
            //起始点:屏幕1/2宽度  1/3高度位置
            //终止点:屏幕1/2宽度  2/3高度位置
            PointOption pointOption1 = PointOption.point(width/2,height/4);
            PointOption pointOption2 = PointOption.point(width/2,height*3/4);
            //(3)、通过touchAction完成一系列手势操作
            //先去按压起始点->移动到终止点->手指释放-->让动作生效
            //waitAction -->设置滑动的时间 WaitOptions
            Duration duration = Duration.ofMillis(time);
            WaitOptions waitOptions = WaitOptions.waitOptions(duration);
            touchAction.press(pointOption1).waitAction(waitOptions).moveTo(pointOption2).release().perform();
        }
    
    }

    3、失败用例截图

    3.1 生成本地图片

    public static void takeScreenshot(String filePath) {
    // 类型强制转换
    TakesScreenshot takesScreenshot = (TakesScreenshot) driver;
    // OutputType.FILE -->返回类型为File(图片)
    File srcFile = takesScreenshot.getScreenshotAs(OutputType.FILE);
    // 把file(图片)保存到本地
    // 给一个目标地址的File对象
    File destFile = new File(filePath);
    // 把原始file对象拷贝到目标地址对应的file对象中
    // 第三方依赖 commons-io
    try {
    FileUtils.copyFile(srcFile, destFile);
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
    }

    3.2 Allure报表嵌入截图

    1、创建AllureReportListener类实现IHookable接口
    IHookable接口作用:动态替换每一个被@Test注解标注的方法

    public class TestResultListener implements IHookable {
    //public int i = 1;
    @Override
    public void run(IHookCallBack iHookCallBack, ITestResult iTestResult) {
    //在执行的时候替换掉@Test注解标注的测试方法
    //System.out.println("这里是监听器的run方法");
    //我们的目的是为了监听测试结果的,不是为了禁止掉测试方法执行
    //让测试方法可以正常的执行
    iHookCallBack.runTestMethod(iTestResult);
    //监听测试的结果(失败的???) iTestResult--》保存测试的结果
    if(iTestResult.getThrowable() != null){
    //此时来截图
    //OutputType.FILE --> 返回值类型File类型
    File srcFile =
    BaseTest.androidDriver.getScreenshotAs(OutputType.FILE);
    //把File对象保存到本地,以图片格式
    //每一次生成的截图名字都得要不一样
    //System.out.println(iTestResult.get());
    //如何获取到工程的根路径
    String projectPath = System.getProperty("user.dir");
    //时间戳
    long time = System.currentTimeMillis();
    //格式转换
    File targetFile = new File(projectPath+"\screenshot\screenshot_"+
    iTestResult.getName()+"_"+time+".png");
    //i++;
    try {
    FileUtils.copyFile(srcFile,targetFile);
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }

    2、配置监听器-testng.xml,和test同级别-记得要运行这文件,不然不生效

    <listeners>
    <listener class-name="com.lemon.listener.AllureReportListener"/>
    </listeners>

     

  • 相关阅读:
    ASP.NET对IIS中的虚拟目录进行操作
    QLive EULA
    Windows Phone在模拟器中去除Debug信息
    Windows Phone区别应用是App还是Game
    UI Automation By Microsoft
    UIA: Choose item in Combobox
    身份证号码验证 C#
    Windows Phone 获取窗口大小
    重载 Sort, ==, !=
    C++枚举类型
  • 原文地址:https://www.cnblogs.com/shishibuwan/p/13775574.html
Copyright © 2020-2023  润新知