selenium 学习
启动
firefox
安装foxmail driver
https://github.com/mozilla/geckodriver/releases
这里写了当前driver满足的版本问题
这里用的虚拟环境 非虚拟环境直接放到使用的python的scripts目录下即可 保持与使用的python同级目录
pip3 install selenium
开个firefox
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("http://www.baidu.com/")
他说找不到moz:firefoxOptions.binary 也就是找不到firefox的二进制文件
那么我们就添加上
Chrome
一键搭建
pip3 install webdriver-helper==1.0.1
import time
from webdriver_helper import *
driver = get_webdriver()
# 默认chrome
driver.get("http://baidu.com")
# 访问百度
time.sleep(3)
driver.quit()
import time
from webdriver_helper import *
with get_webdriver() as driver:
#类似文件操作
driver.get("http://baidu.com")
元素定位
根据文本定位
import time
from selenium.webdriver.common.by import By
from webdriver_helper import *
with get_webdriver() as driver:
#类似文件操作
driver.get("http://101.34.221.219:8010/")
time.sleep(3)
el = driver.find_element(By.LINK_TEXT,"登录")
print(el)
# 通过文本定位一个元素
el2 = driver.find_element(By.PARTIAL_LINK_TEXT,"登")
print(el2)
属性定位
<input id="search-input" name="wd" type="text" placeholder="其实搜索很简单^_^ !" value="" autocomplete="off">
el = driver.find_element(By.ID,"search-input")
el = driver.find_element(By.NAME,"wd")
el = driver.find_element(By.CLASS_NAME,"search-group")
el = driver.find_element(By.TAG_NAME,"search-group")
通用定位
driver.find_element(By.CSS_SELECTOR,"#search-input")
driver.find_element(By.XPATH,"/html/body/div[6]/div/div[1]/div[2]/a[1]")
XPATH选择器
语法
- / (开头) 根路径 /html/body/div
- // 任意层级(包括下级 下级的下级) //div
- @属性 //a[@target=“_top”]
- /(中间) 下一级 //p/input
- . 本级
- … 上一级
函数
-
text 获取元素内的文本
$x("//a[text()='vivo X5MAX L 移动4G 八核超薄大屏5.5吋双卡手机vivoX5max']")
-
contains 任意位置包含
$x("//a[contains(text(),'vivo')]")
-
starts-with 开头
$x("//a[starts-with(text(),'vivo')]")
实践
登录一闪而过
使用debugger 进行停止
先在控制台输入debugger 点击登录之后立即按回车
import pdb
import time
from selenium.webdriver.common.by import By
from webdriver_helper import *
# <input id="search-input" name="wd" type="text" placeholder="其实搜索很简单^_^ !" value="" autocomplete="off">
with get_webdriver() as driver:
#类似文件操作
driver.get("http://101.34.221.219:8010/")
driver.maximize_window()
# 窗口最大化
driver.find_element(By.XPATH,'//a[text()="登录"]').click()
time.sleep(0.5)
driver.find_element(By.XPATH,'//input[@data-validation-message="请填写登录账号"]').send_keys("wanan")
driver.find_element(By.XPATH,'//input[@placeholder="请输入登录密码"]').send_keys("123123")
driver.find_element(By.XPATH,'//button[text()="登录"]').click()
time.sleep(0.5)
msg = driver.find_element(By.XPATH,'//p[@class="prompt-msg"]').text
assert msg=="登录成功"
time.sleep(3)
driver.find_element(By.XPATH,'//a[text()="vivo X5MAX L 移动4G 八核超薄大屏5.5吋双卡手机vivoX5max"]').click()
# print(driver.current_window_handle)
# 打印当前的窗口 id
# print(driver.window_handles[1])
# 打印所有的窗口 id 中的第2个
driver.switch_to.window(driver.window_handles[1])
print(driver.current_url)
# 打印当前窗口的url
driver.find_element(By.ID,"text_box").send_keys("2")
driver.find_element(By.XPATH,'//button[@title="点此按钮到下一步确认购买信息"]').click()
driver.switch_to.alert.accept()
# 接受弹框
driver.find_element(By.XPATH,'//span[text()="货到付款"]').click()
driver.switch_to.alert.accept()
driver.find_element(By.XPATH,'//button[@title="点击此按钮,提交订单"]').click()
time.sleep(0.5)
msg = driver.find_element(By.XPATH,'//p[@class="prompt-msg"]').text
assert msg=="操作成功"
pytest
pip3 install pytest
import time
from selenium.webdriver.common.by import By
from webdriver_helper import get_webdriver
def test_login_ok():
with get_webdriver() as driver:
# 类似文件操作
driver.get("http://101.34.221.219:8010/")
driver.maximize_window()
# 窗口最大化
driver.find_element(By.XPATH, '//a[text()="登录"]').click()
time.sleep(0.5)
driver.find_element(By.XPATH, '//input[@data-validation-message="请填写登录账号"]').send_keys("wanan")
driver.find_element(By.XPATH, '//input[@placeholder="请输入登录密码"]').send_keys("123123")
driver.find_element(By.XPATH, '//button[text()="登录"]').click()
time.sleep(0.5)
msg = driver.find_element(By.XPATH, '//p[@class="prompt-msg"]').text
assert msg == "登录成功"
def test_login_fail():
with get_webdriver() as driver:
# 类似文件操作
driver.get("http://101.34.221.219:8010/")
driver.maximize_window()
# 窗口最大化
driver.find_element(By.XPATH, '//a[text()="登录"]').click()
time.sleep(0.5)
driver.find_element(By.XPATH, '//input[@data-validation-message="请填写登录账号"]').send_keys("wanan")
driver.find_element(By.XPATH, '//input[@placeholder="请输入登录密码"]').send_keys("123123123123")
driver.find_element(By.XPATH, '//button[text()="登录"]').click()
time.sleep(0.5)
msg = driver.find_element(By.XPATH, '//p[@class="prompt-msg"]').text
assert msg == "密码错误"
def test_order_ok():
with get_webdriver() as driver:
driver.get("http://101.34.221.219:8010/")
driver.maximize_window()
driver.find_element(By.XPATH, '//a[text()="vivo X5MAX L 移动4G 八核超薄大屏5.5吋双卡手机vivoX5max"]').click()
# print(driver.current_window_handle)
# 打印当前的窗口 id
# print(driver.window_handles[1])
# 打印所有的窗口 id 中的第2个
driver.switch_to.window(driver.window_handles[1])
print(driver.current_url)
# 打印当前窗口的url
driver.find_element(By.ID, "text_box").send_keys("2")
driver.find_element(By.XPATH, '//button[@title="点此按钮到下一步确认购买信息"]').click()
driver.switch_to.alert.accept()
# 接受弹框
driver.find_element(By.XPATH, '//span[text()="货到付款"]').click()
driver.switch_to.alert.accept()
driver.find_element(By.XPATH, '//button[@title="点击此按钮,提交订单"]').click()
time.sleep(0.5)
msg = driver.find_element(By.XPATH, '//p[@class="prompt-msg"]').text
assert msg == "操作成功"
由于这里没有登录 因此这里未通过
夹具
import time
import pytest
from selenium.webdriver.common.by import By
from webdriver_helper import get_webdriver
@pytest.fixture()
# 添加装饰器
def driver():
driver = get_webdriver()
# 添加一个函数
return driver
def test_login_ok(driver):
#在测试中添加 夹具函数名字
driver.get("http://101.34.221.219:8010/")
driver.maximize_window()
# 窗口最大化
driver.find_element(By.XPATH, '//a[text()="登录"]').click()
time.sleep(0.5)
driver.find_element(By.XPATH, '//input[@data-validation-message="请填写登录账号"]').send_keys("wanan")
driver.find_element(By.XPATH, '//input[@placeholder="请输入登录密码"]').send_keys("123123")
driver.find_element(By.XPATH, '//button[text()="登录"]').click()
time.sleep(0.5)
msg = driver.find_element(By.XPATH, '//p[@class="prompt-msg"]').text
assert msg == "登录成功"
夹具的范围
这种写法会启动两次
@pytest.fixture()
def driver():
driver = get_webdriver()
driver.maximize_window()
driver.get("http://101.34.221.219:8010/")
# 前置部分,在测试用例之前执行
yield driver
# 后置部分,在测试用例之后执行
print("测试用例执行完成")
driver.quit()
scope
- function 默认 每个用例执行一次
- class 每个类执行一次
- module 每个文件执行一次
- package 每个包只执行一次
- session 整个测试过程执行一次
@pytest.fixture(scope="session")
def driver():
注意修改的代码
import time
import pytest
from selenium.webdriver.common.by import By
from webdriver_helper import get_webdriver
@pytest.fixture(scope="session")
def driver():
driver = get_webdriver()
driver.maximize_window()
driver.get("http://101.34.221.219:8010/")
# 前置部分,在测试用例之前执行
yield driver
# 后置部分,在测试用例之后执行
print("测试用例执行完成")
driver.quit()
@pytest.fixture(scope="session")
def user_driver():
driver = get_webdriver()
driver.maximize_window()
# 前置部分,在测试用例之前执行
# 登录页面
driver.get("http://101.34.221.219:8010/?s=user/logininfo.html")
driver.find_element(By.XPATH, '//input[@data-validation-message="请填写登录账号"]').send_keys("wanan")
driver.find_element(By.XPATH, '//input[@placeholder="请输入登录密码"]').send_keys("123123")
driver.find_element(By.XPATH, '//button[text()="登录"]').click()
time.sleep(0.5)
msg = driver.find_element(By.XPATH, '//p[@class="prompt-msg"]').text
assert msg == "登录成功"
yield driver
# 后置部分,在测试用例之后执行
print("测试用例执行完成")
driver.quit()
def test_login_ok(driver):
driver.get("http://101.34.221.219:8010/")
# 窗口最大化
driver.find_element(By.XPATH, '//a[text()="登录"]').click()
time.sleep(0.5)
driver.find_element(By.XPATH, '//input[@data-validation-message="请填写登录账号"]').send_keys("wanan")
driver.find_element(By.XPATH, '//input[@placeholder="请输入登录密码"]').send_keys("123123")
driver.find_element(By.XPATH, '//button[text()="登录"]').click()
time.sleep(0.5)
msg = driver.find_element(By.XPATH, '//p[@class="prompt-msg"]').text
assert msg == "登录成功"
def test_login_fail(driver):
driver.delete_all_cookies()
# 删除所有cookies
driver.get("http://101.34.221.219:8010/")
driver.maximize_window()
# 窗口最大化
driver.find_element(By.XPATH, '//a[text()="登录"]').click()
time.sleep(0.5)
driver.find_element(By.XPATH, '//input[@data-validation-message="请填写登录账号"]').send_keys("wanan")
driver.find_element(By.XPATH, '//input[@placeholder="请输入登录密码"]').send_keys("123123123123")
driver.find_element(By.XPATH, '//button[text()="登录"]').click()
time.sleep(0.5)
msg = driver.find_element(By.XPATH, '//p[@class="prompt-msg"]').text
assert msg == "密码错误"
def test_order_ok(user_driver):
# 注意这里需要修改成 user_driver
user_driver.get("http://101.34.221.219:8010/")
user_driver.find_element(By.XPATH, '//a[text()="vivo X5MAX L 移动4G 八核超薄大屏5.5吋双卡手机vivoX5max"]').click()
# print(driver.current_window_handle)
# 打印当前的窗口 id
# print(driver.window_handles[1])
# 打印所有的窗口 id 中的第2个
user_driver.switch_to.window(user_driver.window_handles[1])
print(user_driver.current_url)
# 打印当前窗口的url
user_driver.find_element(By.ID, "text_box").send_keys("2")
user_driver.find_element(By.XPATH, '//button[@title="点此按钮到下一步确认购买信息"]').click()
user_driver.switch_to.alert.accept()
# 接受弹框
user_driver.find_element(By.XPATH, '//span[text()="货到付款"]').click()
user_driver.switch_to.alert.accept()
user_driver.find_element(By.XPATH, '//button[@title="点击此按钮,提交订单"]').click()
time.sleep(0.5)
msg = user_driver.find_element(By.XPATH, '//p[@class="prompt-msg"]').text
assert msg == "操作成功"
pages.py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.expected_conditions import *
class BasePage:
_loc_msg ='//p[@class="prompt-msg"]'
def __init__(self,driver: webdriver.Chrome):
# 在实例化是创建的
self._driver = driver
self._wait = WebDriverWait(driver,10)
# 用来处理浏览器的等待时间 最长时间为10秒
def __getattr__(self, item):
key = f"_loc_"+item
xpath = getattr(self,key)
if xpath:
return self.get_element(xpath)
raise AttributeError("属性不存在异常")
def get_element(self,xpath):
"""
元素定位会自动等待
:param xpath:
:return:
"""
el = self._wait.until(
visibility_of_element_located((By.XPATH,xpath))
# 直到找到xpath结束 否则执行 10秒
)
return el
def alert_ok(self):
alert = self._wait.until(alert_is_present())
# 等待弹窗出现
alert.accept()
# 点击接受
class LoginPage(BasePage):
_loc_username = '//input[@data-validation-message="请填写登录账号"]'
_loc_password = '//input[@placeholder="请输入登录密码"]'
_loc_btn = '//button[text()="登录"]'
def login(self,username,password):
self.username.send_keys(username)
self.password.send_keys(password)
self.btn.click()
import time
import pytest
from selenium.webdriver.common.by import By
from webdriver_helper import get_webdriver
from pages import *
@pytest.fixture(scope="session")
def driver():
driver = get_webdriver()
driver.maximize_window()
driver.get("http://101.34.221.219:8010/")
# 前置部分,在测试用例之前执行
yield driver
# 后置部分,在测试用例之后执行
print("测试用例执行完成")
driver.quit()
@pytest.fixture(scope="session")
def user_driver():
driver = get_webdriver()
driver.maximize_window()
# 前置部分,在测试用例之前执行
# 登录页面
driver.get("http://101.34.221.219:8010/?s=user/logininfo.html")
driver.find_element(By.XPATH, '//input[@data-validation-message="请填写登录账号"]').send_keys("wanan")
driver.find_element(By.XPATH, '//input[@placeholder="请输入登录密码"]').send_keys("123123")
driver.find_element(By.XPATH, '//button[text()="登录"]').click()
time.sleep(0.5)
msg = driver.find_element(By.XPATH, '//p[@class="prompt-msg"]').text
assert msg == "登录成功"
yield driver
# 后置部分,在测试用例之后执行
print("测试用例执行完成")
driver.quit()
def test_login_ok(driver):
driver.get("http://101.34.221.219:8010/?s=user/logininfo.html")
page = LoginPage(driver)
page.login("wanan","123123")
assert page.msg.text == "登录成功"
不同参数测试
import pytest
def test_a():
print("这是个测试用例")
@pytest.mark.parametrize('i',range(5))
def test_b(i):
print(f"这是第{i}个测试用例")
多组测试用例 测试添加地址
pages.py
import pdb
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support.expected_conditions import *
class BasePage:
_loc_msg ='//p[@class="prompt-msg"]'
def __init__(self,driver: webdriver.Chrome):
# 在实例化是创建的
self._driver = driver
self._wait = WebDriverWait(driver,10)
# 用来处理浏览器的等待时间 最长时间为10秒
def __getattr__(self, item):
key = f"_loc_"+item
xpath = getattr(self,key)
if xpath:
return self.get_element(xpath)
raise AttributeError("属性不存在异常")
def get_element(self,xpath):
"""
元素定位会自动等待
:param xpath:
:return:
"""
el = self._wait.until(
visibility_of_element_located((By.XPATH,xpath))
# 直到找到xpath结束 否则执行 10秒
)
return el
def alert_ok(self):
alert = self._wait.until(alert_is_present())
# 等待弹窗出现
alert.accept()
# 点击接受
class LoginPage(BasePage):
_loc_username = '//input[@data-validation-message="请填写登录账号"]'
_loc_password = '//input[@placeholder="请输入登录密码"]'
_loc_btn = '//button[text()="登录"]'
def login(self,username,password):
self.username.send_keys(username)
self.password.send_keys(password)
self.btn.click()
class AddressPage(BasePage):
_loc_new = '//button[@data-popup-title="新增地址"]'
_loc_name = '/html/body/div[1]/form/div[2]/input'
_loc_tel = '/html/body/div[1]/form/div[3]/input'
_loc_sheng = '/html/body/div[1]/form/div[4]/div[1]'
_loc_shi = '/html/body/div[1]/form/div[4]/div[2]'
_loc_qu = '/html/body/div[1]/form/div[4]/div[3]'
_loc_addr = '//*[@id="form-address"]'
_loc_btn = "/html/body/div[1]/form/div[7]/button"
def click_new(self):
self.new.click()
self.alert_ok()
iframe = self.get_element('//iframe[@src="http://101.34.221.219:8010/?s=useraddress/saveinfo.html"]')
self._driver.switch_to.frame(iframe)
# 这里是切换到iframe
def input_info(self,name,tel,sheng,shi,qu,addr):
self.name.send_keys(name)
self.tel.send_keys(tel)
self.div_select(self.sheng,sheng)
self.div_select(self.shi,shi)
self.div_select(self.qu,qu)
self.addr.send_keys(addr)
def div_select(self,el,value):
el.click()
el.find_element(By.XPATH,"./div/div/input").send_keys(value)
el.find_element(By.XPATH,'./div/ul/li').click()
def click_save(self):
self.btn.click()
p1.py
import pytest
from webdriver_helper import get_webdriver
from pages import *
@pytest.fixture(scope="session")
def user_driver():
driver = get_webdriver()
driver.maximize_window()
driver.get("http://101.34.221.219:8010/?s=user/logininfo.html")
login_page = LoginPage(driver)
login_page.login("wanan","123123")
assert login_page.msg.text == "登录成功"
driver.get("http://101.34.221.219:8010/?s=useraddress/index.html")
yield driver
driver.quit()
@pytest.mark.parametrize("name,tel,sheng,shi,qu,addr,msg",
[
["wanan","123456","北京市","东城区","东华门街道","一号楼","操作成功"],
["","","","","","","姓名格式 2~16 个字符之间"],
]
)
def test_new_address(user_driver,name,tel,sheng,shi,qu,addr,msg):
page = AddressPage(user_driver)
page.click_new()
page.input_info(name,tel, sheng, shi, qu, addr)
page.click_save()
assert page.msg.text == msg