为了账号安全,请及时绑定邮箱和手机立即绑定

如何在自动化测试中实现精准截图?

标签:
JavaScript

今天分享的这个技能可以说是灰常有用,做自动化测试,无论是Web端的Selenium(Appium的使用基本类似Selenium)还是移动端的UiAutomator2.0都有提供相应的截屏API,直接调用对应方法轻松截屏,可是问题来了,很多时候我并不想截取整个屏幕,除了整屏图片太大外,还有有时候我还需要二次处理,比如常见的对指定位置进行背景色提取、样式、文字或数据验证等,这时候就需要我们精准的截取需要的部分,从而排除无关的干扰区域。这要怎么做?下面就以Selenium和UiAutomator2.0的实现代码来演示……

思路

大致思路是在截取整屏后,我们根据坐标和截取区域大小,再次去截取对应的小图,因此要精准截图,这就要以我们能获取到的控件元素或对象为基础,通过对应的对象获取该对象在屏幕中的的坐标,以及对象的区域(长、宽)等信息,有了这些信息就可以通过代码轻松截取指定位置和区域的图了。下面看具体实现:

Selenium实现精准截图

你可以让最终结果返回一个File对象,指向对应的截图后的文件对象,也可以直接返回截图后的文件路径(返回路径:file.getAbsolutePath()),这个根据需要,自己去选择。

private File snapshotAndSave(WebElement element, String filePath) {
    File scrFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);//截图整个页面
    try {
        BufferedImage img = ImageIO.read(scrFile);        // 获得元素的高度和宽度
        int width = element.getSize().getWidth();        int height = element.getSize().getHeight() ;        // 创建一个矩形使用上面的高度,和宽度
        Rectangle rect = new Rectangle(width, height);        // 得到元素的起始坐标
        int x = element.getLocation().getX();        int y = element.getLocation().getY();        //开始按坐标和区域截图
        BufferedImage dest = img.getSubimage(x, y, rect.width, rect.height);        //存为png格式
        ImageIO.write(dest, SNAPSHOT_IMG_SUFFIX, scrFile);
        File file = new File(filePath);
        FileUtils.copyFile(scrFile, file);        return file;
    } catch (Exception e) {
        LOGGER.error("snapshotAndSave error:", e);
    }    return null;
}

UiAutomator2.0实现精准截图

实现思路跟Selenium几乎是一样的,这里传入了一个paths数组(当然你也可以改一下分开传2个参数),传一个就代表截屏和后面的再次截图是用的同一个路径,传2个就对应分开了。返回对应图片文件对象还是路径根据自己需要去调整了。(注:鉴于排版,有些I/O的规范就没遵循了,用的时候自己去调整下流的关闭位置)

public static String takeElementshot(UiObject2 object, String...paths) {    if (paths == null || paths.length < 1) {        throw new IllegalArgumentException("paths参数不能为空");
    }    if (object == null) {        return null;
    }    try {
        File file = new File(paths[0]);
        mDevice.takeScreenshot(file);

        BitmapFactory.Options bfOptions = new BitmapFactory.Options();
        bfOptions.inDither = false;
        bfOptions.inTempStorage = new byte[12 * 1024];
        bfOptions.inJustDecodeBounds = true;
        Bitmap bitmap = BitmapFactory.decodeFile(paths[0]);
        Rect rect = object.getVisibleBounds();
        bitmap = bitmap.createBitmap(bitmap, rect.left, rect.top, rect.width(), rect.height());//获取区域

        String jpgCutPath = paths.length > 1 ? paths[1] : paths[0];
        File filePic = new File(jpgCutPath);    
        if (!filePic.exists()) {
            filePic.createNewFile();
        }
        FileOutputStream fos = new FileOutputStream(jpgCutPath);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
        fos.flush();
        fos.close();        return filePic.getAbsolutePath();
    } catch (Exception e) {        return null;
    }
}

怕有童鞋看不清楚,给个调用的例子演示一下:

String jpgPath = Config.LOG_PATH + "ocr.jpg";String jpgCutPath = Config.LOG_PATH + "ocr_cut.jpg";String path = takeElementshot(object, jpgPath, jpgCutPath);



作者:测试开发栈
链接:https://www.jianshu.com/p/7e0a390616c2


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

举报

0/150
提交
取消