Pythone4_Selenium实战

 

 

 

 

 

 

 

Pythone_Selenium实战

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

自动化测试基础

什么样的项目适合自动化测试

1,任务测试明确,不会频繁变动

2,每日构建后的测试验证;

3,比较频繁的回归测试;

4,软件系统界面稳定,变动少

5,需要在多平台运行的相同案例、组合遍历型的测试、大量重复任务;

6,软件维护周期长;

7,项目进度压力不大;

8,被测软件系统开发比较规范,能够保证系统的可测试性;

9,具备大量的自动化测试平台

10,测试人员具备较强的编程能力

以上具备 3个条件,既可以开展;

 

什么是 Selenium?


Selenium 自动化测试工具,它主要是用于 Web 应用程序的自动化测试,但并不只局限于此,它还支
持所有基于 web 的管理任务自动化。
Selenium 的特点:
l开源,免费
l多浏览器支持:FireFox、Chrome、IE、Opera
l多平台支持:linux 、windows、MAC
l多语言支持:java、Python、Ruby、php、C#、JavaScript
l对 web 页面有良好的支持
l简单(API 简单)、灵活(用开发语言驱动)
l支持分布式测试用例执行

 

 

 

 

 

 

 

脚本编辑环境搭建

 

Phthon安装

https://www.python.org/downloads/windows/

环境变量配置

步骤:a: 右键 我的电脑�>属性->高级系统设置->环境变量配置 

 

步骤:   b: 在系统变量中点击 新建,输入如下内容(注意变量名可以随便取,变量值就是python的安装目录) 

 

步骤:c: 在系统变量中找到 Path->选择编辑->新建,输入%PYTHON_HOME%PYTHON_HOME就是上一步中的变量名),接着在新建再输入如下内容:%PYTHON_HOME%\Scripts%PYTHON_HOME%\DLLs%PYTHON_HOME%\Lib\lib-tk (注意:后面这几个是为了使用pip,esay_install而添加的,如果不需要则可不用添加了)

 

浏览器环境搭建

 

 FireFox、  Chrome

 

安装浏览器驱动driver

     1.chromedriver 下载地址:https://code.google.com/p/chromedriver/downloads/list

     2.Firefo驱动下载地址:https://github.com/mozilla/geckodriver/releases/

注意:下载解压后,将chromedriver.exe , geckodriver.exe , Iedriver.exe发到Python的安装目录,例如 D:\python 。 然后再将Python的安装目录添加到系统环境变量的Path下面。

FireFox 需要安装插件 : Firebug、Firepath、Xpath find;

 

Chrome需要安装插件:     x path for free

编写第一个自动化脚本

#coding = utf-8
#导入webdriver驱动
from selenium import  webdriver
#webdriver  Firefox 赋值给 browser
driver = webdriver.Firefox()
#给浏览器 定义一个地址
driver.get('http://www.baidu.com')
#查找元素,同时输入selenium2
driver.find_element_by_id("kw").send_keys("selenium2")
#查找元素 点击提交
driver.find_element_by_id("su").click()
#关闭
driver.quit()

 

WebDriver API

 

ID定位 (www.baidu.com)

driver.find_element_by_id("kw")

 

Name定位(http://www.csdn.net/)

 

find_element_by_name("passwordtwo")

 

 

Class定位

find_element_by_class_name("s_ipt")

620b39b1fe0d92c06389e55c1a6d8dc390e.jpg

Tag定位

find_element_by_tag_name("input")
find_element_by_tag_name("input") 

 

Link定位

link 定位与前面介绍的几种定位方法有所不同,它专门用来定位本链接。百度输入框上面的几个文本
链接的代码如下:
<a class="mnav" name="tj_trnews" href="http://news.baidu.com">新闻</a>
<a class="mnav" name="tj_trhao123" href="http://www.hao123.com">hao123</a>
<a class="mnav" name="tj_trmap" href="http://map.baidu.com">地图</a>
<a class="mnav" name="tj_trvideo" href="http://v.baidu.com">视频</a>
<a class="mnav" name="tj_trtieba" href="http://tieba.baidu.com">贴吧>

find_element_by_link_text("新闻")
find_element_by_link_text("hao123")

find_element_by_link_text()方法通过元素标签对之间的部分文本信息来定位元素

 

Partial link定位

parial link 定位是对 link 定们的一个种补充,有些文本连接会比较长,这个时候我们可以取文本链接的

有一部分定位,只要这一部分信息可以唯一的标识这个链接。
<a class="mnav" name="tj_lang" href="#">一个很长很长的文本链接</a>
通过 partial link 定位如下:
find_element_by_partial_link_text("一个很长的")
find_element_by_partial_link_text("文本连接")

 

Xpath定位

//表示当前页面某个目录下,input 表示定位元素的标签名,[@id='kw'] 表示这个元素的 id 属性值等于
kw。下面通过 name class 属性值来定位。
find_element_by_xpath("//input[@id='wd']")
find_element_by_xpath("//input[@class='s_ipt']")
find_element_by_xpath("//*[@class='bg s_btn']")
如果不想指定标签名也可以用星号(*)代替。当然,使用 XPath 不仅仅只局限在 idname class
三个属性值,元素的任意属性值都可以使用,只要它能唯一的标识一个元素。
find_element_by_xpath("//input[@maxlength='100']")
find_element_by_xpath("//input[@autocomplete='off']")
find_element_by_xpath("//input[@type='submit']")

假如百度输入框本身没有可利用的属性值,我们可以查找它的上一级属性。比如,“小明”刚出生的
时候没有名字,没上户口(没身份证号),那么亲朋好友来找“小明”可以先到小明的爸爸,因为他爸爸
是有很多属性特征的,找到了小明的爸爸,抱在怀里的一定就是小明了。通过 XPath 描述如下:
Selenium2 Python 自动化测试实战》样张
66
find_element_by_xpath("//span[@class='bg s_ipt_wr']/input")
find_element_by_xpath("//span[@class='bg s_btn_wr']/input")
span[@class='bg s_ipt_wr'] 通过 class 属性定位到是父元素,后面/input 也就表示父元素下面标签名为
input 的子元素。如果父元素没有可利用的属性值,那么可以继续向上查找“爷爷”元素。
find_element_by_xpath("//form[@id='form']/span/input")
find_element_by_xpath("//form[@id='form']/span[2]/input")

使用逻辑运算符
如果一个属性不能唯一的区分一个元素,我们还可以使用逻辑运算符连接多个属性来区别于其它属
性。
……
<input id="kw" class="su" name="ie">
<input id="kw" class="aa" name="ie">
<input id="bb" class="su" name="ie">
……
如上面的三行元素,假如我们现在要定位第一行元素,如果使用 id 将会与第二行元素重名,如果使用
class 将会与第三行元素的重名。那么如果同时使用 id class 就会唯一的标识这个元素。那么这个时候就
可以通过逻辑运算符号连接。
find_element_by_xpath("//input[@id='kw' and @class='su']/span/input")
当然,我们也可以用 and 连接更多的属性来唯一的标识一个元素

Css定位

"百度搜索框"

<span class="soutu-btn"/>

<input id="kw" class="s_ipt" name="wd" value="" maxlength="255" autocomplete="off"/>

<a id="quickdelete" class="quickdelete" href="javascript:;" title="清空" style="top: 0px; right: 0px; display: none;"/

 

  “百度提交按钮”

<span class="bg s_btn_wr">

<input id="su" class="bg s_btn btnhover" value="百度一下" type="submit"/>

</span>

 

 

通过class 属性定位:

find_element_by_css_selector(".s_ipt")

find_element_by_css_selector(".bg s btn btnhover")

通过id 属性定位:

find_element_by_css_selector("#kw")

find_element_by_css_selector("#su")

通过标签名定位:

find_element_by_css_selector("input")

通过父子关系定位:

find_element_by_css_selector("span>input")

上面的写法表示有父亲元素,它的标签名叫 span,查找它的所有标签名叫 input 的子元素

通过属性定位:

find_element_by_css_selector("input[autocomple='off']"

find_element_by_css_selector("input[maxlength='255']")

find_element_by_css_selector("iniput[type='submit']")

在css当中也可以使用元素的任意属性,只要这些熟悉可以唯一的标识这个元素。

组合定位:

find_element_by_css_selector("span.bg s_ipt_wr>input.s_ipt")

find_element_by_cess_selector("span.bg S_ipt_wr>input#su")

 

用By定位元素

from  selenium.webdriver.common.by import By

具体通过哪种定位方式(id name)根据实际场景而定位,By 就可以设
置定位策略

find_elenium(By.ID,"kw")

find_elenium(By.NAME,"wd")

find_elenium(By.CLASS_NAME,"s_ipt")

find_elenium(By.TAG_NAME,"input")

find_elenium(By.LINK_TEXT,u"新闻")

find_elenium(By.PARTIAL_LINK_TEXT,u"新闻")

find_elenium(By.XPATH,"//*[@class='bg s_btn]")

find_elenium(By.CSS_SELECTOR,"span.bg s_btn_wr>input#su")

控制浏览器

#设置浏览器大小
driver.set_window_size(480,800)

 

#设置浏览器最大化
driver.maximize_window()

浏览器的前进、后退

driver.get("http://www.baidu.com")

driver.get("http://news.baidu.com")

driver.back()

driver.forward()

简单元素操作

clear()  清除文本、send_keys(*value) 输入 、click()点击元素;

案例: 登录github

from selenium import webdriver

import time

driver = webdriver.Firefox()
driver.get("https://github.com/")

driver.find_element_by_xpath(".//*[@id='user[login]']").click()
driver.find_element_by_xpath(".//*[@id='user[email]']").send_keys("ppppppppppppppppp")
paswd=driver.find_element_by_xpath(".//*[@id='user[password]']")

paswd.send_keys("0000000000000000000000000000000000000")
paswd.clear()

time.sleep(100)
driver.quit()

 

注意 :接口提交数据使用submit()要求提交对象是一个表单

driver.find_element_by_xpath("xxxxx").submit()

 

 

l size 返回元素的尺寸。
l text 获取元素的文本。

user=driver.find_element_by_xpath(".//*[@id='user[login]']").size

email=driver.find_element_by_xpath("html/body/div[4]/div[6]/div[2]/form/p").text

print(user)

print(email)


l get_attribute(name) 获得属性值。


user=driver.find_element_by_xpath(".//*[@id='user[login]']").get_attribute("type")

get_attribute 可以获取 id、class、name、type


l is_displayed() 设置该元素是否用户可见ss

#返回元素的结果是否可见,返回结果为 True False

email=driver.find_element_by_xpath("html/body/div[4]/div[6]/div[2]/form/p").is_displayed()

鼠标事件

ActionChains 类提供的鼠标操作的常用方法:


l perform() 执行所有 ActionChains 中存储的行为
l context_click() 右击
l double_click() 双击
l drag_and_drop() 拖动
l move_to_element() 鼠标悬停

 

#定位到要右击的元素
right_click =driver.find_element_by_id("xx")
#对定位到的元素执行鼠标右键操作
ActionChains(driver).context_click(right_click).perform()

 

 

from selenium.webdriver import ActionChains
对于 ActionChains 类下面的方法,在使用之前需要先将模块导入。
ActionChains(driver)
调用 ActionChains()方法,在使用将浏览器驱动 driver 作为参数传入。
context_click(right_click)
context_click()方法用于模拟鼠标右键事件,在调用时需要传入右键的元素。
perform()
执行所有 ActionChains 中存储的行为,可以理解成是对整个操作事件的提交动作

 

鼠标悬浮操作

#定位到要悬停的元素
above =driver.find_element_by_id("xx")
#对定位到的元素执行悬停操作
ActionChains(driver).move_to_element(above).perform()

 

鼠标双击操作

 

#定位到要悬停的元素
double_click = driver.find_element_by_id("xx")
#对定位到的元素执行双击操作
ActionChains(driver).double_click(double_click).perform()

 

鼠标堆放操作(拖动操作)

 

#定位元素的源位置
element = driver.find_element_by_name("xxx")
#定位元素要移动到的目标位置
target = driver.find_element_by_name("xxx")
#执行元素的拖放操作
ActionChains(driver).drag_and_drop(element,target).perform()

 

键盘事件

 

from selenium.webdriver.common.keys import Keys

 

#输入框输入内容
driver.find_element_by_id("kw").send_keys("seleniumm")
#删除多输入的一个 m
driver.find_element_by_id("kw").send_keys(Keys.BACK_SPACE)
#输入空格键+“教程
driver.find_element_by_id("kw").send_keys(Keys.SPACE)
driver.find_element_by_id("kw").send_keys(u"教程")
#ctrl+a 全选输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'a')
#ctrl+x 剪切输入框内容
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'x')
#ctrl+v 粘贴内容到输入框
driver.find_element_by_id("kw").send_keys(Keys.CONTROL,'v')
#通过回车键盘来代替点击操作
driver.find_element_by_id("su").send_keys(Keys.ENTER)

 

获得验证信息

获得验证处理 常用通过 title 和 URL   text 、get_attribute() 获取属性值

 

#获取页面 title
driver.title
#获取页面URL
driver.current_url
#获取指定位置的,文本 信息
driver.find_element_by_xpath().text

 

#获取页面 title
title=driver.title
#获取页面URL
url=driver.current_url
#获取指定位置的,文本 信息
baid=driver.find_element_by_xpath(".//*[@id='su']").get_attribute("value")

 

设置元素等待

显示等待:

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
from selenium.webdriver.common.by import By

driver=webdriver.Firefox()
driver.get("http://www.baidu.com")

element=WebDriverWait(driver,5,0,5).until(
    EC.presence_of_element_located((By.ID,"kw"))
)


element.send_keys("selenium")

driver.quit()

WebDriverWait()


它是由 webdirver 提供的等待方法。在设置时间内,默认每隔一段时间检测一次当前页面元素是否存
在,如果超过设置时间检测不到则抛出异常。具体格式如下:
WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
driver - WebDriver 的驱动程序(IeFirefoxChrome 等)
timeout - 最长超时时间,默认以秒为单位

until()
WebDriverWait()一般由 until()(或 until_not())方法配合使用,下面是 until()until_not()方法的说明。
until(method, message=’ ’)
调用该方法提供的驱动程序作为一个参数,直到返回值为 Ture
until_not(method, message=’ ’)
调用该方法提供的驱动程序作为一个参数,直到返回值为 False


Expected Conditions


在本例中, 我们在使用 expected_conditions 类时对其时行了重命名, 通过 as 关键字对其重命名为 EC
并调用 presence_of_element_located()判断元素是否存在。
expected_conditions 类提供一些预期条件的实现。
title_is 用于判断标题是否 xx
title_contains 用于判断标题是否包含 xx 信息。
presence_of_element_located 元素是否存在。
visibility_of_element_located 元素是否可见。
visibility_of 是否可见
presence_of_all_elements_located 判断一组元素的是否存在
text_to_be_present_in_element 判断元素是否有 xx 文本信息
text_to_be_present_in_element_value 判断元素值是否有 xx 文本信息
frame_to_be_available_and_switch_to_it 表单是否可用,并切换到该表单。
invisibility_of_element_located 判断元素是否隐藏
element_to_be_clickable 判断元素是否点击,它处于可见和启动状态
staleness_of 等到一个元素不再是依附于 DOM
element_to_be_selected 被选中的元素。

element_located_to_be_selected 一个期望的元素位于被选中。
element_selection_state_to_be 一个期望检查如果给定的元素被选中。
element_located_selection_state_to_be 期望找到一个元素并检查是否选择状态
alert_is_present 预期一个警告信息

隐式等待

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium import webdriver
from selenium.webdriver.common.by import By

driver=webdriver.Firefox()
driver.get("http://www.baidu.com")

driver.implicitly_wait(10)

 

休眠设置

from time import sleep

 

sleep(2)

 

定位一组元素

 

通过 find_elements_xxx  

 

如果遇到 checkbox 点击操作:

 

 1,driver.find_element_by_xx().pop().click()

 

 2, ActionChains(driver).double_click(driver.find_element_by_xx).perform()

 

如果遇到重复多的 需要进行过滤:

#然后从中过滤出 tpye checkbox 的元素,单击勾选
for i in inputs:
if i.get_attribute('type') == 'checkbox':
i.click()

 

多表单切换

from selenium import webdriver
import time
import os

driver=webdriver.Firefox()

file_path='file:///'+ os.path.abspath('fram.html')

driver.get(file_path)

driver.switch_to.frame("if")

driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()

time.sleep(3)
driver.quit()

 

 

切换表单:

driver.switch_to.frame("if")

 

退回到上一步骤:

driver.switch_to.default_content()

 

如果表单嵌套在当前页面,要先定位表单frame:

切换表单:

driver.switch_to.frame("if")

 

多窗口切换

current_window_handle 获得当前窗口句柄
window_handles 返回的所有窗口的句柄到当前会话
switch_to_window()

 

from selenium import webdriver
from time import sleep

driver=webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.baidu.com")

sreach_windows=driver.current_window_handle

driver.find_element_by_xpath(".//*[@id='u1']/a[7]").click()

sleep(3)

driver.find_element_by_xpath(".//*[@id='TANGRAM__PSP_10__submitWrapper']/a[1]").click()
sleep(3)

all_windos=driver.window_handles

for handle in all_windos:
    if handle!=sreach_windows:
        driver.switch_to.window(handle)
        print("now register window")
        driver.find_element_by_xpath(".//*[@id='TANGRAM__PSP_3__userName']").send_keys("username")
        driver.find_element_by_xpath(".//*[@id='TANGRAM__PSP_3__password']").send_keys("userpassd")


for handle in all_windos:

    if handle == sreach_windows:
        driver.switch_to.window(handle)
        print("now sreach winow")

        #关闭登录tab
        driver.find_element_by_xpath(".//*[@id='TANGRAM__PSP_4__closeBtn']").click()
        driver.find_element_by_id("kw").send_keys("selenium")
        driver.find_element_by_id("su").click()
        sleep(3)

driver.quit()

 

警告框处理

switch_to_alert

 

 l text 返回 alert/confirm/prompt 中的文字信息。
l accept 点击确认按钮。
l dismiss 点击取消按钮,如果有的话。
l send_keys 输入值,这个 alert\confirm 没有对话框就不能用了,不然会报错

sleep(2)
move=driver.find_element_by_xpath(".//*[@id='u1']/a[8]")
ActionChains(driver).move_to_element(move).perform()
sleep(2)
driver.find_element_by_xpath(".//*[@id='wrapper']/div[6]/a[1]").click()
sleep(2)
driver.find_element_by_xpath(".//*[@id='gxszButton']/a[1]").click()

sleep(2)
driver.switch_to.alert.accept()

 

上传文件

#coding=utf-8
from selenium import webdriver
import os
driver = webdriver.Firefox()
#打开上传功能页面
file_path = 'file:///' + os.path.abspath('upfile.html')
driver.get(file_path)
#定位上传按钮,添加本地文件
driver.find_element_by_name("file").send_keys('D:\\upload_file.txt')
driver.quit()
通过这种方法上传,就绕开了操作 Windows 控件的步骤。如果能找上传的 input 标签,那么基本都可
以通过 send_keys()方法向其输入一个文件地址来实现上传

 

下载文件

FireFox 让浏览器能实现文件的载,我们需要通过 FirefoxProfile() 对其参数做一个设置。
browser.download.folderList
设置成 0 代表下载到浏览器默认下载路径;设置成 2 则可以保存到指定目录。
browser.download.manager.showWhenStarting
是否显示开始,Ture 为显示,Flase 为不显示。
browser.download.dir
用于指定你所下载文件的目录。os.getcwd() 该函数不需要传递参数,用于返回当前的目录。
browser.helperApps.neverAsk.saveToDisk
指定要下载页面的 Content-type 值,“application/octet-stream”为文件的类型。HTTP Content-type
用对照表:http://tool.oschina.net/commons
这些参数的设置可以通过在 Firefox 浏览器地址栏输入:about:config 进行设置,如图 4.17
4.17 FireFire 参数设置

9e44958874baf4d02d7e6d96171994d0c9a.jpg

 

操作 Cookie

业务场景:

开发人员开发一个功能,当用户登录后,会将用户的用户名写入浏览器 cookie,指定的 key 为“username”,那么我们就可以通过 get_cookies() 找到 useranme
打印 vlaue,如果找不到 username 或对应的 value 为空,那么说明保存浏览器的 cookie 是有问题的

#coding=utf-8
from selenium import webdriver
from time import sleep

driver = webdriver.Firefox()
driver.get("http://www.baidu.com")

#获取cookie信息
cookie = driver.get_cookies()

#将获得cookie 的信息打印
print(cookie)

driver.add_cookie({'name':'key-aaaaa','value':'value-bbbbbb'})

#遍历cookiesname  value

for cookie in driver.get_cookies():

    print("%s  -> %s"%(cookie['name'],cookie['value']))

driver.quit()

l webdriver 操作 cookie 的方法有:
l get_cookies() 获得所有 cookie 信息
l get_cookie(name) 返回有特定 name 值有
l add_cookie(cookie_dict) 添加 cookie,必须有 n
l delete_cookie(name) 删除特定(部分)cook
l delete_all_cookies() 删除所有 cookie 信息

 

调用 JavaScript

通过浏览器打开百度进行搜索,搜索的一屏无法完全显示将会出现滚动条。这个时候就可以通过
JavaScript 代码控制滚动条在任意位置,需要改变的就是 scrollTop 的值。通过 execute_script()方法来执行这段 JavaScript 代码

 

般用到操作滚动条的会两个场景:
l 注册时的法律条文的阅读,判断用户是否阅读完成的标准是:滚动条是否拉到最下方。
l 要操作的页面元素不在视觉范围,无法进行操作,需要拖动滚动条。

#coding=utf-8
from selenium import webdriver
from time import sleep

driver = webdriver.Firefox()

driver.get("http://www.baidu.com")

#搜索

driver.find_element_by_id("kw").send_keys("selenium")
driver.find_element_by_id("su").click()
sleep(3)
#将页面滚动条拖到底部
js = "var q=document.documentElement.scrollTop=1000"
driver.execute_script(js)

js_="var q = document.documentElement.scrollTop=0"
driver.execute_script(js_)
sleep(3)
driver.quit()

 

窗口截图


#coding=utf-8
from  selenium import webdriver
import logging
logging.basicConfig(level=logging.DEBUG)

driver = webdriver.Firefox()
driver.get("http://www.baidu.com")

try:
    driver.find_element_by_id("kw_error").send_keys('selenium')
    driver.find_element_by_id("su").click()

except :
    driver.get_screenshot_as_file("D:\\baidu_error\\baidu_error.jpg")
    driver.quit()

 

自动化测试模型

线性测试

a9c1f5f0249e2853fd6dea80d65f95135a4.jpg

模块化与类库

560275d5917c9e73f3ce0b687aa97972823.jpg

 

public.py

#coding=utf-8
from selenium import webdriver
#登陆
def login():
driver.find_element_by_id("idInput").clear()
driver.find_element_by_id("idInput").send_keys("username")
driver.find_element_by_id("pwdInput").clear()
driver.find_element_by_id("pwdInput").send_keys("password")
driver.find_element_by_id("loginBtn").click()
#退出
def logout():
driver.find_element_by_link_text(u"退出").click()
driver.quit()
driver = webdriver.Firefox()
driver.implicitly_wait(10)
driver.get("http://www.126.com")
login() #调用登陆模块
#收信、写信、删除信件等操作
logout() #调用退出模块

 

mail126.py

#coding=utf-8
from selenium import webdriver
from time import sleep

import public

driver = webdriver.Firefox()

driver.get("http://www.126.com")

#调用登录模块

public.login(driver)

#调用退出模块

public.logout(driver)

 

数据驱动

653ba1219f66a6a7e9c26cbc37cd23ea77b.jpg

#coding=utf-8

from selenium import  webdriver
file_info=open('info.txt','r')

values = file_info.readlines()
file_info.close()

for serch in values:
    driver=webdriver.Firefox()
    driver.implicitly_wait(10)
    driver.get("http://www.baidu.com")
    driver.find_element_by_id("kw").send_keys(serch)
    driver.find_element_by_id("su").click()
    driver.quit()

 

文本读取

读取txt文件

l read() 读取整个文件。
l readline() 读取一行数据。
l readlines() 读取所有行的数据

#coding=utf-8

zhangsan,123
lisi,456
wangwu,789

from selenium import  webdriver
file_info=open('info.txt','r')

values = file_info.readlines()
file_info.close()

for serch in values:
    username= serch.split(',')[0]
    passwd=serch.split(',')[1]

读取 csv 文件

import csv

#读取本地csv文件

my_file='E:\\info.csv'
date = csv.reader(open(my_file,'rb'))

#循环输出
for user in date:
    
    print(user)

读取xml文件

 

import xml.dom.minidom as do

#打开xml文档
dom=do.parse('info.xml')

#获得文档元素对象

root=dom.documentElement

 

获取标签的属性值

#coding=utf-8
import xml.dom.minidom
#打开 xml 文档
dom = xml.dom.minidom.parse('info.xml')
#得到文档元素对象
root = dom.documentElement
logins = root.getElementsByTagName('login')
#获得 login 标签的 username 属性值
username=logins[0].getAttribute("username")
print username
#获得 login 标签的 passwd 属性值
password=logins[0].getAttribute("passwd")
print password
items = root.getElementsByTagName('item')
#获得第一个 item 标签有 id 属性值
id1=items[0].getAttribute("id")
print id1
#获得第二个 item 标签有 id 属性值
id2=items[1].getAttribute("id")

 

获取标签之间的数据

 

#coding=utf-8
import xml.dom.minidom
#打开 xml 文档
dom = xml.dom.minidom.parse('info.xml')
#得到文档元素对象
root = dom.documentElement
captions=dom.getElementsByTagName('caption')
#获得第一个标签对的值
c1=captions[0].firstChild.data
print c1
#获得第二个标签对的值
c2=captions[1].firstChild.data
print c2
#获得第三个标签对的值
c3=captions[2].firstChild.data
print c3

 

unittest 单元测试框架

提供用例组织与执行:对一个功能编写几个测试用例来说,当然不同讲究用例的组织,但测试用例达
到成百上千时,就需要考虑编写用例的规范与组织,否则后期的维护成本是呈现指数级增加的。可能,我
们都无法顾及开发新功能,而花费大量的时间和精力在维护测试用例。这也是单元测试用例的目的。
提供比较方法:不是管是功能测试用例,还是单元测试都会有一个预期结果,测试的过程其实就是执
行某些操作之后拿实际的结果与预期结果进行比较,当然,这个比较有我们前面介绍来的断言与验证。
提供丰富的日志:当所有用例执行完成,要有足够清晰的日志信息告诉我哪些用例失败以及它们失败
的位置,如果没这清晰的日志,那么将会大大提供 debug 问题也是一件非常耗时的工作。

#coding=utf-8

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.keys import Keys
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest2,time,re


class BaiduTest(unittest2.TestCase):
    def setUp(self):
        self.driver=webdriver.Firefox()
        self.driver.implicitly_wait(30)
        self.base_url="http://www.baidu.com"
        self.verificationErrors=[]
        self.accept_next_alert= True

    def test_baidu(self):
        driver=self.driver
        driver.get(self.base_url+"/")
        driver.find_element_by_id("kw").click()
        driver.find_element_by_id("kw").send_keys("selenium ide")
        driver.find_element_by_id("su").click()

    def is_element_present(self,how,what):
        try:
            self.driver.find_element(by=how,value=what)
        except NoSuchElementException as e:
            return False
        return True

    def is_alert_present(self):
        try:
            self.driver.switch_to.alert()
        except NoAlertPresentException as e:
            return False
        return True

    def close_alert_and_get_its_text(self):
        try:
            alert=self.driver.switch_to.alert()
            alert_text=alert.text
            if self.accept_next_alert:
                alert.accept()
            else:
                alert.dismiss()
            return alert_text
        finally:
            self.accept_next_alert=True

    def tearDown(self):
        self.driver.quit()
        self.assertAlmostEqual([],self.verificationErrors)


if __name__ == '__main__':
    unittest2.main()

 

unittest 单元测试框架解析

#coding=utf-8
from count import Count
import unittest
class TestCount(unittest.TestCase):
def setUp(self):
self.j = Count(2,3)
def test_add(self):
self.add = self.j.add()
self.assertEqual(self.add,5)
def tearDown(self):
pass
if __name__ == '__main__':
unittest.main()

unittest 的文档中开篇就介绍了 4 个重要的概念:test fixture, test case, test suite, test
runner,我觉得只有理解了这几个概念,才能真正的理解单元测试的基本原理。
test case --测试用例
一个 TestCase 的实例就是一个测试用例。什么是测试用例呢?就是一个完整的测试流程,包括测试
前准备环境的搭建(setUp),实现测试过程的代码(run),以及测试后环境的还原(tearDown)。元测试(unit
test)的本质也就在这里,一个测试用例是一个完整的测试单元,通过运行这个测试单元,可以对某一个
功能进行验证。
test suite ---测试方案
对一个功能的验证往往是需要多测试用例的,可以把多的测试用例集合在一起执行,这就产生了测试
套件 TestSuite 的概念,它用来组装单个测试用例,而且 TestSuite 也可以嵌套 TestSuite。
可以通过 addTest 加载 TestCase 到 TestSuite 中,再返回一个 TestSuite 实例。
test runner  ----测试执行
TextTestRunner 是来执行测试用例的,其中的 run(test)用来执行 TestSuite/TestCase。测试的结果
会保存到 TextTestResult 实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。
test fixture  -----创建于销毁
对一个测试用例环境的搭建和销毁,是一个 fixture,通过覆盖 TestCase 的 setUp()和 tearDown()
方法来实现。这个有什么用呢?比如说在这个测试用例中需要访问数据库,那么可以在 setUp()中建立数
据库连接以及进行一些初始化, 在 tearDown()中清除在数据库中产生的数据, 然后关闭连接。 注意 tearDown
的过程很重要,要为以后的 TestCase 留下一个干净的环境。

 

# coding=utf-8

import unittest2


class Count:
    def __index__(self, a, b):
        self.a = a
        self.b = b

    def add(self):
        return self.a + self.b


class TestCount(unittest2.TestCase):
    def setUp(self):
        self.j = Count(2, 3)

    def test_add(self):
        self.add = self.j.add()
        self.assertEqual(self.add, 5)

    def tearDown(self):
        pass


if __name__ == '__main__':
    # 构造suit

    suit = unittest2.TestSuite()
    suit.addTest(TestCount("test_add"))

    # 执行测试

    test_suit = unittest2.TextTestRunner()

    test_suit.run(suit)

 

count.py

 

#coding=utf-8
#计算器类
class Count:

    def __init__(self,a,b):
        self.a = a
        self.b = b

    def add(self):
        return self.a + self.b

 

all_count.py

 

#coding=utf-8
from .count import Count
import unittest

class Testcase(unittest.TestCase):
    def setUp(self):
        pass

    #测试整数相加

    def test_add(self):
        self.j=Count(2,3)
        self.add=self.j.add()
        self.assertEqual(self.add,5)

    # 测试小数相加

    def test_add2(self):
        self.j=Count(2.3,4.2)
        self.add=self.j.add()
        self.assertEqual(self.add,6.5)
    #测试字符窜 相加

    def test_add3(self):
        self.j=Count("hello","world")
        self.add=self.j.add()
        self.assertEqual(self.add,"helloworld")

if __name__ == '__main__':

    #构造测试集
  suit= unittest.TestSuite()
    suit.addTest(Testcase("test_add"))
    suit.addTest(Testcase("test_add2"))
    suit.addTest(Testcase("test_add3"))

    #执行测试
  runner = unittest.TextTestRunner()
    runner.run(suit)

 

 

TestLoader

 


该类根据各种标准负责加载测试用例,并它们返回给测试套件。正常情况下没有必要创建这个类的实
例。unittest 提供了可以共享了 defaultTestLoader 类,可以使用其子类和方法创建实例,所以我们可以
使用其下面的 discover()方法来创建一个实例。
discover(start_dir,pattern='test*.py',top_level_dir=None)
找到指定目录下所有测试模块,并可递归查到子目录下的测试模块,只有匹配到文件名才能被加载。
如果启动的不是顶层目录,那么顶层目录必须要单独指定。
start_dir :要测试的模块名或测试用例目录。
pattern='test*.py' :表示用例文件名的匹配原则。星号“*”表示任意多个字符。
top_level_dir=None:测试模块的顶层目录。如果没顶层目录(也就是说测试用例不是放在多级目录
中),默认为 None。

 

#coding =utf-8
import unittest

def creatsuit():
    testnuit=unittest.TestSuite()

    test_dir='E:\\hello'

    discover=unittest.defaultTestLoader.discover(test_dir,pattern='test*.py',top_level_dir=None
                                                 )

    #discover筛选出来,
    for test_unit in discover:
        for test_case in test_unit:
            testnuit.addTest(test_case)

    return testnuit

if __name__ == '__main__':
    #测试执行

    runner=unittest.TextTestRunner()

    runner.run(creatsuit())
    

 

创建 creatsuite()函数用于查找指定条件的下的所有测试用例,并将其组装到测试套件中。
调用 discover()方法,首先通过 test_dir 定义查找测试文件的目录,pattern 用来定义匹配测试文
件的文件名,如果文件名以 test 开头的.py 文件,那么就认为它是一个测试文件。top_level_dir 默认为
None。
discover()只能找到了测试文件,接下来通过 for 循环来找到测试文件下的每一个测试用例,并且将
其添加测试套件中

项目实战

测试类型

测试静态内容
静态内容测试是最简单的测试,用于验证静态的、不变化的 UI 元素的存在性。例如:
每个页面都有其预期的页面标题?这可以用来验证链接指向一个预期的页面。
•应用程序的主页包含一个应该在页面顶部的图片吗?
•网站的每一个页面是否都包含一个页脚区域来显示公司的联系方式,隐私政策,以及商标信息?
•每一页的标题文本都使用的<h1>标签吗?每个页面有正确的头部文本内吗?
您可能需要或也可能不需要对页面内容进行自动化测试。如果您的网页内容是不易受到影响手工对内
容进行测试就足够了。如果,例如您的应用文件的位置被移动,内容测试就非常有价值。


测试链接


Web 站点的一个常见错误为的失效的链接或链接指向无效页。链接测试涉及点各个链接和验证预期的
页面是否存在。如果静态链接不经常更改,手动测试就足够。但是,如果你的网页设计师经常改变链接,或者
文件不时被重定向,链接测试应该实现自动化。
功能测试
在您的应用程序中,需要测试应用的特定功能,需要一些类型的用户输入,并返回某种类型的结果。通常
一个功能测试将涉及多个页面,一个基于表单的输入页面,其中包含若干输入字段、提交“和”取消“操作,
以及一个或多个响应页面。用户输入可以通过文本输入域,复选框,下拉列表,或任何其他的浏览器所支持的
输入。
功能测试通常是需要自动化测试的最复杂的测试类型,但也通常是最重要的。典型的测试是登录,注册
网站账户,用户帐户操作,帐户设置变化,复杂的数据检索操作等等。功能测试通常对应着您的应用程序的描
述应用特性或设计的使用场景。


测试动态元素


通常一个网页元素都有一个唯一的标识符,用于唯一地定位该网页中的元素。通常情况下,唯一标识符
用 HTML 标记的’id’属性或’name’属性来实现。这些标识符可以是一个静态的,即不变的、字符串常量。
它们也可以是动态生产值,在每个页面实例上都是变化的。例如,有些 Web 服务器可能在一个页面实例
上命名所显示的文件为 doc3861,并在其他页面实例上显示为 doc6148,这取决于用户在检索的‘文档’。
验证文件是否存在的测试脚本,可能无法找到不变的识别码来定位该文件。通常情况下,具有变化的标识符
的动态元素存在于基于用户操作的结果页面上,然而,显然这取决于 Web 应用程序。


Ajax 的测试


Ajax 是一种支持动态改变用户界面元素的技术。页面元素可以动态更改,但不需要浏览器重新载入页
面,如动画,RSS 源,其他实时数据更新等等。Ajax 有不计其数的更新网页上的元素的方法。但是了解 AJAX
的最简单的方式,可以这样想,在 Ajax 驱动的应用程序中,数据可以从应用服务器检索,然后显示在页面上,
而不需重新加载整个页面。只有一小部分的页面,或者只有元素本身被重新加载

 

编写自动化测试用例

在编写用例过程中应该遵守以下几点原则:
1、一个脚本是一个完整的场景,从用户登陆操作到用户退出系统关闭浏览器。
2、一个脚本脚本只验证一个功能点,不要试图用户登陆系统后把所有的功能都进行验证再退出系统
3、尽量只做功能中正向逻辑的验证,不要考虑太多逆向逻辑的验证,逆向逻辑的情况很多(例如手
号输错有很多种情况),验证一方面比较复杂,需要编写大量的脚本,另一方面自动化脚本本身比较脆弱,
很多非正常的逻辑的验证能力不强。(我们尽量遵循用户正常使用原则编写脚本即可)
4、脚本之间不要产生关联性,也就是说编写的每一个脚本都是独立的,不能依赖或影响其他脚本。
5、如果对数据进行了修改,需要对数据进行还原。
6、在整个脚本中只对验证点进行验证,不要对整个脚本每一步都做验证。

 

用例存放&维护:

5209c3f2f6cba5b6d9e101b17dcd190cc25.jpg

 

发送邮件:

fe82f285fcf2670d5f62a7d4d5da42171da.jpg

#coding=utf-8
from selenium import webdriver
import unittest, time
from public import login
import xml.dom.minidom
#打开 xml 文档
dom = xml.dom.minidom.parse('E:\\test_object\\test_date\\login.xml')
#得到文档元素对象
root = dom.documentElement
Selenium2 Python 自动化测试实战》样张
193
class TestSendMail(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.maximize_window()
self.driver.implicitly_wait(30)
logins = root.getElementsByTagName('url')
self.base_url=logins[0].firstChild.data
self.verificationErrors = []
#只填写收件人发送邮件
def test_send_mail(self):
driver = self.driver
driver.get(self.base_url)
#登录
login.login(self,"testingwtb","a123456")
#写信
driver.find_element_by_css_selector("#_mail_component_47_47 >
span.oz0").click()
#填写收件人
driver.find_element_by_xpath("//*[@class='bz0']/div[2]/div/input")
.send_keys('testingwtb@126.com')
#发送邮件
driver.find_element_by_xpath("/html/body/div[2]/div/div[2]/header
/div/div/div/span[2]").click()
driver.find_element_by_xpath("//*[@class='nui-msgbox-ft-btns']
/div/span").click()
#断言发送结果
text = driver.find_element_by_class_name('tK1').text
self.assertEqual(text,u'发送成功')
login.logout(self)
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()

 

系统会弹框提示“确定真的不需要写主题吗?”,在用例中默认 click
“确定”。邮件发送成功,验证“发送成功”的提示信息

 

搜索邮件:

8fadd2290a1586151268021d5b7dd498103.jpg

............................

#搜索邮件
def test_search_mail(self):
driver = self.driver
driver.get(self.base_url)
#调用登录模块

login.login(self,'testingwtb','a123456')
#搜索邮件
driver.find_element_by_xpath("//input[@class='nui-ipt-input' and
@type='text']").send_keys(u'小明')
driver.find_element_by_xpath("//input[@class='nui-ipt-input' and
@type='text']").send_keys(Keys.ENTER)
#断言搜索邮件标签页面
text= driver.find_element_by_xpath("//div[@id='dvMultiTab']/ul
/li[5]/div[3]").text
self.assertEqual(text,u'搜索邮件')
#调用退出
login.logout(self)

.........................................

自动化测试高级应用

安装和使用HTMLTestRunner生成测试报告

HTMLTestRunner 是 Python 标准库的 unittest 单元测试框架的一个扩展。它生成易于使用的 HTML 测
试报告。 HTMLTestRunner 是在 BSD 许可证下发布。
首先要下 HTMLTestRunner.py 文件,下载地址:
http://tungwaiyip.info/software/HTMLTestRunner.html
HTMLTestRunner.py 本是一个.py 文件,将它放到 Python 安装目录下即可调用。
Windows :将下载的文件放入...\Python\Lib 目录下。

#coding=utf-8
from selenium import webdriver
import unittest, time
import HTMLTestRunner #引入 HTMLTestRunner

class Baidu(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Firefox()
        self.driver.implicitly_wait(10)
        self.base_url = "http://www.baidu.com/"
        self.verificationErrors = []

    # 百度搜索用例
    def test_baidu_search(self):
        driver = self.driver
        driver.get(self.base_url)
        driver.find_element_by_id("kw").send_keys("HTNMLTestRunner")
        driver.find_element_by_id("su").click()

    def tearDown(self):
        self.driver.quit()
        self.assertEqual([], self.verificationErrors)

if __name__ == "__main__":
#测试套件
    testunit=unittest.TestSuite()
#添加测试用例到测试套件中
    testunit.addTest(Baidu("test_baidu_search"))
#定义个报告存放路径
    filename = 'E:\\result.html'
    fp = open(filename, 'wb')
#定义测试报告
    runner =HTMLTestRunner.HTMLTestRunner(
stream=fp,
title=u'百度搜索测试报告',
description=u'用例执行情况:')
#运行测试用例
    runner.run(testunit)
#关闭报告文件
    fp.close()

 

更易读的测试报告

……
#百度搜索用例
def test_baidu_search(self):
u'''百度搜索用例'''
driver = self.driver
driver.get(self.base_url)
driver.find_element_by_id("kw").send_keys("HTNMLTestRunner")
driver.find_element_by_id("su").click()
……
再次运行测试用例,查看测试报告。如图 9.2

 

测试报告文件名称

time

time.time() 获取当前时间戳。
time.ctime() 当前时间的字符串形式。
time.localtime() 当前时间的 struct_time 形式。
time.strftime() 用来获得当前时间,可以将时间格式化为字符串。
Python 中时间日期格式化符号(区分大小写):

Directive

Meaning

%a

星期几的简写

%A

星期几的全称

%w

十进制表示的星期几(值从 0 6,星期天为 0

%d

十进制表示的每月的第几天

%b

月份的简写

%B

月份的全称

%m

十进制表示的月份

%y

不带世纪的十进制年份(值从 0 99

%Y

带世纪部分的十制年份

%H

24 小时制的小时

%I

12 小时制的小时

%p

本地的 AM PM 的等价显示

%M

十时制表示的分钟数

 

Directive

Meaning

%S

十进制的秒数

%f

十进制的微秒,零填充左边

%Z

当前时区的名称

%j

十进制表示的每年的第几天

%U

一年中的星期数(00-53)星期天为星期的开始

%W

一年中的星期数(00-53)星期一为星期的开始

%x

本地相应的日期表示

%X

本地相应的时间表示

%%

%号本身


#获取当前时间
now = time.strftime("%Y-%m-%d %H_%M_%S")
#定义个报告存放路径
filename = 'E:\\test_object\\report\\'+now+'result.html'

 

#coding=utf-8
import unittest
import HTMLTestRunner
import time
def creatsuite():
testunit=unittest.TestSuite()
#定义测试文件查找的目录
test_dir='E:\\test_object\\test_case'
#定义 discover 方法的参数
discover=unittest.defaultTestLoader.discover(test_dir,pattern='test*.py',
top_level_dir=None)
#discover 方法筛选出来的用例,循环添加到测试套件中
for test_case in discover:
print test_case
testunit.addTests(test_case)
return testunit
now = time.strftime("%Y-%m-%d %H_%M_%S")
filename = 'E:\\test_object\\report\\'+now+'result.html'
fp = file(filename, 'wb')
runner =HTMLTestRunner.HTMLTestRunner(
stream=fp,
title=u'百度搜索测试报告',
description=u'用例执行情况:')

alltestnames = creatsuite()
runner.run(alltestnames)
fp.close()

 

0694ba9e5672ac3dd41a4a1b3592a781ee8.jpg

 

Selenium Grid2

Selenium2 工作原理
Selenium2 中因为使用的 WebDriver,这个技术不是靠 js 驱动的,而是直接调用浏览器的原生态接口
驱动的。所以就没有同源问题,也就不需要使用 RC 来执行本地脚本了(当然缺点就是并不是所有的浏览
器都有提供很好的驱动支持,但 JavaScript 却是所有浏览器都通用的)。所以 Selenium2 中执行本地脚
本的方式是:通过本地 WebDriver 驱动直接调用本地浏览器接口就可以了。
Selenium 1(RC)代码
我们可以通过 Selenium IDE 将录制的脚本导出为“Python2/unittest/Remote Control”格式。通过
编辑器打开导出的脚本

selenium grid 工作方式

#coding=utf-8
from selenium import selenium
import unittest, time, re
class serc(unittest.TestCase):
def setUp(self):
self.verificationErrors = []
self.selenium = selenium("localhost", 4444, "*chrome",
"http://www.baidu.com/")
self.selenium.start()
def test_serc(self):
sel = self.selenium
sel.open("/")
sel.type("id=kw", "selenium grid")
sel.click("id=su")
sel.wait_for_page_to_load("30000")
def tearDown(self):
self.selenium.stop()
self.assertEqual([], self.verificationErrors)
if __name__ == "__main__":
unittest.main()

Selenium Server 环境配置

 

环境搭建

第一步、 配置 java 环境
java 下载地址:http://www.java.com/zh_CN/download/manual.jsp

第二步、下载运行 selenium server
下载地址:http://selenium-release.storage.googleapis.com/2.41/selenium-server-2.41.0.zip
在页面的左侧列表中找到 selenium-server-standalone-XXX.jar 进行下载。下载完成可以放到任意
位置,直接在命令提示符下启动 Selenium Server:
C:\selenium> java -jar selenium-server-standalone-XXX.jar

 

调用 Selenium Grid 的基本结构图

f237ac257f799075c95ac5f46227620d81f.jpg

样例演示 :

87053cb01b3c7acde9db4b5dedf2dce90be.jpg

 

 

在浏览器中打开:http://127.0.0.1:4444/grid/console

Selenium Grid 应用

WebDriver 提供了 Remote 可以发送指令到远程服务器控制浏览器。 首先我们先来认识 Remote 的格式

from selenium.webdriver import Remote
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
driver = Remote(command_executor='http://127.0.0.1:4444/wd/hub',
desired_capabilities=DesiredCapabilities.CHROME
)
driver.get('http://www.baidu.com')
……
driver.quit()

 

 

 

 

Desired Capabilities 本质上是 key value 的对象,它告诉 Selenium Server 脚本执行的基本运行环
境:
'platform': 'ANY' 平台默认可以是任何(Windows,MAC,android)。
'browserName': 'chrome' 浏览器名字是 chrome。
'version': '' 浏览器的版本默认为空。
'javascriptEnabled': True javascript 启动状态为 True

 

from selenium.webdriver import Remote
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
driver = Remote(command_executor='http://127.0.0.1:4444/wd/hub',
desired_capabilities={'platform': 'ANY',
'browserName':'chrome',
'version': '',
'javascriptEnabled': True
})
driver.get('http://www.baidu.com')
……
driver.quit()

 

WebDriver API 提供了不同平台及浏览器的参数:

 

ANDROID = {'platform': 'ANDROID', 'browserName': 'android', 'version': '',
'javascriptEnabled': True}

CHROME = {'platform': 'ANY', 'browserName': 'chrome', 'version': '',
'javascriptEnabled': True}

FIREFOX = {'platform': 'ANY', 'browserName': 'firefox', 'version': '',
'javascriptEnabled': True}

HTMLUNIT = {'platform': 'ANY', 'browserName': 'htmlunit', 'version': ''}

HTMLUNITWITHJS = {'platform': 'ANY', 'browserName': 'htmlunit', 'version':
'firefox', 'javascriptEnabled': True}

INTERNETEXPLORER = {'platform': 'WINDOWS', 'browserName': 'internet
explorer', 'version': '', 'javascriptEnabled': True}

IPAD = {'platform': 'MAC', 'browserName': 'iPad', 'version': '',
'javascriptEnabled': True}

IPHONE = {'platform': 'MAC', 'browserName': 'iPhone', 'version': '',
'javascriptEnabled': True}

 

SAFARI = {'platform': 'ANY', 'browserName': 'safari', 'version': '',
'javascriptEnabled': True}

PHANTOMJS = {'platform': 'ANY', 'browserName': 'phantomjs', 'version': '',
'javascriptEnabled': True}

OPERA = {'platform': 'ANY', 'browserName': 'opera', 'version': '',
'javascriptEnabled': True}

 

参数化浏览器执行用例


#coding=utf-8
from selenium.webdriver import Remote
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
#浏览器数组
lists=['chrome','firefox','internet explorer']
#读取不同的浏览器执行脚本
for browser in lists:
print browser
driver = Remote(
command_executor='http://127.0.0.1:4444/wd/hub',
desired_capabilities={'platform': 'ANY',
'browserName':browser,
'version': '',
'javascriptEnabled': True
})
driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys(browser)
driver.find_element_by_id("su").click()
driver.close()

 

多节点执行用例

#coding=utf-8
from selenium.webdriver import Remote
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
#定义主机与浏览器
lists={'http://127.0.0.1:4444/wd/hub':'chrome',
'http://127.0.0.1:5555/wd/hub':'firefox',
'http://127.0.0.1:5556/wd/hub':'internet explorer'}
#通过不同的浏览器执行脚本
for host,browser in lists.items():
print host,browser
driver = Remote(
command_executor=host,
desired_capabilities={'platform': 'ANY',
'browserName':browser,
'version': '',
'javascriptEnabled': True
})

driver.get("http://www.baidu.com")
driver.find_element_by_id("kw").send_keys(browser)
driver.find_element_by_id("su").click()
driver.close()

 

启动远程 node

 

我们目前启动的 hub 与 node 都是在一台主机上。 那么要在其它主机启动 node 必须满足以下几个要求:
l 本地 hub 主机与远程 node 主机之间可以相互 ping 通。
l 远程主机必须安装运行脚本的运行环境(Python 、Selenium、浏览器及浏览器驱动 )。
l 远程主机必须安装 java 环境,因为需要运行 Selenium Server。
操作步骤如下:
启动本地 hub 主机(本地主机 IP 为:172.16.10.66):

C:\selenium>java -jar selenium-server-standalone-2.39.0.jar -role hub


启动远程主机(操作系统:Ubuntu ,IP 地址:172.16.10.34):
远程主机启动 node 方式如下:

fnngj@fnngj-VirtualBox:~/selenium$ java -jar selenium-server-standalone-2.39.0ar -role node -port 5555
-hub http://172.16.10.66:4444/grid/register


(设置的端口号为:5555 ,指向的 hub ip 为 172.16.10.66)
修改远程主机的 IP 地址及端口号,在其上面的 firefox 浏览下运行脚本。
hosts.py
……
#定义主机与浏览器
lists={'http://127.0.0.1:4444/wd/hub':'chrome',
'http://127.0.0.1:5555/wd/hub':'internet explorer',
'http://172.16.10.34:5555/wd/hub': 'firefox'}
……

 

小技巧:
自从使用 Selenium Server 执行自动化脚本后,常常会因为忘记启动 Selenium Server 导致脚本运行
报错。其实我们以在脚本中执行 cmd 命令。如在我们创建的 all_test.py 文件中添加:
import os
os.chdir('E:\\selenium')
os.system('java -jar selenium-server-standalone-2.39.0.jar')
这样就再也不会因为忘记启动 Selenium Server 导致测试脚本运行失败了

 

 

 

https://www.cnblogs.com/yufeihlf/p/5764099.html

 

http://blog.csdn.net/boonya/article/details/55049483

转载于:https://my.oschina.net/u/3447023/blog/1928742

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值