场景:
在进行UI自动化测试时解决验证码进行登录的方法有很多,比如:
设置万能验证码
手动登录后设置cookies绕过免登录
进行切图,使用pytesseract和pillow实现验证码识别(这个只能解决一些不太复杂的验证码问题,识别率很低)
切图后调用第三方AI库识别验证码(识别率高但是要花钱~~)
除了以上我们常用的方法之外,这里给大家介绍另外一种方法,通过获取接口返回数据拿到验证码code
解决:
使用BrowserMob-Proxy来实现,通过proxy访问目标网络获取到请求和返回数据来得到数据,类似于我们使用charles抓包工具
安装Browsermob-Proxy
需要java8以上环境
安装对应的python包:pip install BrowserMob-Proxy
下载解压BrowserMob-Proxy包:https://github.com/lightbody/browsermob-proxy
举例:
访问Web的登录url,获取"/getVerifyCode"接口的返回数据data作为验证码进行成功登录
配置Proxy启动WebDriver
# 开启Proxy
server = Server(r'E:\ProgramFiles\browsermob-proxy\bin\browsermob-proxy.bat')
server.start()
proxy = server.create_proxy()
chrome_options = Options()
chrome_options.add_argument('--proxy-server={0}'.format(proxy.proxy))
driver = webdriver.Chrome(chrome_options=chrome_options)
获取返回数据
# 要访问的登录页面的地址
base_url = "http://xxx/login"
# 告诉browsermobproxy需要监听记录的是响应
self.proxy.new_har("Login", options={'captureContent': True})
self.driver.get(base_url)
self.driver.maximize_window()
time.sleep(1)
result = proxy.har
for entry in result['log']['entries']:
url = entry['request']['url']
# 根据URL找到数据接口,
if "/getVerifyCode" in _url:
response = entry['response']
# 获取接口返回内容
content = response['content']["text"]
# 文本字符串转换为json对象
print json.loads(content)["data"]
server.stop()
Tips:生成har文件可以通过http://www.softwareishard.com/har/viewer/查看目录结构找到目标数据
完整代码:
import json
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from browsermobproxy import Server
import time
# 启动代理浏览器
class ProxyBrowser:
def __init__(self):
self.server = Server(r'E:\ProgramFiles\browsermob-proxy\bin\browsermob-proxy.bat')
self.server.start()
self.proxy = self.server.create_proxy()
chrome_options = Options()
chrome_options.add_argument('--proxy-server={0}'.format(self.proxy.proxy))
self.driver = webdriver.Chrome(options=chrome_options)
self.proxy.new_har("Login", options={'captureContent': True})
# 获取请求接口响应数据
def get_response_data(self, url_name):
url_name = "/" + url_name
result = self.proxy.har
for entry in result['log']['entries']:
url = entry['request']['url']
if url_name in url:
response = entry['response']
content = response['content']["text"]
return json.loads(content)
# 测试用例
def test_get_network_data():
browser = ProxyBrowser()
browser.driver.get("http://xxxx/login")
browser.driver.maximize_window()
time.sleep(2)
browser.driver.find_element_by_id("userName").send_keys("admin")
browser.driver.find_element_by_id("password").send_keys("admin")
content = browser.get_response_data("getVerifyCode")
browser.driver.find_element_by_id("rand").send_keys(content["data"])
browser.driver.find_element_by_class_name("btn").click()
time.sleep(2)
if __name__ == '__main__':
test_get_network_data()
最后:UI自动化中通过该方法获取接口数据,不仅可以解决验证码问题,同样也可以实现接口返回数据和页面数据的对比测试中~