周末实验自动化提交数据时,本来没打算写记录的,不过遇到一些问题,觉得可以提提。基本操作就不用写了,搜索过程中都发现了两个博客都出了selenium+python的书,说明操作一搜一大把。

1. 等待页面加载完成

本来用的sleep(),自己判断的有的需要时间长点就给3-4秒,时间短的页面内等待就0.5秒。但有时候网络不稳定可能需要的时间更长就会抛错。发现文档中有说:

显式等待是你在代码中定义等待一定条件发生后再进一步执行你的代码。 最糟糕的案例是使用time.sleep(),它将条件设置为等待一个确切的时间段。

尴尬=-=!

但是最后我还是采用了sleep(),以后需要优化再改吧。

一些跳转链接的地方我用了

driver.current_url来获取当前URL和预期的作对比来完成操作。

2.开左右两个窗口各占一半屏

使用maximize_window将浏览器最大化,然后用get_window_size获取到宽高。接下来就只是简单的用set_window_rect置左右窗口位置和大小了。

def start(self, align=None):
""" 配置并启动 """ option = webdriver.ChromeOptions()
option.add_argument('disable-infobars') # 无提醒
#option.add_argument('headless') # 静默运行 self.driver = webdriver.Chrome(chrome_options=option) # 置屏幕左右
if align:
# 全屏
self.driver.maximize_window()
# 获取大小
size = self.driver.get_window_size()
width = size['width']
height = size['height'] if align == 'left':
self.driver.set_window_rect(0, 0, int(width/2), height)
elif align == 'right':
self.driver.set_window_rect(int(width/2), 0, int(width/2), height)
else:
pass return self.driver

3. 多线程

上面明显是一个执行之后再另外一个,刚好需要加多线程,正好测试测试。

类中的方法加多线程试出来一种办法:

study = StudyMap('left')
study2 = StudyMap('right')
# for i in range(10):
# study.addCompleteMap() #构建线程
threads =[]
t = Thread(target=study.addCompleteMap)
threads.append(t)
t = Thread(target=study2.addCompleteMap)
threads.append(t) #启动所有线程
for t in threads:
t.start()

先初始化两个类,这个过程是单线程的,之后调用addCompleteMap方法使用多线程。ok。

想多次执行addCompleteMap函数怎么办呢,比如上面我注释掉的

for i in range(10):
study.addCompleteMap()

加个函数试试,

study = StudyMap('left')
study2 = StudyMap('right') def runx(cls):
for i in range(10):
cls.addCompleteMap() # 构建线程
threads = []
t = Thread(target=runx, args=(study,))
threads.append(t)
t = Thread(target=runx, args=(study2,))
threads.append(t) # 启动所有线程
for t in threads:
t.start()

可以的,将runx方法多线程,参数为类对象。所以不管是普通方法还是类中的成员方法,用多线程来实现没有多大区别。这不,都转了一例。具体更深入的问题,留到以后研究或者遇到了再研究吧。

4. 多线程取数据问题

上面的还有问题,业务中第二步有用数据,两个选择了同样的数据不能保存成功。以及有的页面小屏看不到确定按钮。(没打算自动化测试,只是想填数据。还真给测出了BUG)

1) 针对数据混乱问题,加锁

图:多线程调用数据重复,线程加锁前

lock = threading.Lock()

# 选择试卷需要加锁
lock.acquire() logging.info('[获取试卷]') ... ... 其他逻辑处理 logging.info('[保存]') lock.release()

图:多线程加锁后,数据调用完整

加锁导致速度变慢,考虑取数据时可以分开取:第一个线程取第1行,第二个线程取第2行也可以,就取了锁。用线程名取不同的数据。为了避免数据不够最后多备1条数据。还有其他业务需同时取3条数据,同理。

线程加name:

# 构建线程
threads = []
t = Thread(target=runx, args=(study,), name="t1")
threads.append(t)
t = Thread(target=runx, args=(study2,), name='t2')
threads.append(t)

判断获取不同的数据,为了清晰,在另外一处业务取不同的3条数据处来查看:

原写法:

self.driver.find_element_by_xpath("//table[starts-with(@ng-table-dynamic,'tableParams')]/tbody/tr[1]").click()
self.driver.find_element_by_xpath("//table[starts-with(@ng-table-dynamic,'tableParams')]/tbody/tr[2]").click()
self.driver.find_element_by_xpath("//table[starts-with(@ng-table-dynamic,'tableParams')]/tbody/tr[3]").click()

修改为:根据线程获取不同数据

if threading.current_thread().name == 't1':
tn = 1
else:
tn = 4
# 线程1->取123行, 2->456行
self.driver.find_element_by_xpath("//table[starts-with(@ng-table-dynamic,'tableParams')]/tbody/tr[{0}]".format(tn)).click()
self.driver.find_element_by_xpath("//table[starts-with(@ng-table-dynamic,'tableParams')]/tbody/tr[{0}]".format(tn+1)).click()
self.driver.find_element_by_xpath("//table[starts-with(@ng-table-dynamic,'tableParams')]/tbody/tr[{0}]".format(tn+2)).click()

图:不用锁,不同线程选择不同数据

2) 针对按钮看不到,放全屏操作完后,再还原

为了重置窗口大小,将1节中的方法拆分

from selenium import webdriver
from time import sleep class AutoSubmit():
""" 自动提交测试 """
def __init__(self):
self.rect = (0, 0, 800, 600)
pass def start(self, align=None):
""" 配置并启动 """
logging.info('配置并启动Chrome')
option = webdriver.ChromeOptions()
option.add_argument('disable-infobars') # 无提醒
#option.add_argument('headless') # 静默运行 self.driver = webdriver.Chrome(chrome_options=option) # 置屏幕左右
if align:
# 全屏
self.driver.maximize_window()
# 获取大小
size = self.driver.get_window_size()
width = size['width']
height = size['height'] if align == 'left':
self.rect=(0, 0, int(width/2), height)
elif align == 'right':
self.rect=(int(width/2), 0, int(width/2), height)
else:
pass
# 设置窗口
self.setWindow() return self.driver def setWindow(self, *, maxWindow=False, minWindow=False):
""" 设置窗口位置和大小 """
if maxWindow:
self.driver.maximize_window()
elif minWindow:
self.driver.minimize_window()
else:
self.driver.set_window_rect(*self.rect)

start()中左右屏幕只改变self.rect变量,调用setWdindow()方法重置大小,不传参则为当前rect大小,传maxWindow/minWindow则放大缩小。

调用打开左右两个窗口

# 左右两个窗口
driver1 = a1.start('left')
driver2 = a2.start('right')

窗口2全屏加载bing首页,并置原大小

# 需要全屏时

a2.setWindow(maxWindow=True)
driver2.get('http://bing.com')
sleep(2)
a2.setWindow()

参考资料

python下selenium自动化测试自我实践的更多相关文章

  1. python下的自动化测试--selenium 验证码输入问题

    之前一直在研究scrapy下数据抓取,在研究ajax数据抓取时碰巧研究了一下selenium,确实很实用,不过只做scrapy下的数据抓取,不怎么合适,一是性能的损耗,一直需要开一个浏览器,二是对于爬 ...

  2. 基于python的selenium自动化测试环境搭建

    Windows下的环境搭建: 1.安装python2.7.152.cmd里敲pip install selenium3.安装firefox47.geckodriver11(并将geckodriver. ...

  3. 《Selenium自动化测试实战:基于Python》Selenium自动化测试框架入门

    第1章  Selenium自动化测试框架入门 1.1  Selenium自动化测试框架概述 说到目前流行的自动化测试工具,相信只要做过软件测试相关工作,就一定听说过Selenium. 图1-1是某企业 ...

  4. 基于python的selenium自动化测试环境安装

    1. Python2安装 官方网站:https://www.python.org/downloads/ (python3或新版本已经默认集成了pip包和path,安装的时候打勾就行,可以直接跳过下面第 ...

  5. 阿里大牛教你基于Python的 Selenium自动化测试示例解析

    今天给大家讲解的是自动化测试示例的解析,如有不对的地方请多多指教. 自动化测试示例如下: from selenium import webdriver from selenium.webdriver. ...

  6. python下selenium测试报告整合

    使用过一段时间的Robot Framework测试框架,测试之前需要先搭环境,需要安装的东西很多,这一点个人有些排斥. 每一个测试内容对应一个Test_Case,Robot有自己语法格式,如判断.循环 ...

  7. python下selenium模拟浏览器基础操作

    1.安装及下载 selenium安装: pip install selenium  即可自动安装selenium geckodriver下载:https://github.com/mozilla/ge ...

  8. Selenium自动化测试第二天(下)

    如有任何学习问题,可以添加作者微信:lockingfree 目录 Selenium自动化测试基础 Selenium自动化测试第一天(上) Selenium自动化测试第一天(下) Selenium自动化 ...

  9. Selenium自动化测试第一天(下)

    如有任何学习问题,可以添加作者微信:lockingfree 目录 Selenium自动化测试基础 Selenium自动化测试第一天(上) Selenium自动化测试第一天(下) Selenium自动化 ...

随机推荐

  1. Linux SSH登录很慢的解决方法

    一:UseDNS OpenSSH在用户登录的时候会验证IP,它根据用户的IP使用反向DNS找到主机名,再使用DNS找到IP地址,最后匹配一下登录的IP是否合法.如果客户机的IP没有域名,或者DNS服务 ...

  2. [Tensorflow实战Google深度学习框架]笔记4

    本系列为Tensorflow实战Google深度学习框架知识笔记,仅为博主看书过程中觉得较为重要的知识点,简单摘要下来,内容较为零散,请见谅. 2017-11-06 [第五章] MNIST数字识别问题 ...

  3. C语言里有没有像C++里面的sort函数一样的函数?有!

    C 库函数 - qsort() 描述 C 库函数 void qsort(void *base, size_t nitems, size_t size, int (*compar)(const void ...

  4. Linux系统-tcpdump常用抓包命令

    主要语法 过滤主机/IP: tcpdump -i eth1 host 172.16.7.206 抓取所有经过网卡1,目的IP为172.16.7.206的网络数据 过滤端口:  tcpdump -i e ...

  5. 剑指Offer 50. 数组中重复的数字 (数组)

    题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为 ...

  6. Python 使用sys.exc_info自己捕获异常详细信息

    一般程序中,我们需要对异常进行捕获来保证程序的健壮.但是debug的时候,我们可能需要异常的详细信息,这时可以使用sys.exec_info来处理: import traceback import s ...

  7. Coprime Sequence (HDU 6025)前缀和与后缀和的应用

    题意:给出一串数列,这串数列的gcd为1,要求取出一个数使取出后的数列gcd最大. 题解:可以通过对数列进行预处理,求出从下标为1开始的数对于前面的数的gcd(数组从下标0开始),称为前缀gcd,再以 ...

  8. The Twelve-Factor Container

    转自:https://medium.com/notbinary/the-twelve-factor-container-8d1edc2a49d4?%24identity_id=550978996201 ...

  9. Java线程及线程池状态

    一.Java线程的六种状态 如上图1,JDK定义线程状态是不存在“运行中”状态,但为方便描述过程有些图中会画出运行中的状态. Java线程创建后调用start方法进入就绪状态,被OS调度选中后运行,运 ...

  10. MyTomcat(手写服务器)

    Tomcat 是非常流行的 Web Server,它还是一个满足 Servlet 规范的容器.那么想一想,Tomcat 和我们的 Web 应用是什么关系? 从感性上来说,我们一般需要把 Web 应用打 ...