记录Selenium自动化测试过程中接口的调用信息

上一篇博客,我写了python自动化框架的一些知识和粗浅的看法,在上一篇中我也给自己提出一个需求:如果记录在测试过程中接口的调用情况?提出这个需求,我觉得是有意义的。你在测试过程中肯定会遇到一些莫名其妙的问题,比如:web某个页面一直在刷进度条,导致你定位元素失败,但是,你再手动操作一遍可能无法复现....对于我们来说,肯定会遇到许多类似的问题。你会发现有时候仅仅靠一张截图,你远远找不到bug的原因。这时候,我在想如果我能拿到这一系列操作所调用的接口信息多好,我就能明白为什么发生这种问题了。比如一直在刷进度条我觉得有几种情况:1.后端一直在等待某个接口的响应信息。2.网络原因导致,接口响应很慢(局域网一般很少出现这类问题)、3.前端工程师没有动态的把这个进度条display="None"....不论何种原因,我拿到相关的接口信息,就能对错误逐个排除。比如我发现某个接口的响应时间很长.....或者所有接口的响应的时间多是大于1s的,又或者都正常响应,原来js没有动态改变进度的属性?反正无论如何我拿到自动化操作的接口信息是没有坏处的吧?(小小的缺点我后面提到)

那么问题是,我们如何精准的拿到这些信息?我开始的想法是通过firebug去拿,firebug我们平时用的也比较多,可以方便的看到控制台信息(js的执行情况)和网络信息(接口调用情况),但是我查了很多资料都没有办法完整的把这些信息给导出来....但是,我很快的想到了Fiddler。Fiddler是目前为止我用的最好最顺手的一款http抓包工具(不要和我提什么wireshark,虽然经过网卡的信息它都能抓但是仅对http协议来说,真不如fiddler牛逼,谁用谁知道),更重要的是由于它是个代理服务器,所以能抓任何设置其为代理的终端,包括手机...想到这,心中一阵窃喜。下面我先说说思路,然后再详细的说明,我是怎么做的。我的思路如下:

1.设置fiddler过滤一下抓取信息,如:只抓取host为:*.csdn.net的接口信息。

2.测试执行开始前,打开fiddler。

3.当执行一个test时,先在fiddler控制台输入cls,清空当前sessions,防止接口信息过多或混在一起不方便排查错误。

4.当执行test完毕,如果有错误,则保存此test执行过程中的所有sessions至一个文件夹。无错误不做操作(如果你非要保存也是可以的)

5.重复2-3的步骤,直至所有测试结束。

6.测试执行结束后,关闭fiddler。

上面的想法,其实也是很简单的,我们再一个个看看如何实现:

对于步骤1/2/5  用python调用控制台打开fiddler是有问题的(主进程会阻塞,其他应用程序没问题),改用AutoIt的run方法,关闭没问题。

对于3/4是要想想办法的。对于自动化人员来说AutoIt您应该是接触过了,如果没有就去看看吧!AutoIt有弊端有优点,最大的优点就是编写简单、脚本能转换成exe.最大的缺点:windows非标准控件无法获取。万幸的是Fiddler的控制台输入框能被AutoIt识别!还有就是如何改写Fiddler的Scripts。(我们的需求很简单,别被吓到了)

所以第一步:我们编写清除fiddler session的脚本,转换成C_interface.exe。脚本简单到不能简单了,如下:

1

2

3

4

5

6

7

8

Example()

Func Example()

    Local $hWnd = WinWait("[Title:Telerik Fiddler Web Debugger]", "", 10)

    WinActivate($hWnd);激活当前窗口

    ControlFocus($hWnd, "","[CLASS:WindowsForms10.EDIT.app.0.141b42a_r6_ad1;NAME:txtExec]")

    ControlSetText($hWnd, "", "[CLASS:WindowsForms10.EDIT.app.0.141b42a_r6_ad1;NAME:txtExec]","cls")

    Send("{ENTER}")

 EndFunc   ;

 照顾一下,刚开始看AutoIt的同学,Title中的Telerik Fiddler Web Debugger与ControlFocus中的CLASS、NAME是通过AutoIt Window info这个工具捕捉的,我们的可能不一样贴图一张:

我们写完了了清除session后,再来写下保存接口信息的脚本,也很简单保存为D_interface.exe:

Example()
Func Example()Local $parment=$CmdLine[1];接受控制台数据,$parment为fiddler接口保存路径Local $hWnd = WinWait("[Title:Telerik Fiddler Web Debugger]", "", 10)WinActivate($hWnd);激活当前窗口ControlFocus($hWnd, "","[CLASS:WindowsForms10.EDIT.app.0.141b42a_r6_ad1;NAME:txtExec]")ControlSetText($hWnd, "", "[CLASS:WindowsForms10.EDIT.app.0.141b42a_r6_ad1;NAME:txtExec]","dump "&$parment)Send("{ENTER}")IF WinActive("[Title:Cannot Save SAZ]") ThenControlClick("[Title:Cannot Save SAZ]","","Button1")EndIf
EndFunc   ;

标红部分的解释是:当Fiddler没有session时(虽然不太可能出现这种情况),执行dump命令会弹出个对话框,这时候要关闭对话框!!如果不关闭的话下面对fiddler的操作会出现问题,因为这时候弹出框是fiddler的顶级窗口,可能导致脚本中使用Enter键无效...

其次,由于python调用控制台启动Fiddler有问题(具体问题原因未知),所以我们也用AutoIt编写,并转换成S_interface.exe:

1

2

3

4

5

Example()

Func Example()

    Local $parment=$CmdLine[1]

    Run($parment)

EndFunc   ;

最后,我们改下Fiddler的Script的,从菜单的Rules->Customer Rules打开脚本剪辑器,直接拉到script的末端修改方法OnExecAction如下:

  ......case "dump":UI.actSelectAll();var bpMethod = sParams[1]//UI.actSaveSessionsToZip(CONFIG.GetPath("Captures") + "dump.saz");UI.actSaveSessionsToZip(bpMethod)FiddlerObject.StatusText = "Dumped all sessions to " +bpMethod;//FiddlerObject.alert(bpMethod);UI.actRemoveAllSessions();return true;

修改case 'dump'的情况,bpMethod是由命令bump空格后的参数。对应于上文我们AutoIt脚本中的$parment参数(由控制台输入)。

上面我们的准备工作的做的差不多了,总结一下,干了下面的几个事情:

1.用AutoIt生成了清除Fiddler session的一个exe

2.用AutoIt生成了保存Fiddler session的一个exe

3.修改了Fiddler的Script接受一个保存session路径的一个参数

在完成了以上工作后,我们来进行测试!注意:在此之前我们要明白一些事情:

1.用Fiddler做代理后,可能影响接口的加载速度,毕竟有个第三者。但是我觉得速度影响在web自动化上不是那么重要的事情,毕竟现实中的访问速度肯定比你公司内部访问速度更差。(缺点之一)

2.用Fiddler做代理后,我们知道在访问https的时候比如访问百度,可能显示非安全链接,我们平常的做法是把fiddler的证书导入浏览器(具体百度上有说明),但是我们webdriver启动的是个空白的浏览器,如何能自动加载Fiddler证书?

3.用Fiddler做代理后,如果Fiddler崩溃或者没启动起来造成无法联网导致所有脚本无法运行,这个风险我们如何规避?

第一个问题跳过,我们看看第二个问题

在路径C:\Python27\Lib\site-packages\selenium\webdriver\firefox\firefox_profile.py下定义了一个FirefoxProfile类,这个类我们平时可能不太用的上,但是用不上不代表他不重要,这个类是个管理浏览器插件的类。我们说明一下:

1.其构造函数传火狐浏览器的插件路径。火狐浏览器的插件一般在C:\Users\***\AppData\Roaming\Mozilla\Firefox\Profiles\****.default-*****"这个路径下面。构造函数会把这个路径下的东西copy到c:\\users\\pf-211x3\\appdata\\local\\temp\\***\\webdriver-py-profilecopy这个文件夹下。

2.encoded函数。这个函数的文档属性这样解释:"A zipped, base64 encoded string of profile directory for use with remote WebDriver JSON wire protocol"具体很么意思呢?就是这个函数会把上文中我们提到的c:\\users\\pf-211x3\\appdata\\local\\temp\\***\\webdriver-py-profilecopy这个文件夹压缩成ZIP格式文件,然后对这个文件进行base64的编码,当启动浏览器的时候,会将这个编码一同发给服务器,服务器再对他base64解码、解压缩将您本地火狐插件完完整整的复制到新启动的空白浏览器上,那么我们新启动的浏览器就拥有了本地浏览器所有的插件了。

3.set_preference。传递一个键值对,就是设置火狐浏览器的选项,比如设置代理等等....

4.add_extension。传递一个***.xpi的路径,就是设置浏览器加载的插件,比如启动浏览器加载firebug,把firebug插件路径传递给add_extension即可

经过我对FirefoxProfile类的说明,您大概知道了问题二的解决办法了吧,对的就是向FirefoxProfile类中传递插件的路径。但是C:\Users\***\AppData\Roaming\Mozilla\Firefox\Profiles\****.default-*****"这个文件是比较大的反正我的是50M,将这样一个大的文件经过步骤2的操作,是个费事费力的事情。所以你们会发现,如果把完整的插件路径传递给FirefoxProfile,经过一系列的压缩、传递,启动本地浏览器会非常非常慢!经过排除和尝试法,我发现火狐对证书的控制是由插件文件夹下的cert8.db控制的,所有我们把这个文件给拷贝出来放在一个文件夹中,单独传这个文件夹路径即可。

第三个问题:

浏览器的代理有几下几种:1.不使用代理。2.自动检测此网络的代理设置。3.使用系统代理。4.手动配置代理。5,自动代理配置

对于1和4大家都明白;对于5也还好就是:写一个脚本告诉浏览器什么样的域名我要代理,其他的不使用代理(具体百度);对于2和3我多少有点不知道他怎么用,对于3使用系统代理我的实践就是如果我启动了fiddler它就使用了fiddler代理,如果没有启动就不使用代理,看起来挺智能了。我也不太清楚这样为什么...所以对于问题三我也是纠结的:第一、如果设置手动代理看起来是没问题的,就怕fiddler故障了,然后雪崩...第二、我着实不太了解我使用系统代理对不对?这个大家自己看好了。我反正就用系统代理了,至少能满足我的想法:万一fiddler故障了也没啥,大不了就抓不到接口数据呗,其他的还能正常的跑....最后,就是在我们上篇继承unnitest的run方法里面,修改一点点代码,也很简单(红色标识了):


......
def run(self, result=None):orig_result = resultif result is None:result = self.defaultTestResult()startTestRun = getattr(result, 'startTestRun', None)if startTestRun is not None:startTestRun()self._resultForDoCleanups = resultscreenshot_path=getattr(result,"screenshot_path",False)dir_name = os.path.dirname(__file__) # 当前脚本根目录#因为fiddler保存尽量要使用绝对路径,如果使用相对路径会保存到安装目录下,这是我们不希望的sessiong_path = dir_name + "/" + "Error_session"#默认session保存路径if not screenshot_path:screenshot_path=self.__screenshot_pathelse:if os.path.dirname(screenshot_path):#如果是绝对路径sessiong_path=os.path.dirname(screenshot_path)+"/Error_session"#拿到运行test的根目录+FiddlerSessionsresult.startTest(self)testMethod = getattr(self, self._testMethodName)if (getattr(self.__class__, "__unittest_skip__", False) orgetattr(testMethod, "__unittest_skip__", False)):# If the class or method was skipped.try:skip_why = (getattr(self.__class__, '__unittest_skip_why__', '')or getattr(testMethod, '__unittest_skip_why__', ''))self._addSkip(result, skip_why)finally:result.stopTest(self)returntry:success = Falsetry:self.setUp()except SkipTest as e:self._addSkip(result, str(e))except KeyboardInterrupt:raiseexcept:result.addError(self, sys.exc_info())#启动setUp失败直接判断出错else:try:testMethod()except KeyboardInterrupt:raiseexcept (self.failureException,exceptions.WebDriverException):#如果是断言错误或WebDriverException,类型为fail,且增加截图#增加截图browser=self.getbrowser()#尝试拿浏览器实例if browser:filename=self.__class__.__name__+"_"+self._testMethodName+".png"#格式:类名+方面名称browser.get_screenshot_as_file(screenshot_path+"\\"+filename)reback_filename=filenameelse:reback_filename=None#保存sessions数据sessionfile_name=self.__class__.__name__+"_"+self._testMethodName+"_err.saz"#注意格式是sazos.popen(dir_name+"/"+"Tools/D_interface.exe "+sessiong_path+"\\"+sessionfile_name)#控制台运行D_interface.exe由AutoIt生成,保存出错的sessionresult.addFailure(self, sys.exc_info(),reback_filename)#回传截图名称给report,以便能显示在报告中except SkipTest as e:#如果为跳过的异常,类型为Skip异常

最后我的demo文档结构大概是这样的:

其中Error_session是保存错误的session;FireFox_profile是我们说到的火狐证书插件;Tools是我们转换的3个简单的exe程序;screen_shot存放错误截图;IqunxingTest.py是我们改写的unnitest类,我们新建测试demo脚本:

#coding=utf-8
import IqunxingTest
import HTMLTestRunner
import sys,os
import unittest
from  selenium import webdriver
from  selenium.webdriver.firefox import firefox_profile
import time
dir_name = os.path.dirname(__file__)  # 拿到根目录
class Mydemo(IqunxingTest.IqunxingTest):u'''测试CSDN登录'''@classmethoddef setUpClass(cls):profile=firefox_profile.FirefoxProfile(profile_directory=dir_name+"/FireFox_profile")profile.set_preference("network.proxy.type", 5)#将浏览器代理设置为系统代理cls.browser=webdriver.Firefox(firefox_profile=profile)#启动带插件的浏览器cls.browser.implicitly_wait(10)@unittest.Myskipdef test1(self):u'''打开csdn'''browser=self.browserbrowser.get("http://www.csdn.net/")@unittest.Myskipdef test2(self):u'''csdn登录'''os.popen(dir_name+"/"+"Tools/C_interface.exe")#在test开始前,清空Fiddler session信息browser = self.browserbrowser.find_element_by_link_text(u"登录").click()time.sleep(1)browser.find_element_by_id("username").send_keys("test")time.sleep(1)browser.find_element_by_id("password").send_keys("test")time.sleep(1)browser.find_element_by_class_name("logging").click()#点击登录if not browser.find_element_by_class_name("phr_first").is_displayed():#如果没有登录成功是找不到这个控件会报错self.assertTrue(False,"login failed")
if __name__ == '__main__':fiddler_path = "C:\Program Files (x86)\Fiddler2\Fiddler.exe"#您的Fiddler路径s = os.popen(dir_name + "/Tools/S_interface.exe " + "\"" + fiddler_path + "\"")#启动Fiddermodule_name=os.path.basename(sys.argv[0]).split(".")[0]module=__import__(module_name)runner=HTMLTestRunner.HTMLTestRunner("reprot.html")all_suite=unittest.defaultTestLoader.loadTestsFromModule(module)runner.run(all_suite)os.popen('''taskkill /f /im "Fiddler.exe"''')#测试完成后关闭fiddler

因为我们要找一些有用的sesssion信息,可喜的是Fiddler能过滤一些你设置完的信息,我的过滤信息如下:

因为测试CSDN,所以我只展示域名为*.csdn.net的会话;另外,一些css,js,png等无用信息我也隐藏了(正则表达式隐藏)。好了万事具备,我们运行下这个demo:最后在Error_session下保存了我们test2操作的所有http信息文件名为:Mydemo_test2_err.saz(过滤的除外),同时在screen_shot下保存错误的截图。我们直接用fiddler打开这个saz文件:

从上面的截图可以看出来,我们保存的session是完整的(过滤的除外)。而且我们看到了我们点击登录时,使用的接口以及传递的相关信息。当然,我们点击Fiddler其他标签事能获取一切我们想获取的信息。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/11981.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【JAVA】 String 类简述笔记

个人主页:【😊个人主页】 系列专栏:【❤️初识JAVA】 文章目录 前言String类创建一个String类 常用方法字符串长度 length() 方法连接字符串 concat() 方法创建格式化字符串 format()功能 前言 string是C、java、VB等编程语言中的字符串&…

行星碰撞(力扣)栈 JAVA

给定一个整数数组 asteroids,表示在同一行的行星。 对于数组中的每一个元素,其绝对值表示行星的大小,正负表示行星的移动方向(正表示向右移动,负表示向左移动)。每一颗行星以相同的速度移动。 找出碰撞后剩…

unity进阶--xml的使用学习笔记

文章目录 xml实例解析方法一解析方法二 xml-path创建xml文档 xml实例 解析方法一 解析方法二 xml-path 创建xml文档

C++数据结构笔记(11)二叉树的#号创建法及计算叶子节点数

首先分享一段计算叶子节点数目的代码,如下图: 不难发现,上面的二叉树叶子节点数目为4。我们可以采用递归的方式,每当一个结点既没有左结点又没有右节点时,即可算为一个叶子结点。 int num0; //全局变量,代…

MyBatis-入门-快速入门程序

本次使用MyBatis框架是基于SpringBoot框架进行的,在IDEA中创建一个SpringBBot工程,根据自己的需求选择对应的依赖即可 快速入门 需求:使用MyBatis查询所有用户数据步骤: 准备工作(创建Spring Boot工程、数据库user表…

【误差自适应跟踪方法AUV】自适应跟踪(EAT)方法研究(Matlab代码Simulin实现)

目录 💥1 概述 📚2 运行结果 🎉3 参考文献 🌈4 Matlab代码、Simulink模型、文献 💥1 概述 摘要:跟踪问题(即如何遵循先前记忆的路径)是移动机器人中最重要的问题之一。根据机器人状…

机器学习深度学习——线性回归的从零开始实现

虽然现在的深度学习框架几乎可以自动化实现下面的工作,但从零开始实现可以更了解工作原理,方便我们自定义模型、自定义层或自定义损失函数。 import random import torch from d2l import torch as d2l线性回归的从零开始实现 生成数据集读取数据集初始…

windows默认编码格式修改

1.命令提示符界面输入 chcp 936 对应 GBK 65001 对应 UTF-8 2.临时更改编码格式 chcp 936(或65001) 3.永久更改编码格式 依次开控制面板->时钟和区域->区域->管理->更改系统区域设置,然后按下图所示,勾选使用UTF-8语言支持。然后重启电脑。此…

防止连点..

1.连点js文件 let timer; letflag /*** 节流原理:在一定时间内,只能触发一次** param {Function} func 要执行的回调函数* param {Number} wait 延时的时间* param {Boolean} immediate 是否立即执行* return null*/ function throttle(func, wait 500…

【数字IC基础】竞争与冒险

竞争-冒险 1. 基本概念2. 冒险的分类3. 静态冒险产生的判断4. 毛刺的消除使用同步电路使用格雷码增加滤波电容增加冗余项,消除逻辑冒险引入选通脉冲 1. 基本概念 示例一: 如上图所示的这个电路,使用了两个逻辑门,一个非门和一个与…

Windows 找不到文件‘chrome‘。请确定文件名是否正确后,再试一次

爱像时间,永恒不变而又短暂;爱像流水,浩瀚壮阔却又普普通通。 Windows 找不到文件chrome。请确定文件名是否正确后,再试一次 如果 Windows 提示找不到文件 "chrome",可能是由于以下几种原因导致的&#xff1…

机器学习深度学习——模型选择、欠拟合和过拟合

👨‍🎓作者简介:一位即将上大四,正专攻机器学习的保研er 🌌上期文章:机器学习&&深度学习——多层感知机的简洁实现 📚订阅专栏:机器学习&&深度学习 希望文章对你们有…

【GitOps系列】使用 ArgoCD 快速打造GitOps工作流

文章目录 ArgoCD简介ArgoCD安装访问ArgoCDGitOps 工作流总览创建 ArgoCD 应用检查 ArgoCD 同步状态访问应用 连接 GitOps 工作流体验 GitOps 工作流生产建议1)修改默认密码2)配置 Ingress 和 TLS3)使用 Webhook 触发 ArgoCD4)将源…

DoIP学习笔记系列:(二)VN5620 DoIP测试配置实践笔记

文章目录 1. 添加.cdd2. CAPL中调用接口发送DoIP请求3. “Ethernet Packet Builder”的妙用4. CANoe也可以做交互界面在进行测试前,先检查车载以太网硬件连线是否正确,需要注意连接两端的Master、Slave,100M、1000M等基本情况,在配置VN5620的时候就可以灵活处理了。成功安装…

数学建模-MATLAB三维作图

导出图片用无压缩tif会更清晰 帮助文档:doc 函数名 matlab代码导出为PDF 新建实时脚本或右键文件转换为实时脚本实时编辑器-全部运行-内嵌显示保存为PDF

【TypeScript】接口类型 Interfaces 的使用理解

导语: 什么是 类型接口? 在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement&#x…

JVM-类加载

1.了解冯诺依曼计算机结构 1.1计算机处理数据过程 (1)提取阶段:由输入设备把原始数据或信息输入给计算机存储器存起来 (2)解码阶段:根据CPU的指令集架构(ISA)定义将数值解译为指令 (3)执行阶段:再由控制器把需要处理或计算的数据调入运算器 (4)最终阶段:由输出设备把最后运…

区间预测 | MATLAB实现基于QRF随机森林分位数回归时间序列区间预测模型

区间预测 | MATLAB实现基于QRF随机森林分位数回归时间序列区间预测模型 目录 区间预测 | MATLAB实现基于QRF随机森林分位数回归时间序列区间预测模型效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现基于QRF随机森林分位数回归时间序列区间预测模型&#xff1…

Dooring-Saas低代码技术详解

hello, 大家好, 我是徐小夕, 今天和大家分享一下基于 H5-Dooring零代码 开发的全新零代码搭建平台 Dooring-Saas 的技术架构和设计实现思路. 背景介绍 3年前我上线了第一版自研零代码引擎 H5-Dooring, 至今已迭代了 300 多个版本, 主要目的是快速且批量化的生产业务/营销过程中…

empty module导致的lvs问题

write_verilog时-exclude empty_modules即可 这里也分享一下ICC2 write lvs netlist的命令 write_verilog -exclude {scalar_wire_declarations leaf_module_declarations empty_modules well_tap_cells filler_cells supply_statements} -hierarchy all -force_no_referenc…