• python+pytest+selenium自动化测试图片搜索功能


    介绍

    图片搜索是现在的多数浏览器都提供的功能,如果能用脚本实现一个自动化的检查,那么能够实现发版前的简单冒烟,或者日常的功能检查。

    思路

    针对PC网页端的浏览器的图片搜索功能进行编写脚本,
    首先就是要确定用的语言框架及工具:Python+pytest+selenium,
    其次是了解整个功能的流程:上传图片->开始搜索->结果验证,
    最后搞清楚每个关键节点上会用到的相关组件或方法,开始coding。

    难点及解决方式

    1.对动态元素的定位
    在做自动化的过程中,我喜欢先找到要操作的页面元素,然后根据其特性来决定定位方式。
    如下,前四个都是能够很容易定位到的元素,title是搜索结果的文章页,是一个动态元素,这个时候需要借用到谷歌开发者工具来对其进行调试确定最后的定位路径,这里我用到了xpath提供的模糊匹配的方法contains()。

     # 定义页面元素
        img_search = "soutu-btn"  # by class name
        choose_img = "upload-pic"  # by class name
        search = "soutu-url-btn soutu-url-btn-new"
        result_div = '//*[@id="app"]/div/div[2]/div/div[2]/div[3]/div/a'  # by xpath
        title = '//*[@id="ssr-content"]//div[starts-with(@class,"app-module")][2]//div[contains(@class,"index-module")]//div[contains(@class,"index-module")][1]'   # xpath  
        guide = "graph-guide-info-btn"  # class name
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    2.处理弹窗
    多次尝试的过程中,发现搜索结果页会随机出现引导弹窗,类似下面这种,因为是随机出现的,所以在处理逻辑中要做判断,弹窗是否出现,出现就处理掉
    在这里插入图片描述

    3.如何对结果进行断言
    对图片搜索结果进行断言,我首先想到了截图保留证据,这样也方便后期出问题验证。然后意识到,如果是做数据驱动,那是不是需要给上传的每个图片加个属性,来标识其内容特点,如猫,狗,人等。然后在断言的时候把结果内容与其进行比较。
    所以我选择了搜索结果中的第一个结果来做点击操作,来获取其标题中的相关内容进行断言。

    实现

    import pytest
    from selenium import webdriver
    from selenium.common import TimeoutException
    from selenium.webdriver.chrome.service import Service
    from selenium.webdriver.common.by import By
    from time import sleep, strftime, localtime, time
    from selenium.webdriver.support import expected_conditions as EC
    from selenium.webdriver.support.wait import WebDriverWait
    
    class TestSearchImg:
    
        url = "https://www.baidu.com"
    
        s = Service(executable_path=r'/Users/daisy/BrowserDrivers/chromedriver')
        driver = webdriver.Chrome(service=s)
    
        # 定义页面元素
        img_search = "soutu-btn"  # by class name
        choose_img = "upload-pic"  # by class name
        search = "soutu-url-btn soutu-url-btn-new"
        result_div = '//*[@id="app"]/div/div[2]/div/div[2]/div[3]/div/a'  # by xpath
        title = '//*[@id="ssr-content"]//div[starts-with(@class,"app-module")][2]//div[contains(@class,"index-module")]//div[contains(@class,"index-module")][1]'   # xpath  '//*[@id="ssr-content"]/div[2]/div/div[1]/div/div/div[1]'
        guide = "graph-guide-info-btn"  # class name
    
        title_text = ''
    
        def setup(self):
            self.driver.get(self.url)
            self.driver.fullscreen_window()
    
        def teardown(self):
            self.driver.quit()
    
        def search_img(self):
            self.driver.find_element(By.CLASS_NAME,self.img_search).click()
            self.driver.find_element(By.CLASS_NAME,self.choose_img).send_keys("/Users/daisy/PycharmProjects/Test/PccwGlobal/part1/cat.png")
            sleep(5)
            # 获取当前窗口的句柄
            origin_handle = self.driver.current_window_handle
            # print("origin_handle",origin_handle)
            file_name = "search-" + strftime("%Y%m%d-%H%M%S", localtime(time())) + ".png"
            self.driver.save_screenshot(file_name)
    
            # 处理引导弹窗
            try:
                ele = WebDriverWait(self.driver, 10, 0.5).until(lambda x: x.find_element(By.XPATH, self.result_div))
            except TimeoutException:
                if self.driver.find_element(By.CLASS_NAME,self.guide):
                    self.driver.find_element(By.CLASS_NAME, self.guide).click()
            self.driver.execute_script("arguments[0].scrollIntoView();", ele)
            self.driver.execute_script("arguments[0].click();", ele)
            sleep(5)
            # 跳到新窗口,获取所有句柄
            handles = self.driver.window_handles
            # print("All handles:", handles)
            for i in handles:
                if i != origin_handle:
                    self.driver.switch_to.window(i)
            self.title_text = self.driver.find_element(By.XPATH,self.title).get_attribute('innerText')
    
            # 截图
            res_file_name = "result-" + strftime("%Y%m%d-%H%M%S", localtime(time())) + ".png"
            self.driver.save_screenshot(res_file_name)
    
        def test_search_img(self):
            self.search_img()
            assert '猫' in str(self.title_text)
    
    
    if __name__ == '__main__':
        pytest.main()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    优化方向

    1.用PO设计模式将代码整理得更易维护。
    2.将处理弹窗的操作封装成为更通用的功能。
    3.在大批量数据处理时,如何进行更通用的断言来判断结果的正确性。

    我的断言只是简单的获取文章标题来判断其中是否有关键词,是很不通用的一种断言方式,当搜索结果中的第一结果变成了其他文章,我的这种方式就很容易失败,导致代码不够健壮。另外,如果在断言中用到一些图像处理/图像识别的方法,不知会不会是更有价值的解决方式。

    以上是短时间内处理的一个小问题,所以目标是解决眼前的问题,各处都考虑不周,后期如果有时间还会继续优化,也欢迎小伙伴们来分享更好的解决方法。

  • 相关阅读:
    多模态&多目标学习-vsn+transformer
    基于Flask的视频网站设计与实现(Python电影视频推荐系统)
    探索音频传输系统:数字声音的无限可能 | 百能云芯
    解决结构赋值中函数的this指向问题
    概率论的学习和整理--番外5:等差数列,等比数列求和,以及其他数列之和。
    leetcode:762. 二进制表示中质数个计算置位
    经验分享,xps格式转成pdf格式
    学习java的第二十二天。。。(异常)
    linux系统查看bash的history
    STM32与ZigBee无线通信技术在工业自动化中的应用
  • 原文地址:https://blog.csdn.net/Youga123/article/details/126685528