前戏:线程的基础

运行多个线程同时运行几个不同的程序类似,但具有以下优点:
进程内共享多线程与主线程相同的数据空间,如果他们是独立的进程,可以共享信息或互相沟通更容易.
线程有时称为轻量级进程,他们并不需要多大的内存开销,他们关心的不是过程便宜.
一个线程都有一个开始,执行顺序,并得出结论。它有一个指令指针,保持它的上下文内正在运行的跟踪.
(1)、它可以是抢占(中断)
(2)、它可以暂时搁置(又称睡眠),而其他线程正在运行
看一下以下的小案例:

import thread
from time import sleep, ctime def loop0():
print "loop 0开始时间:",ctime() #第一个函数loop0开始时间
sleep(4) # 休眠4秒
print "loop 0 结束时间:_’,ctime() def loopl():
print "loop 1 开始时间:",ctime()
sleep(2)
print "loop 1 结束时间:_’,ctime() def main():
print "程序开始时间:",ctime()
thread.start_new_thread(loop0,()) # 第二个参数是必不可少的,即使loope没有传递参数,仍然要写一个空元组
thread.stant_new_thnead(loopl,())
sleep(6) #这里休眠6秒的原因是确保两个线程己经执行完毕,主线程才接着执行下面的语句
print "程序结束时间:",ctime() if __name__ == '__main__':
main()

在web测试中,不可避免的一个测试就是浏览器兼容性测试,在没有自动化测试前,我们总是苦逼的在一台或多台机器上安装N种浏览器,然后手工在不同的浏览器上验证主业务流程和关键功能模块功能,以检测不同浏览器或不同版本浏览器上,我们的web应用是否可以正常工作。如果我们使用selenium webdriver,那我们就能够自动的在IE、firefox、chrome、等不同浏览器上运行测试用例。为了能在同一台机器上不同浏览器上同时执行测试用例,我们需要多线程技术。下面我们基于python的多线程技术来尝试同时启动多个浏览器进行selenium自动化测试。

#-*- coding:utf-8

from selenium import webdriver
import sys
from time import sleep
from threading import Thread reload(sys)
sys.setdefaultencoding("utf-8") def test_baidu_seanch(browsen, url):
driver = None
#可添加更多浏览器支持进来
if browser == "ie":
driver = webdriver.Ie()
elif browser == "finefox":
driver = webdriver.Firefox()
elif browser == "chrome":
driver = webdriver.Chnome() if driver == None:
exit() driver.get(url)
sleep(3) driver.find_element_by_id("xxx").send_keys(u"xxxx")
sleep(3) driver.find_element_by_id("xxx").click()
sleep(3) driver.quit() if __name__ == "__main__":
#浏览器和首页url
data = {
"ie":"http://www.xxx.com",
"firefox": "http: //www.xxx.com",
"chrome":"http://www.xxxx.com"
} #构建线程
threads =[]
for b, url in data.items():
t = Thread(target=test_baidu_search,angs=(b, url))
threads.append(t) #启动所有线程
for thr in threads:
thr.start()

8.1 多线程进阶学习

threading 高级线程接口

import threading

class MyThnead(threading.Thread):
   def __init__(self, name=None):
   threading.Thread.__init__(self)
  self.name = name    def run(self):
  print self.name    def test():
   for i in range(0, 100):
t = MyThread("thread_" + str(i))
t.start() if __name__ == '__main__':
test()

Lock 线程锁
这里创建实现了一个计数器 count 这个全局变量会被多个线程同时操作,使其能够被顺序相加,需要靠线程锁的帮助。

#-*- encoding: utf-8
import threading
import time class Test(threading.Thread):
def __init__(self, num):
threading.Thread.—init—(self)
self._run_num = num def run(self):
global count, mutex
threadname = threading.currentThnead().getName() for x in nange(int(self._run_num)):
mutex.acquire()
count = count + 1
mutex.release()
print (thneadname, x, count)
time.sleep(l) if __name__ == '__main__':
global count^ mutex
threads =[]
num = 5
count =0
#创建锁
mutex = threading.Lock()
#创建线程对象
for x in nange(num):
threads.append(Test(10))
#启动线程
for t in threads:
t. start()
#等待子线程结束
for t in threads:
t.join()

Queue队列

#!/usr/bin/env python
import Queue
import threading
import urllib2
import time hosts = ["http://xxxx.com", "http://xxxxx.com","http://xxxxxx.com","http://xxxxx.com", "http://xxxxx.com"]
queue = Queue.Queue() class ThreadUrl(thneading.Thread):
""”Threaded Uni Grab
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue def run(self):
while True:
#gnabs host from queue
host = self.queue.get()
url = urllib2.urlopen(host)
#gnabs urls of hosts and prints first 1024 bytes of page
uni = urllib2.urlopen(host)
#signals to queue job is done
self.queue.task_done()
start = time.time() def main():
#spawn a pool of threads, and pass them queue instance
for i in nange(5):
t = ThreadUrl(queue)
t.setDaemon(True)
t.start() #populate queue with data
for host in hosts:
queue.put(host) #wait on the queue until everything has been processed
queue.join() main() print "Elapsed Time: %s" % (time.time() - start)

8.2 使用队列与线程

当线程需要共享数据或资源时,线程可能会变得复杂。线程模块提供许多同步原语,包括信号量,条件变量,事件和锁。虽然存在这些选项,但它被认为是最佳做法,而是专注于使用队列。队列更容易处理,并且使线程编程更安全,因为它们有效地将资源访问单个线程,并允许更清晰和更可读的设计模式。
首先创建一个程序,该程序将按顺序或一个接一个地获取网站的URL,并打印页面的前1024个字节。这是一个经典的例子,可以使用线程更快地完成任务。首先,让我们一起使用这个urllib2 模块来抓住这些页面,然后再使用代码:

import urllib2
import time hosts = ["http://xxxx.com", "http://xxxxx.com","http://xxxxxx.com","http://xxxxx.com", "http://xxxxx.com"]
start = time.time() for host in hosts:
url = urllib2.urlopen(host)
print url.read(1024) print "Elapsed Time: %s" % (time.time() - start)

导入两个模块首先, urllib2模块是什么是繁重的抓住网页。其次,通过调用创建开始时间值 time.time(),然后再次调用它,并减去初始值以确定程序执行多长时间。最后,在查看程序的速度时,“两个半秒”的结果是不可怕的,但是如果您有数百个网页来检索,则考虑到目前的平均值,大概需要50秒。看看如何创建一个线程版本加快速度:

import Queue
import threading
import urllib2
import time hosts = ["http://xxxx.com", "http://xxxxx.com","http://xxxxxx.com","http://xxxxx.com", "http://xxxxx.com"]
queue = Queue.Queue() class ThreadUrl(thneading.Thread):
""”Threaded Uni Grab
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue def run(self):
while True:
#gnabs host from queue
host = self.queue.get()
url = urllib2.urlopen(host)
#gnabs urls of hosts and prints first 1024 bytes of page
print url.read(1024)
#signals to queue job is done
self.queue.task_done() def main():
#spawn a pool of threads, and pass them queue instance
for i in nange(5):
t = ThreadUrl(queue)
t.setDaemon(True)
t.start() for host in hosts:
queue.put(host)
queue.join() main() print "Elapsed Time: %s" % (time.time() - start)

上面的案例并不比第一个线程示例复杂得多,这要归功于使用排队模块。这种模式是使用Python的线程的一种非常常见的推荐方式。步骤描述如下:
1. 创建一个实例,Queue.Queue()然后用数据填充它。

2.将填充数据的实例传递到您从继承中创建的线程类threading.Thread。

3.产生一个守护进程池线程。

4. 一次将一个项目拉出队列,并使用线程内的数据,运行方法来完成工作。

5.完成工作后,向queue.task_done()任务完成发送一个信号到队列。

6. 加入队列,这意味着等到队列为空,然后退出主程序。

只是一个关于这种模式的注释:通过将守护进程线程设置为true,它允许主线程或程序退出,如果只有守护进程线程存活。这将创建一种控制程序流程的简单方法,因为您可以在退出之前连接队列,或等到队列为空。具体过程最好在队列模块的文档中描述,如相关主题所示:
join()
“块直到队列中的所有项目已经被处理完毕,每当一个项目被添加到队列中时,未完成任务的计数就会上升,当消费者线程调用task_done()来指示项目被检索时,所有的工作都是完成的,当未完成任务的计数下降到零时,join()解除阻塞。

python+selenium自动化软件测试(第8章) :多线程的更多相关文章

  1. python+selenium自动化软件测试(第13章):selenium面试题

    前言最近看到群里有小伙伴贴出一组面试题,最近又是跳槽黄金季节,小编忍不住抽出一点时间总结了下 一.selenium中如何判断元素是否存在?expected_conditions模块提供了16种判断方法 ...

  2. python+selenium自动化软件测试(第10章):测试驱动TDD

    测试驱动开发模式,要求开发在写业务代码的时候,先写出测试代码,同时单元测试例子决定了如何来写产品的代码,并且不断的成功的执行编写的所有的单元测试例子,不断的完善单元测试例子进而完善产品代码, 这样随着 ...

  3. python+selenium自动化软件测试(第11章):持续集成jenkins和GitHub的使用

    11.1 jenkins持续集成环境 相关安装包下载链接:http://pan.baidu.com/s/1qYhmlg4 密码:dcw2赠送jenkins集成selenium环境视频链接http:// ...

  4. python+selenium自动化软件测试(第9章) :Logging模块

    9.1 Logging模块 什么是日志记录?记录是跟踪运行时发生的事件的一种手段.该软件的开发人员将记录调用添加到其代码中,以指示某些事件已发生.事件由描述性消息描述,该消息可以可选地包含可变数据(即 ...

  5. python+selenium自动化软件测试(第16章):基础实战(3)

    #coding:utf-8 from time import sleep from selenium import webdriver class cloudedge_register(object) ...

  6. python+selenium自动化软件测试(第15章):基础实战(2)

    #coding:utf-8 #for windows/py2.7 from time import sleep from selenium import webdriver browser = web ...

  7. python+selenium自动化软件测试(第14章):基础实战(1)

    #coding=utf- from selenium import webdriven from selenium.webdriver.common.by import By from seleniu ...

  8. python+selenium自动化软件测试(第12章):Python读写XML文档

    XML 即可扩展标记语言,它可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进 行定义的源语言.xml 有如下特征: 首先,它是有标签对组成:<aa></aa> ...

  9. python+selenium自动化软件测试(第7章):Page Object模式

    什么是Page ObjectModel模式Page Objects是selenium的一种测试设计模式,主要将每个页面看作是一个class.class的内容主要包括属性和方法,属性不难理解,就是这个页 ...

随机推荐

  1. 【微信小程序开发教程】如何显示群名称?

    今年 5 月份的时候,微信宣布:「为了更好的针对群场景提供个性化服务,当用户在群聊中点击小程序分享卡片时,小程序支持开发者获取群 ID 和群名称」.但随后没多久,发现小程序只返回了群 ID,并没有给我 ...

  2. 大三仍是Linux系统小白的我给大家讲讲学习历程

    我与Linux结缘是在大三的时候.我与Linux熟识是在偶然遇到<Linux就该这么学>的时候.因为我是电子信息工程专业,在高年级时开设了嵌入式课程,嵌入式系统是一种专用的计算机系统,作为 ...

  3. vs2015数据驱动的单元测试

    今天在做测试的时候boss让我这个菜鸟做vs2015下c#的单元测试,并且给了我参考http://www.cnblogs.com/kingmoon/archive/2011/05/13/2045278 ...

  4. tensorflow Relu激活函数

    1.Relu激活函数 Relu激活函数(The Rectified Linear Unit)表达式为:f(x)=max(0,x). 2.tensorflow实现 #!/usr/bin/env pyth ...

  5. spring mvc3 静态文件放在WEB-INF下无法访问解决和解决@Controller失效问题

    今天整合spring+mybatis+easyui碰到的问题 将easyui放在WEB-INF下后无法访问, 解决:需配置<mvc:resources mapping="/easyui ...

  6. nopCommerce 3.9 大波浪系列 之 网页加载Widgets插件原理

    一.插件简介 插件用于扩展nopCommerce的功能.nopCommerce有几种类型的插件如:支付.税率.配送方式.小部件等(接口如下图),更多插件可以访问nopCommerce官网. 我们看下后 ...

  7. Keras Xception Multi loss 细粒度图像分类

    作者: 梦里茶 如果觉得我的工作对你有帮助,就点个star吧 关于 这是百度举办的一个关于狗的细粒度分类比赛,比赛链接: http://js.baidu.com/ 框架 Keras Tensorflo ...

  8. Mybatis 的分页条件查询语句编写

    刚来到一家新公司, 翻看项目代码, 发现一位同事写的查询逻辑很好, 不用插件, 一个语句完成了分页条件查询. 而我之前一般都是在业务层对参数进行判断, 如果有条件,就调用条件查询的方法, 如果没有条件 ...

  9. ASP.NET前台table通过Ajax获取绑定后台查询的json数据

    上一篇<ASP.NET前台html页面AJAX提交数据后台ashx页面接收数据>写了前台提交数据后台保存到数据库,数据处理以后用户肯定要查询.接下来就写一个前台table通过ajax  J ...

  10. Vue实例对象的数据选项

    前面的话 一般地,当模板内容较简单时,使用data选项配合表达式即可.涉及到复杂逻辑时,则需要用到methods.computed.watch等方法.本文将详细介绍Vue实例对象的数据选项 data ...