Appium 中截取 element 图片作为对比,判断对比结果

本文介绍如何使用Appium实现对应用界面特定元素的截图,并通过图片对比功能判断界面变化,包括代码示例及实际测试过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

哈哈,看了以下两个帖子,综合下捣鼓出了这个对比的功能
@ianxiaohanxu
http://testerhome.com/topics/1389
@monkey
http://testerhome.com/topics/202

其实在https://github.com/gb112211/Adb-For-Test 里面有一个截取element进行对比的方法,但是在使用appium时是无法使用的,因为其用到了uiautomator命令。。。

在appium中截取界面某个element,也就是截取屏幕的部分区域进行对比,在以图片对比结果作为判断依据的时候还是有用的,直接上代码:
extend.py

#!/usr/bin/env python
#coding=utf-8

import os
import platform
import tempfile
import shutil

from PIL import Image

PATH = lambda p: os.path.abspath(p)
TEMP_FILE = PATH(tempfile.gettempdir() + "/temp_screen.png")

class Appium_Extend(object):
    def __init__(self, driver):
        self.driver = driver

    def get_screenshot_by_element(self, element):
        #先截取整个屏幕,存储至系统临时目录下
        self.driver.get_screenshot_as_file(TEMP_FILE)

        #获取元素bounds
        location = element.location
        size = element.size
        box = (location["x"], location["y"], location["x"] + size["width"], location["y"] + size["height"])

        #截取图片
        image = Image.open(TEMP_FILE)
        newImage = image.crop(box)
        newImage.save(TEMP_FILE)

        return self

    def get_screenshot_by_custom_size(self, start_x, start_y, end_x, end_y):
        #自定义截取范围
        self.driver.get_screenshot_as_file(TEMP_FILE)
        box = (start_x, start_y, end_x, end_y)

        image = Image.open(TEMP_FILE)
        newImage = image.crop(box)
        newImage.save(TEMP_FILE)

        return self

    def write_to_file( self, dirPath, imageName, form = "png"):
        #将截屏文件复制到指定目录下
        if not os.path.isdir(dirPath):
            os.makedirs(dirPath)
        shutil.copyfile(TEMP_FILE, PATH(dirPath + "/" + imageName + "." + form))

    def load_image(self, image_path):
        #加载目标图片供对比用
        if os.path.isfile(image_path):
            load = Image.open(image_path)
            return load
        else:
            raise Exception("%s is not exist" %image_path)

    #http://testerhome.com/topics/202
    def same_as(self, load_image, percent):
        #对比图片,percent值设为0,则100%相似时返回True,设置的值越大,相差越大
        import math
        import operator

        image1 = Image.open(TEMP_FILE)
        image2 = load_image

        histogram1 = image1.histogram()
        histogram2 = image2.histogram()

        differ = math.sqrt(reduce(operator.add, list(map(lambda a,b: (a-b)**2, \
                                                         histogram1, histogram2)))/len(histogram1))
        if differ <= percent:
            return True
        else:
            return False

接着跑了个appium脚本简单测试了下:
extend_test.py

#coding=utf-8

import unittest
import os

from extend import Appium_Extend
from appium import webdriver

class Test(unittest.TestCase):
    #初始化环境
    def setUp(self):
        desired_caps = {}
        desired_caps["platformName"] = "Android"
        desired_caps["platformVersion"] = "4.3"
        desired_caps["deviceName"] = "788a6ab5"
        desired_caps["appPackage"] = "com.android.settings"
        desired_caps["appActivity"] = ".Settings"

        self.driver = webdriver.Remote("http://127.0.0.1:4723/wd/hub", desired_caps)

        self.extend = Appium_Extend(self.driver)

        #回到主屏幕
        self.driver.press_keycode(3)

    #退出测试
    def tearDown(self):
        self.driver.quit()

    def test_get_screen_by_element(self):
        element = self.driver.find_element_by_id("com.android.deskclock:id/imageview")

        self.extend.get_screenshot_by_element(element).write_to_file("f:\\screen", "image")
        self.assertTrue(os.path.isfile("f:\\screen\\image.png"))

    def test_same_as(self):
        element = self.driver.find_element_by_id("com.android.deskclock:id/imageview")

        load = self.extend.load_image("f:\\screen\\image.png")
        #要求百分百相似
        result = self.extend.get_screenshot_by_element(element).same_as(load, 0)
        self.assertTrue(result)

if __name__ == "__main__":
    suite = unittest.TestSuite()
    suite.addTest(Test("test_get_screen_by_element"))
    suite.addTest(Test("test_same_as"))
    #执行测试
    unittest.TextTestRunner().run(suite)

这里截取的图片是下面这张图中的时间插件:


截取后的图片:

另外批量截图、批量对比就针对需求再做扩展了!

要使用appium自动化获取图片验证码,可以按照以下步骤进行操作: 1. 导入所需的库和类: - import time:用于生成唯一的文件名。 - from common.image_recognition import ImageRecognition:用于图像识别。 - from page.base_page import BasePage:用于页面的基本操作。 2. 创建一个名为Screen的类,继承BasePage类。 3. 在Screen类中定义一个名为_get_part_screen(self)的方法,用于截取页面中特定区域的验证码图片保存至指定的文件夹中。 4. 在_get_part_screen方法中,定义图片验证码输入框的定位路径。 5. 设置截取图片保存位置和文件名,可以使用时间戳来生成唯一的文件名。 6. 使用appium提供的方法,如find_element_by_xpath()来定位截取特定位置的图片保存在指定的位置和文件名。 7. 实例化ImageRecognition类,传入需要识别的图片位置。 8. 调用ImageRecognition类的ocr()方法,进行图像识别,获取识别结果。 下面是一个示例代码,其中包含了以上步骤的实现: import time from common.image_recognition import ImageRecognition from page.base_page import BasePage class Screen(BasePage): _img_check_code = "/hierarchy/android.widget.FrameLayout/android.widget.LinearLayout/android.widget.FrameLayout/android.widget.RelativeLayout/android.widget.FrameLayout/android.webkit.WebView/android.webkit.WebView/android.widget.Image" def get_part_screen(self): # 截图图片保存至固定的位置 img_folder = 'E:\\study\\Fork\\Weibo_Demo\\Weibo\\image\\' times = time.strftime('%Y%m%d%H%M', time.localtime(time.time())) screen_save_path = img_folder + times + '.png' self.find_element_by_xpath(self._img_check_code).screenshot(screen_save_path) # 实例化ImageRecognition,传入需要识别的图片位置 ir = ImageRecognition(screen_save_path) result = ir.ocr() return result 请注意,以上代码仅为示例,具体的实现可能会因应用的特定情况而有所不同。您可能需要根据您的应用程序的实际情况进行适当的调整和修改。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值