目录
一、基础准备
1. 环境搭建
工欲善其事必先利其器,废话不多说。我们先开始搭建环境。
# 创建项目目录
mkdir WebTesting
# 切换到项目目录下
cd WebTesting
# 安装虚拟环境创建工具
pip install virtualenv
# 创建虚拟环境,env代表虚拟环境的名称,可自行定义
virtualenv env
# 启动虚拟环境,执行下面命令后会发现路径上有 (env) 字样的标识
source env/Scripts/activate
# 查看 (env) 环境下使用的 Python 和 pip 工具版本
ls env/Scripts/
# *** 安装 Selenium ***
pip install selenium
# 退出虚拟环境,退出后路径上的 (env) 字样的标识消失
cd env/Scripts/
deactivate
# 导出环境所需要的模块的清单
pip freeze >> requirements.txt
# 上传 GitHub 时,将下面项忽略上传
echo env/ >> .gitignore
echo WebTesting.iml >> .gitignore
echo __pycache__/ >> .gitignore
# 将代码传至 GitHub
# 本地仓初始化
git init
# 创建本地仓与 GitHub 仓的远程链接
git remote add github 你的github仓的地址
# 将代码添加到暂存区
git add .
# 将代码提交到
git commit -m "init environment"
# 将代码上传到GitHub仓中
git push github master
初始化环境的项目结构示例如下:
2. Selenium 原理
Selenium 是一套完整的 web 应用程序测试系统 ,它包含了测试录制(Selenium IDE)、编写及运行(Selenium Remote Control) 和测试的并行处理(Selenium Grid)。Selenium的核心 Selenium Core基于 JsUnit,完全由 JavaScript 编写,因此可以运行于任何支持 JavaScript 的浏览器上。其基本原理如下:
2.1 设置浏览器驱动
from selenium import webdriver
driver = webdriver.Firefox() # Firefox浏览器
driver = webdriver.Chrome() # Chrome浏览器
driver = webdriver.Ie() # Ie浏览器
driver = webdriver.Edge() # Edge浏览器
driver = webdriver.PhantomJS() # PhantomJS()
2.2 Selenium元素定位
<html>
<head>
<body link="#0000cc">
<a id="result_logo" href="/" onmousedown="return c({'fm':'tab','tab':'logo'})">
<form id="form" class="fm" name="f" action="/s">
<span class="soutu-btn"></span>
<input id="kw" class="s_ipt" name="wd" value="" maxlength="255" autocomplete="off">
# 通过 id 定位
dr.find_element_by_id("kw")
# 通过name定位:
dr.find_element_by_name("wd")
# 通过class name定位:
dr.find_element_by_class_name("s_ipt")
# 通过tag name定位:
dr.find_element_by_tag_name("input")
# 通过 xpath 定位的几种写法
dr.find_element_by_xpath("//*[@id='kw']")
dr.find_element_by_xpath("//*[@name='wd']")
dr.find_element_by_xpath("//input[@class='s_ipt']")
dr.find_element_by_xpath("/html/body/form/span/input")
dr.find_element_by_xpath("//span[@class='soutu-btn']/input")
dr.find_element_by_xpath("//form[@id='form']/span/input")
dr.find_element_by_xpath("//input[@id='kw' and @name='wd']")
# 通过 css 定位的几种写法
dr.find_element_by_css_selector("#kw")
dr.find_element_by_css_selector("[name=wd]")
dr.find_element_by_css_selector(".s_ipt")
dr.find_element_by_css_selector("html > body > form > span > input")
dr.find_element_by_css_selector("span.soutu-btn> input#kw")
dr.find_element_by_css_selector("form#form > span > input")
# 通过 link_text 定位
dr.find_element_by_link_text("新闻")
dr.find_element_by_link_text("hao123")
dr.find_element_by_partial_link_text("新")
dr.find_element_by_partial_link_text("hao")
dr.find_element_by_partial_link_text("123")
# 如果是定位一组元素,用下面
find_elements_by_id()
find_elements_by_name()
find_elements_by_class_name()
find_elements_by_tag_name()
find_elements_by_link_text()
find_elements_by_partial_link_text()
find_elements_by_xpath()
find_elements_by_css_selector()
2.3 控制浏览器操作
(1) 控制浏览器窗口大小
WebDriver中 set_window_size() 方法来设置浏览器窗口的大小;maximize_window() 使打开的浏览器全屏显示。 【GitHub示例】
from selenium import Webdriver
driver = Webdriver.Chrome('../tools/chromedriver.exe')
driver.get_url('http://www.5itest.cn/register')
# 设置浏览器窗口大小
print("设置浏览器宽500,高600")
driver.set_window_size()
driver.quit()
(2) 控制浏览器后退、前进
webdriver 提供了对应的 back() 和 forward() 方法来模拟后退和前进按钮。【GitHub示例】
from selenium import webdriver
import time
# 2. 控制浏览器的前进、后退
browser_links = webdriver.Chrome('../tools/chromedriver.exe')
first_url = 'https://www.baidu.com/'
second_url = 'https://news.baidu.com/'
print("访问第一个链接:%s" % first_url)
browser_links.get(first_url)
time.sleep(1)
print("访问第二个链接:%s" % second_url)
browser_links.get(second_url)
time.sleep(1)
print("回退到第一个链接:%s" % first_url)
browser_links.back()
time.sleep(1)
print("前进到第二个链接:%s", second_url)
browser_links.forward()
time.sleep(1)
browser_links.quit()
(3) 刷新页面 F5
webdriver中可以用 refresh 方法进行页面刷新。【GitHub代码】
from selenium import webdriver
import time
refresh_url = 'http://www.baidu.com/'
browser_refresh = webdriver.Chrome('../tools/chromedriver.exe')
browser_refresh.get(refresh_url)
time.sleep(2)
browser_refresh.refresh()
browser_refresh.quit()
2.4 webdriver常用方法
webdriver常用方法【GitHub示例】
(1) 点击、输入和清除
定位元素后我们还需要对元素进行操作,常用的元素操作方法有:clear()、send_keys(value)、click()
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : 03_commonMethod.py
@Time : 2021/7/6 12:12
@Author : Crisimple
@Github : https://crisimple.github.io/
@Contact : Crisimple@foxmail.com
@License : (C)Copyright 2019-2021, Micro-Circle
@Desc : None
"""
from selenium import webdriver
import time
base_url = 'https://www.baidu.com'
browser = webdriver.Chrome('../tools/chromedriver.exe')
browser.get(base_url)
# 1. 清除、输入、点击
browser.find_element_by_id('kw').clear()
browser.find_element_by_id('kw').send_keys('python')
browser.find_element_by_id('su').click()
time.sleep(2)
browser.quit()
(2) 提交
submit()方法用于提交表单,在搜索框后输入关键字后,可用于“回车”模拟。
from selenium import webdriver
import time
base_url = 'https://www.baidu.com'
browser = webdriver.Chrome('../tools/chromedriver.exe')
browser.get(base_url)
# 2.提交
search_text = browser.find_element_by_id('kw')
search_text.send_keys('selenium')
search_text.submit()
time.sleep(3)
(3) 其他常用的方法
size: 返回元素的尺寸。
text: 获取元素的文本。
get_attribute(name): 获得属性值。
is_displayed(): 设置该元素是否用户可见。
from selenium import webdriver
import time
base_url = 'https://www.baidu.com'
browser = webdriver.Chrome('../tools/chromedriver.exe')
browser.get(base_url)
# 3. 其他常用方法
size = browser.find_element_by_id('kw').size
print("返回元素的尺寸:%s" % size)
text = browser.find_element_by_id('cp').text
print("返回元素的文本:%s" % text)
attribute = browser.find_element_by_id('kw').get_attribute('type')
print("返回元素的属性:%s" % attribute)
result = browser.find_element_by_id('kw').is_displayed()
print("返回元素是否可见:%s" % result)
browser.quit()
2.5 鼠标事件
在webdriver中,鼠标操作的方法封装在 ActionChains 类提供。ActionChains类提供了鼠标操作的常用方法:【GitHub示例】
ActionChains(driver),将浏览器驱动 driver 作为参数传入。
(1) perform(): 执行所有 ActionChains 中存储的行为,是对整个操作的提交动作;
(2) context_click(): 右击
(3) double_click(): 双击
(4) drag_and_drop(): 拖动
(5) move_to_element(): 鼠标悬停, 在调用时需要指定元素定位
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : 04_mouseEvent.py
@Time : 2021/7/6 16:59
@Author : Crisimple
@Github : https://crisimple.github.io/
@Contact : Crisimple@foxmail.com
@License : (C)Copyright 2019-2021, Micro-Circle
@Desc : None
"""
from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
import time
base_url = 'http://www.baidu.com/'
browser = webdriver.Chrome('../tools/chromedriver.exe')
browser.get(base_url)
# 定位到悬停元素处
above = browser.find_element_by_link_text('设置')
# 对元素执行鼠标悬停操作
ActionChains(browser).move_to_element(above).perform()
time.sleep(5)
# 右击
ActionChains(browser).context_click().perform()
time.sleep(5)
# 定位到要双击的元素处
# double_click_element = browser.find_element_by_link_text('新闻')
# print(double_click_element)
# ActionChains(browser).move_to_element(double_click_element).double_click().perform()
# time.sleep(5)
# 拖动元素
drag_and_drop_element = browser.find_element_by_link_text('地图')
ActionChains(browser).move_to_element(drag_and_drop_element).drag_and_drop().perform()
time.sleep(5)
browser.quit()
2.6 键盘事件
前面的 send_keys() 方法用来模拟键盘输入;keys() 类提供了键盘上几乎所有按键的方法,组合键也是可以的。【GitHub示例】
常用的键盘操作如下:
send_keys(Keys.BACK_SPACE) 删除键(BackSpace)
send_keys(Keys.SPACE) 空格键(Space)
send_keys(Keys.TAB) 制表键(Tab)
send_keys(Keys.ESCAPE) 回退键(Esc)
send_keys(Keys.ENTER) 回车键(Enter)
send_keys(Keys.CONTROL,'a') 全选(Ctrl+A)
send_keys(Keys.CONTROL,'c') 复制(Ctrl+C)
send_keys(Keys.CONTROL,'x') 剪切(Ctrl+X)
send_keys(Keys.CONTROL,'v') 粘贴(Ctrl+V)
send_keys(Keys.F1) 键盘 F1
……
send_keys(Keys.F12) 键盘 F12
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : 05_keyboardEvent.py
@Time : 2021/7/6 22:22
@Author : Crisimple
@Github : https://crisimple.github.io/
@Contact : Crisimple@foxmail.com
@License : (C)Copyright 2019-2021, Micro-Circle
@Desc : None
"""
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time
base_url = 'https://www.baidu.com/'
driver = webdriver.Chrome('../tools/chromedriver.exe')
driver.get(base_url)
# 先输入百度
driver.find_element_by_id('kw').send_keys('百度')
# 1.删除度
driver.find_element_by_id('kw').send_keys(Keys.BACK_SPACE)
time.sleep(3)
# 2.键入空格
driver.find_element_by_id('kw').send_keys(Keys.SPACE)
driver.find_element_by_id('kw').send_keys('加入空格')
time.sleep(5)
# 3.ctrl+a 全选输入框里的内容
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'a')
time.sleep(3)
# 4.ctrl+x 剪切输入框里的内容
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'x')
time.sleep(3)
# 5. ctrl+v 粘贴剪切的内容
driver.find_element_by_id('kw').send_keys(Keys.CONTROL, 'v')
time.sleep(3)
# 6. 回车
driver.find_element_by_id('su').send_keys(Keys.ENTER)
time.sleep(3)
driver.quit()
2.7 获取断言信息
测试时需要拿实际结果与预期结果进行比较,这个比较称为 断言,通常可以获取断言元素有:【GitHub示例】
(1)title:当前页面的标题
(2)current_url:当前页面的URL
(3)text:获取元素的文本信息
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : 06_asseert.py
@Time : 2021/7/6 23:23
@Author : Crisimple
@Github : https://crisimple.github.io/
@Contact : Crisimple@foxmail.com
@License : (C)Copyright 2017-2019, Micro-Circle
@Desc : None
"""
from selenium import webdriver
import time
base_url = 'https://www.baidu.com/'
driver = webdriver.Chrome('../tools/chromedriver.exe')
driver.get(base_url)
time.sleep(1)
print("直接访问链接后页面元素获取")
title = driver.title
print('first title: %s' % title)
current_url = driver.current_url
print('first current_url: %s' % current_url)
driver.find_element_by_id('kw').send_keys('python')
driver.find_element_by_id('su').click()
time.sleep(1)
print('搜索关键词后页面元素获取')
title2 = driver.title
print('second title: %s' % title2)
current_url2 = driver.current_url
print('first current_url2: %s ' % current_url2)
kw_text = driver.find_element_by_id('kw').text
print('nums text: %s' % kw_text)
driver.quit()
2.8 设置元素等待
webdriver提供了两种等待方式:显示等待和隐式等待。
(1) 显示等待使webdrver 等待某条件成立时继续执行,否则在达到最大时长时抛出超时异常(TimeoutException)。【GitHub示例】
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
"""
@File : 07_wait.py
@Time : 2021/7/6 14:01
@Author : Crisimple
@Github : https://crisimple.github.io/
@Contact : Crisimple@foxmail.com
@License : (C)Copyright 2019-2021, Micro-Circle
@Desc : None
"""
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
base_url = 'http://www.baidu.com/'
driver = webdriver.Chrome('../tools/chromedriver.exe')
driver.get(base_url)
# 1.显示等待
# WebDriverWait(driver, timeout, poll_frequency=0.5, ignored_exceptions=None)
# driver :浏览器驱动。
# timeout :最长超时时间,默认以秒为单位。
# poll_frequency :检测的间隔(步长)时间,默认为0.5S。
# ignored_exceptions :超时后的异常信息,默认情况下抛NoSuchElementException异常
# until(method, message=‘’)-----调用该方法提供的驱动程序作为一个参数,直到返回值为True。
# until_not(method, message=‘’)---调用该方法提供的驱动程序作为一个参数,直到返回值为False。
# presence_of_element_located()方法判断元素是否存在。
element = WebDriverWait(driver, 5, 0.5).until(
EC.presence_of_element_located((By.ID, 'kw'))
)
element.send_keys('要搜索的内容')
time.sleep(3)
driver.quit()
(2) 隐式等待:WebDriver提供了implicitly_wait()方法实现隐式等待,默认设置为0。假设在第6秒定位到了元素则继续执行,若直到超出设置时长(10秒)还没有定位到元素,则抛出异常。它的设置并不影响程序的执行速度。【GitHub示例】
# 2. 隐式等待
from selenium.common.exceptions import NoSuchElementException
from selenium import webdriver
from time import ctime
import time
base_url2 = 'https://www.baidu.com/'
browser = webdriver.Chrome('../tools/chromedriver.exe')
# 设置隐式等待为10s
browser.implicitly_wait(10)
browser.get(base_url2)
try:
print(ctime())
browser.find_element_by_id('kw').send_keys('se')
time.sleep(3)
except NoSuchElementException as e:
print(e)
finally:
print(ctime())
browser.quit()
2.9 多窗口切换
在页面操作过程中有时候点击某个链接会弹出新的窗口,这时就需要主机切换到新打开的窗口上进行操作。webdriver 中的 switch_to.window() 方法,可以