当前位置:   article > 正文

Selenium自动化测试实战 —— 自动侦测浏览器版本并下载对应的浏览器驱动_自动化测试浏览器驱动

自动化测试浏览器驱动

前天在群里聊天时,有同学说 Appium 官方支持自动下载兼容的浏览器驱动,想来Selenium也有类似的方法,于是在网上搜索一番。参考了Medium上一篇文章的方法,对相关步骤进行改进,增加了对多浏览器的支持。

首先,先想好大致上的几个步骤

  1. 识别本地浏览器版本
  2. 下载对应浏览器版本的驱动
  3. 解压到对应文件夹
  4. 记录到mapping.json文件中

接下来就是撸起袖子开干

定义好目录结构

|— config
|— mapping.json: 浏览器驱动配置信息
|— driver: 存放浏览器驱动
|— utils
|— driver_util.py: 封装的工具包
|— test_search.py: 测试脚本

数据准备

导入第三方库,定义好路径名称等常量

  1. import json
  2. import os
  3. import zipfile
  4. import shutil
  5. import requests
  6. import pathlib
  7. from win32com import client as win_client
  8. # 工作目录(当前路径调试时需加上.parent)
  9. BASE_DIR = str(pathlib.Path.cwd())
  10. # BASE_DIR = str(pathlib.Path.cwd().parent)
  11. CHROME_DRIVER_BASE_URL = "https://chromedriver.storage.googleapis.com"
  12. EDGE_DRIVER_BASE_URL = "https://msedgedriver.azureedge.net"
  13. CHROME_DRIVER_ZIP = "chromedriver_win32.zip"
  14. EDGE_DRIVER_ZIP = "edgedriver_win64.zip"
  15. CHROME_DRIVER = "chromedriver.exe"
  16. EDGE_DRIVER = "msedgedriver.exe"
  17. BROWSER_DRIVER_DIR = str(pathlib.PurePath(BASE_DIR, "driver"))
  18. DRIVER_MAPPING_FILE = os.path.join(BASE_DIR, "config", "mapping.json")

第一步,获取浏览器的版本

Chrome 浏览器有些小版本没有对应版本号的浏览器驱动,需要借助 Query API 查询对应大版本LATEST RELEASE版本,再根据查询对应的浏览器驱动

新版Edge 浏览器每个版本号官网都有对应的驱动下载

  1. Latest Version API
  2. https://chromedriver.storage.googleapis.com/LATEST_RELEASE_{version}Download Chrome Driver
  3. API
  4. https://chromedriver.storage.googleapis.com/{version}/chromedriver_win32.zip
  5. https://msedgedriver.azureedge.net/{version}/edgedriver_win64.zip

代码如下

  1. def get_browser_version(file_path):
  2. """
  3. 获取浏览器版本
  4. :param file_path: 浏览器文件路径
  5. :return: 浏览器大版本号
  6. """
  7. # 判断路径文件是否存在
  8. if not os.path.isfile(file_path):
  9. raise FileNotFoundError(f"{file_path} is not found.")
  10. win_obj = win_client.Dispatch('Scripting.FileSystemObject')
  11. version = win_obj.GetFileVersion(file_path)
  12. return version.strip()
  13. def get_browser_major_version(file_path):
  14. """
  15. 获取浏览器大版本号
  16. :param file_path: 浏览器文件路径
  17. :return: 浏览器大版本号
  18. """
  19. browser_ver = get_browser_version(file_path)
  20. browser_major_ver = browser_ver.split(".")[0]
  21. return browser_major_ver
  22. def get_latest_browser_version(browser_major_ver):
  23. """
  24. 获取匹配大版本的最新release版本
  25. :param browser_major_ver: 浏览器大版本号
  26. :return: 最新release版本号
  27. """
  28. latest_api = f"{CHROME_DRIVER_BASE_URL}/LATEST_RELEASE_{browser_major_ver}"
  29. resp = requests.get(latest_api)
  30. latest_driver_version = resp.text.strip()
  31. return latest_driver_version

第二步,下载浏览器驱动

  1. def download_browser_driver(latest_driver_version, browser_name):
  2. """
  3. 下载浏览器驱动压缩包
  4. :param browser_name: 浏览器名称
  5. :param latest_driver_version: 浏览器的版本号
  6. """
  7. download_api = None
  8. if browser_name == "Chrome":
  9. download_api = f"{CHROME_DRIVER_BASE_URL}/{latest_driver_version}/{CHROME_DRIVER_ZIP}"
  10. elif browser_name == "Edge":
  11. download_api = f"{EDGE_DRIVER_BASE_URL}/{latest_driver_version}/{EDGE_DRIVER_ZIP}"
  12. download_dir = os.path.join(str(BROWSER_DRIVER_DIR), os.path.basename(download_api))
  13. # 下载,设置超时时间20s
  14. resp = requests.get(download_api, stream=True, timeout=20)
  15. if resp.status_code == 200:
  16. with open(download_dir, 'wb') as fo:
  17. fo.write(resp.content)
  18. else:
  19. raise Exception("Download chrome driver failed")

第三步,解驱动压缩包

解压后将原压缩包删除

  1. def unzip_driver(browser_major_ver, browser_name):
  2. """
  3. 解压驱动压缩包
  4. :param browser_name: 浏览器名称
  5. :param browser_major_ver: 浏览器大版本号
  6. :return: 驱动文件路径
  7. """
  8. file_path = None
  9. driver_path = None
  10. if browser_name == "Chrome":
  11. file_path = os.path.join(BROWSER_DRIVER_DIR, os.path.basename(CHROME_DRIVER_ZIP))
  12. driver_path = os.path.join(BROWSER_DRIVER_DIR, browser_major_ver, CHROME_DRIVER)
  13. elif browser_name == "Edge":
  14. file_path = os.path.join(BROWSER_DRIVER_DIR, os.path.basename(EDGE_DRIVER_ZIP))
  15. driver_path = os.path.join(BROWSER_DRIVER_DIR, browser_major_ver, EDGE_DRIVER)
  16. browser_driver_dir = os.path.join(BROWSER_DRIVER_DIR, browser_major_ver)
  17. # 解压到指定目录
  18. with zipfile.ZipFile(file_path, 'r') as zip_ref:
  19. zip_ref.extractall(browser_driver_dir)
  20. return driver_path
  21. def remove_driver_zip(browser_name):
  22. """
  23. 删除下载的驱动压缩包
  24. :param browser_name: 浏览器名称
  25. """
  26. file_path = None
  27. if browser_name == "Chrome":
  28. file_path = os.path.join(BROWSER_DRIVER_DIR, os.path.basename(CHROME_DRIVER_ZIP))
  29. elif browser_name == "Edge":
  30. file_path = os.path.join(BROWSER_DRIVER_DIR, os.path.basename(EDGE_DRIVER_ZIP))
  31. os.remove(file_path)

第四步,读写配置文件信息

  1. def read_driver_mapping_json():
  2. """
  3. 读取 mapping_json
  4. :return: 字典格式
  5. """
  6. if os.path.exists(DRIVER_MAPPING_FILE):
  7. with open(DRIVER_MAPPING_FILE) as fo:
  8. try:
  9. driver_mapping_dict = json.load(fo)
  10. # mapping.json内容为空时,返回空字典
  11. except json.decoder.JSONDecodeError:
  12. driver_mapping_dict = {}
  13. else:
  14. raise FileNotFoundError(f"{DRIVER_MAPPING_FILE} is not found")
  15. return driver_mapping_dict
  16. def write_driver_mapping_json(browser_major_ver, latest_driver_version, driver_path, browser_name):
  17. """
  18. 写入 mapping_json
  19. :param browser_major_ver: 浏览器大版本号
  20. :param latest_driver_version: 浏览器驱动版本号
  21. :param driver_path: 驱动存放路径
  22. :param browser_name: 浏览器名称
  23. """
  24. mapping_dict = read_driver_mapping_json()
  25. # 版本号在dict中(浏览器名不在dict中)
  26. if browser_major_ver in mapping_dict:
  27. mapping_dict[browser_major_ver][browser_name] = {
  28. "driver_path": driver_path,
  29. "driver_version": latest_driver_version
  30. }
  31. # 大版本号不在dict中,且字典不为空
  32. elif browser_major_ver not in mapping_dict and mapping_dict:
  33. mapping_dict[browser_major_ver] = {
  34. browser_name:
  35. {
  36. "driver_path": driver_path,
  37. "driver_version": latest_driver_version
  38. }
  39. }
  40. # 字典为空
  41. else:
  42. mapping_dict = {
  43. browser_major_ver:
  44. {
  45. browser_name:
  46. {
  47. "driver_path": driver_path,
  48. "driver_version": latest_driver_version
  49. }
  50. }
  51. }
  52. mapping_dict.update(mapping_dict)
  53. with open(DRIVER_MAPPING_FILE, 'w') as fo:
  54. json.dump(mapping_dict, fo)

综合

将以上步骤整合到automatic_discover_driver函数中,通过调用该函数返回浏览器驱动路径

  1. def automatic_discover_driver(browser_path, browser_name="Chrome"):
  2. """
  3. 侦测浏览器驱动是否在mapping.json有记录,否则下载该驱动
  4. :param browser_path: 浏览器路径
  5. :param browser_name: 浏览器名称
  6. """
  7. browser_maj_ver = get_browser_major_version(browser_path)
  8. # Chrome需要获取大版本号对应的latest release version
  9. # Edge 可直接用当前浏览器版本号
  10. if browser_name == "Chrome":
  11. latest_browser_ver = get_latest_browser_version(browser_maj_ver)
  12. elif browser_name == "Edge":
  13. latest_browser_ver = get_browser_version(browser_path)
  14. else:
  15. raise Exception(f"{browser_name} is not found")
  16. # 读取mapping.json内容
  17. mapping_dict = read_driver_mapping_json()
  18. # json为空 或版本号不在mapping_dict中 或浏览器名不在mapping_dict中
  19. if not mapping_dict or \
  20. browser_maj_ver not in mapping_dict or \
  21. browser_name not in mapping_dict[browser_maj_ver]:
  22. # 下载浏览器驱动压缩包
  23. download_browser_driver(latest_browser_ver, browser_name)
  24. # 解压浏览器驱动压缩包,并返回驱动路径
  25. driver_path = unzip_driver(browser_maj_ver, browser_name)
  26. # 将浏览器大版本号、浏览器名、驱动路径、对应的浏览器版本号信息写入到mapping.json中
  27. write_driver_mapping_json(browser_maj_ver, latest_browser_ver, driver_path, browser_name)
  28. # 删除浏览器驱动压缩包
  29. remove_driver_zip(browser_name)
  30. # 返回浏览器驱动的路径
  31. mapping_dict = read_driver_mapping_json()
  32. return mapping_dict[browser_maj_ver][browser_name]["driver_path"]

测试

创建一个test_search.py文件验证是否可以自动下载对应的浏览器驱动

  1. import pytest
  2. from time import sleep
  3. from selenium import webdriver
  4. from utils.driver_util import automatic_discover_driver as automatic
  5. class TestSearch:
  6. _CHROME_PATH = r"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe"
  7. _EDGE_PATH = r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe"
  8. _browser = "Edge"
  9. def setup(self):
  10. driver_path = automatic(self._EDGE_PATH, self._browser)
  11. if self._browser == "Chrome":
  12. self.driver = webdriver.Chrome(driver_path)
  13. elif self._browser == "Edge":
  14. self.driver = webdriver.Edge(driver_path)
  15. def teardown(self):
  16. self.driver.close()
  17. self.driver.quit()
  18. def test_search_bing(self):
  19. self.driver.get("https://cn.bing.com/")
  20. self.driver.find_element_by_id("sb_form_q").send_keys("selenium")
  21. self.driver.find_element_by_id("sb_go_par").click()
  22. sleep(3)
  23. if __name__ == '__main__':
  24. pytest.main()

实测,成功打开浏览器!

最后: 为了回馈铁杆粉丝们,我给大家整理了完整的软件测试视频学习教程,朋友们如果需要可以自行免费领取 【保证100%免费】

软件测试面试文档

我们学习必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有字节大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/925989
推荐阅读
相关标签
  

闽ICP备14008679号