Web自动化测试
接python基础后的课程
自动化测试的误区:
- 自动化测试完全替代手工测试
- 自动化测试一定比手工测试厉害
- 自动化可以发掘更多的BUG
什么项目适合自动化测试
- 需求变动不频繁
- 项目周期长
- 项目需要回归测试
本次课程仅以Chorme为例
1.环境准备
pip install selenium
浏览器驱动下载,并配置环境变量,注意要下载自己浏览器对应版本的驱动。
启动浏览器
from selenium import webdriver
browser = webdriver.Chrome()
# browser = webdriver.Firefox()
# browser = webdriver.Ie()
browser.get('http://www.baidu.com/')
2.网页结构以及元素定位
2.1 网页结构
html构成的基础结构,按F12或则右键->检查可查看。
css确定了网页的排版样式,JavaScript决定了网页的可塑造性和动态呈现。
实例
2.2 元素定位
- id定位:find_element_by_id()
- name定位:find_element_by_name()
- class定位:find_element_by_class_name()
- link定位:find_element_by_link_text()
- partial link定位:find_element_by_partial_link_text()
- tag定位:find_element_by_tag_name()
- xpath定位:find_element_by_xpath()
- css定位:find_element_by_css_selector()
#coding=utf-8
from selenium import webdriver
import time
browser=webdriver.Chrome()
browser.get("http://www.baidu.com")
#通过id方式定位
browser.find_element_by_id("kw").send_keys("selenium")
#通过name方式定位
browser.find_element_by_name("wd").send_keys("selenium")
#通过tag name方式定位
browser.find_element_by_tag_name("input").send_keys("selenium")
#通过class name方式定位
browser.find_element_by_class_name("s_ipt").send_keys("selenium")
#通过xpath方式定位
browser.find_element_by_xpath("//input[@id='kw']").send_keys("selenium")
browser.find_element_by_id("su").click()
time.sleep(3)
browser.quit()
以下xpath/css的定位方式先不用掌握,有个概念,用的着后再来找
描述 | xpath | css |
---|---|---|
直接子元素 | //div/a | div > a |
子元素或后代元素 | //div//a | div a |
以id定位 | //div[@id=‘idValue’]//a | div#idValue a |
以class定位 | //div[@class=‘classValue’]//a | div.classValue a |
同级弟弟元素 | //ul/li[@class=‘first’]/following- | ul>li.first + li |
属性 | //form/input[@name=‘username’] | form input[name=‘username’] |
多个属性 | //input[@name=‘continue’ and @type=‘button’] | input[name=‘continue’][type=‘button’] |
第4个子元素 | //ul[@id=‘list’]/li[4] | ul#list li:nth-child(4) |
最后1个子元素 | //ul[@id=‘list’]/li[last()] | ul#list li:last-child |
属性包含某字段 | //div[contains(@title,‘Title’)] | div[title*=“Title”] |
属性以某字段开头 | //input[starts-with(@name,‘user’)] | input[name^=“user”] |
属性以某字段结尾 | //input[ends-with(@name,‘name’)] | input[name$=“name”] |
text中包含某字段 | //div[contains(text(), ‘text’)] | 无法定位 |
元素有某属性 | //div[@title] | div[title] |
父节点 | //div/… | 无法定位 |
同级哥哥节点 | //li/preceding-sibling::div[1] | 无法定位 |
find_element与find_elements,find_element返回单个元素object,存在多个时返回第一个,find_elements返回所有元素object 的列表,不存在时返回空列表
多级定位,driver.find_element().find_element()…
2.3 元素操作
- click——点击对象
- send_keys——在对象上模拟按键输入
- clear——清除对象的内容,如果可以的话
- submit——提交对象的内容,如果可以的话
- text——用于获取元素的文本信息
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.keys import Keys #需要引入 keys 包
import time
browser=webdriver.Chrome()
browser.get("http://www.baidu.com")
browser.find_element_by_id("kw").send_keys("selenium")
browser.find_element_by_id("kw").clear()
# browser.find_element_by_id("kw").send_keys(Keys.ENTER)
browser.find_element_by_id("su").click()
browser.find_element_by_id("su").text
time.sleep(3)
browser.quit()
键盘/鼠标事件
键盘事件上面已经介绍了,下面来介绍一下鼠标事件,常用的包括双击,悬浮,拖拽,右击
from selenium.webdriver.common.action_chains import ActionChains
# context_click() 右击;
# double_click() 双击;
# drag_and_drop() 拖动;
# move_to_element() 鼠标悬停。
#定位到要双击的元素
qqq =driver.find_element_by_xpath("xxx")
#对定位到的元素执行鼠标双击操作
ActionChains(driver).double_click(qqq).perform()
#定位元素的原位置
element = driver.find_element_by_name("source")
#定位元素要移动到的目标位置
target = driver.find_element_by_name("target")
#执行元素的移动操作
ActionChains(driver).drag_and_drop(element, target).perform()
2.4 三种等待方式
强制等待 time.sleep()
隐式等待,隐性等待对整个driver的周期都起作用,所以只要设置一次即可
# -*- coding: utf-8 -*-
from selenium import webdriver
driver = webdriver.Firefox()
driver.implicitly_wait(30) # 隐性等待,最长等30秒
driver.get('http://baidu.com')
print(driver.current_url)
driver.quit()
显示等待,多用于等待某个元素出现
#coding=utf-8
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
base_url = "http://www.baidu.com"
driver = webdriver.Firefox()
driver.implicitly_wait(5)
'''隐式等待和显示等待都存在时,超时时间取二者中较大的'''
locator = (By.ID,'kw')
driver.get(base_url)
WebDriverWait(driver,10).until(EC.title_is(u"百度一下,你就知道"))
'''判断title,返回布尔值'''
WebDriverWait(driver,10).until(EC.title_contains(u"百度一下"))
'''判断title,返回布尔值'''
WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw')))
'''判断某个元素是否被加到了dom树里,并不代表该元素一定可见,如果定位到就返回WebElement'''
WebDriverWait(driver,10).until(EC.visibility_of_element_located((By.ID,'su')))
'''判断某个元素是否被添加到了dom里并且可见,可见代表元素可显示且宽和高都大于0'''
WebDriverWait(driver,10).until(EC.visibility_of(driver.find_element(by=By.ID,value='kw')))
'''判断元素是否可见,如果可见就返回这个元素'''
WebDriverWait(driver,10).until(EC.presence_of_all_elements_located((By.CSS_SELECTOR,'.mnav')))
'''判断是否至少有1个元素存在于dom树中,如果定位到就返回列表'''
WebDriverWait(driver,10).until(EC.visibility_of_any_elements_located((By.CSS_SELECTOR,'.mnav')))
'''判断是否至少有一个元素在页面中可见,如果定位到就返回列表'''
WebDriverWait(driver,10).until(EC.text_to_be_present_in_element((By.XPATH,"//*[@id='u1']/a[8]"),u'设置'))
'''判断指定的元素中是否包含了预期的字符串,返回布尔值'''
WebDriverWait(driver,10).until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR,'#su'),u'百度一下'))
'''判断指定元素的属性值中是否包含了预期的字符串,返回布尔值'''
#WebDriverWait(driver,10).until(EC.frame_to_be_available_and_switch_to_it(locator))
'''判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False'''
#注意这里并没有一个frame可以切换进去
WebDriverWait(driver,10).until(EC.invisibility_of_element_located((By.CSS_SELECTOR,'#swfEveryCookieWrap')))
'''判断某个元素在是否存在于dom或不可见,如果可见返回False,不可见返回这个元素'''
#注意#swfEveryCookieWrap在此页面中是一个隐藏的元素
WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='u1']/a[8]"))).click()
'''判断某个元素中是否可见并且是enable的,代表可点击'''
driver.find_element_by_xpath("//*[@id='wrapper']/div[6]/a[1]").click()
#WebDriverWait(driver,10).until(EC.element_to_be_clickable((By.XPATH,"//*[@id='wrapper']/div[6]/a[1]"))).click()
#WebDriverWait(driver,10).until(EC.staleness_of(driver.find_element(By.ID,'su')))
'''等待某个元素从dom树中移除'''
#这里没有找到合适的例子
WebDriverWait(driver,10).until(EC.element_to_be_selected(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]")))
'''判断某个元素是否被选中了,一般用在下拉列表'''
WebDriverWait(driver,10).until(EC.element_selection_state_to_be(driver.find_element(By.XPATH,"//*[@id='nr']/option[1]"),True))
'''判断某个元素的选中状态是否符合预期'''
WebDriverWait(driver,10).until(EC.element_located_selection_state_to_be((By.XPATH,"//*[@id='nr']/option[1]"),True))
'''判断某个元素的选中状态是否符合预期'''
driver.find_element_by_xpath(".//*[@id='gxszButton']/a[1]").click()
instance = WebDriverWait(driver,10).until(EC.alert_is_present())
'''判断页面上是否存在alert,如果有就切换到alert并返回alert的内容'''
print instance.text
instance.accept()
driver.close()
2.5 浏览器操作
将浏览器最大化显示
browser.maximize_window()
将浏览器最小化显示
browser.minimize_window()
设置浏览器宽480、高800显示
browser.set_window_size(480, 800)
前进
browser.forword()
后退
browser.back()
定位元素过程中经常会遇到找不到元素的问题,出现该问题一般都是以下因素导致:
- 元素定位方法不对
- 页面存在iframe(内嵌窗口)
- 页面超时
其中,页面存在iframe webdriver 提供了一个 switch_to_frame 方法
#先找到到 iframe1(id = f1)browser.switch_to_frame("f1")