霍格沃兹测试开发学社
pip install selenium
类型 | 规则 |
---|---|
文件 | test_开头 或者 _test 结尾 |
类 | Test 开头 |
方法/函数 | test_开头 |
注意:测试类中不可以添加__init__ 构造函数 |
class TestHandinResume:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
# 设置全局隐式等待
self.driver.implicitly_wait(3)
def test_login(self):
url = "https://passport.zhaopin.com/login?bkUrl=%2F%2Fi.zhaopin.com%2Fblank%3Fhttps%3A%2F%2Fwww.zhaopin.com%3FvalidateCampus%3D"
self.driver.get(url)
self.driver.find_element(By.CLASS_NAME, "zppp-panel-normal-bar__img").click()
# 等待扫码
time.sleep(20)
# 登陆成功后,获取登陆 cookies
cookie = self.driver.get_cookies()
print(cookie)
# 将 cookie 写入文件
with open("cookie.yaml", "w") as f:
yaml.safe_dump(cookie, f)
def change_handle(driver):
'''
切换窗口句柄
:return:
'''
handles = driver.window_handles
print(f"当前存在的窗口句柄为 {handles}")
driver.switch_to.window(handles[-1])
print("窗口切换成功")
class TestHandinResume:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
# 设置全局隐式等待
self.driver.implicitly_wait(3)
url = "https://passport.zhaopin.com/login?bkUrl=%2F%2Fi.zhaopin.com%2Fblank%3Fhttps%3A%2F%2Fwww.zhaopin.com%3FvalidateCampus%3D"
self.driver.get(url)
self.driver.find_element(By.CLASS_NAME, "zppp-panel-normal-bar__img").click()
time.sleep(1)
# 从文件中获取 cookie 信息登陆
with open("cookie.yaml", "r", encoding="utf-8") as f:
cookies = yaml.safe_load(f)
print(f"读取出来的cookie:{cookies}")
for cookie in cookies:
try:
# 添加 cookie
self.driver.add_cookie(cookie)
except Exception as e:
print(e)
time.sleep(3)
def teardown_class(self):
self.driver.quit()
def test_handin_resume(self):
# ----首页----
self.driver.get("https://i.zhaopin.com/")
print(self.driver.title, self.driver.current_url)
# 点击搜索框,输入搜索关键词
self.driver.find_element(By.XPATH, "//*[@class='a-input__native']").send_keys("测试开发")
# 点击搜索按钮
self.driver.find_element(By.XPATH, "//*[@class='a-button search-box__button zp-iconfont zp-search a--bordered a--filled']").click()
# ----搜索结果页----
# 打开新页面,切换句柄
change_handle(self.driver)
print(self.driver.title, self.driver.current_url)
# 点击职位
eles = self.driver.find_elements(By.XPATH, "//*[@class='iteminfo__line1__jobname__name']")
eles[0].click()
# ----职位详情页----
# 切换页面,进入职位详情页
change_handle(self.driver)
print(self.driver.title, self.driver.current_url)
# 点击职位申请按钮
self.driver.find_element(By.XPATH, "//*[@class='a-button a--bordered a--filled']").click()
# ----投递结果页----
# 切换页面
time.sleep(3)
change_handle(self.driver)
print(self.driver.title, self.driver.current_url)
result = self.driver.find_element(By.XPATH, "//*[@class='deliver-dialog__box__title']").text
print(result)
# 断言投递结果
assert result == "申请成功!"
Hogwarts $ tree
.
├── __init__.py
├── base
│ ├── __init__.py
│ └── base_driver.py
├── tests
│ ├── __init__.py
│ └── test_xxx.py
├── log
│ ├── test.log
├── datas
│ └── xxx.yaml
├── page
│ ├── __init__.py
│ ├── main_page.py
│ ├── xxx_page.py
│ └── xxx_page.py
├── pytest.ini
└── utils
├── __init__.py
└── log_utils.py
# base/base_driver.py
class BaseDriver:
def __init__(self, driver: WebDriver=None):
print(f"当前页面的 driver 对象 {driver}")
if driver == None:
# 打开 Chrome 浏览器空白页面
self.driver = webdriver.Chrome()
# 设置隐式等待
self.driver.implicitly_wait(10)
# 窗口最大化
self.driver.maximize_window()
else:
self.driver = driver
def close(self):
'''
关闭 driver
'''
print("关闭 driver")
self.driver.quit()
def open_url(self, url=None):
'''
打开网页
:param url: 要打开页面的 URL
'''
info = f"要打开的页面 url 为 {url}"
print(info)
with allure.step(info):
self.driver.get(url)
def find_ele(self, by, value):
'''
查找单个元素
:param by: 元素定位方式
:param value: 元素定位表达式
:return: 找到的元素对象
'''
info = f"查找单个元素:{by},{value}"
print(info)
with allure.step(info):
ele = self.driver.find_element(by, value)
return ele
def find_eles(self, by, value):
'''
查找多个元素
:param by: 元素定位方式
:param value: 元素定位表达式
:return: 找到的元素对象列表
'''
info = f"查找多个元素的定位:{by},{value}"
print(info)
with allure.step(info):
eles = self.driver.find_elements(by, value)
return eles
def find_and_get_text(self, by, value):
'''
获取单个元素的文本属性
:param by: 元素定位方式
:param value: 元素定位表达式
:return: 获取到的文本属性
'''
text = self.find_ele(by, value).text
print(f"获取元素 {by},{value} 的文本:{text}")
return text
def find_and_click(self, by, value):
'''
查找并点击元素
:param by: 元素定位方式
:param value: 元素定位表达式
:return:
'''
print(f"要点击的元素:{by},{value}")
ele = self.find_ele(by, value)
ele.click()
def click_ele(self, ele):
'''
点击元素
:param ele: 要点击的元素对象
'''
print(f"要点击的元素:{ele}")
ele.click()
def find_and_sendkeys(self, by, value, text):
'''
查找并输入关键字
:param by: 元素定位方式
:param value: 元素定位表达式
:param text: 要输入的关键字
'''
print(f"要在元素:{by},{value} 中输入关键字 {text}")
ele = self.find_ele(by, value)
ele.clear()
ele.send_keys(text)
def wait_ele_click(self, by, value, timeout=8):
'''
显示等待单个元素可以被点击到
:param by: 元素定位方式
:param value: 元素定位表达式
:param timeout: 等待时间
:return:
'''
print(f"要等待元素 {by},{value} 可以点击")
WebDriverWait(self.driver, timeout, 0.1).until(
expected_conditions.element_to_be_clickable((by, value))
)
def url(self):
'''
获取当前页面的 url
:return: url
'''
url = self.driver.current_url
print(f"当前页面 url 为 {url}")
return url
def title(self):
'''
获取当前页面的 title
:return: title
'''
title_text = self.driver.title
print(f"当前页面 title 为 {title_text}")
return title_text
def login_yaml(self, file_path):
'''
从 yaml 文件中获取 cookie 登录
'''
time.sleep(1)
with open(file_path, "r", encoding="utf-8") as f:
cookies = yaml.safe_load(f)
print(f"读取出来的 cookie:{cookies}")
for cookie in cookies:
try:
# 添加 cookie
self.driver.add_cookie(cookie)
except Exception as e:
print(e)
time.sleep(3)
def mouse_suspension(self, by, value):
'''
鼠标悬浮操作
:param by: 元素定位方式
:param value: 元素定位表达式
:return:
'''
print(f"要鼠标悬浮的元素为 {by},{value}")
action = ActionChains(self.driver)
ele = self.find_ele(by, value)
action.move_to_element(ele).perform()
def change_handle(self):
'''
切换窗口句柄
:return:
'''
time.sleep(1)
handles = self.driver.window_handles
print(f"当前存在的窗口句柄为 {handles}")
self.driver.switch_to.window(handles[-1])
print("窗口切换成功")
# page/main_page.py
class MainPage(BaseDriver):
login_url = "https://passport.zhaopin.com/login?bkUrl=%2F%2Fi.zhaopin.com%2Fblank%3Fhttps%3A%2F%2Fwww.zhaopin.com%3FvalidateCampus%3D"
main_url = "https://i.zhaopin.com/"
def login(self):
'''
登录,进入首页
:return:
'''
# 进入登录页面
self.open_url(self.login_url)
# 点击扫码登录
self.find_and_click(By.CLASS_NAME, "zppp-panel-normal-bar__img")
# 从 yaml 文件中获取 cookie 信息登陆
self.login_yaml("../datas/cookie.yaml")
# 进入首页
self.open_url(self.main_url)
# 打印当前页面标题与 url
self.title()
self.url()
return self
def input_search_key(self, search_key):
'''
搜索职位
:param search_key: 搜索关键词
:return:
'''
# 1 搜索框中输入搜索关键词
self.find_and_sendkeys(By.XPATH, "//*[@class='a-input__native']", search_key)
# 2 点击搜索按钮
self.find_and_click(
By.XPATH,
"//*[@class='a-button search-box__button zp-iconfont zp-search a--bordered a--filled']"
)
# 3 跳转搜索结果页
return SearchResultPage(self.driver)
# page/search_result_page.py
class SearchResultPage(BaseDriver):
def click_job(self):
'''
点击职位
:return:
'''
# ----搜索结果页----
# 打开新页面,切换句柄
self.change_handle()
# 打印当前页面 title 与 url
self.title()
self.url()
# 1 点击第一个职位
eles = self.find_eles(By.XPATH, "//*[@class='iteminfo__line1__jobname__name']")
# eles[0].click()
self.click_ele(eles[0])
# 2 跳转职位详情页
return JobInfoPage(self.driver)
# page/job_info_page.py
class JobInfoPage(BaseDriver):
def click_deliver(self):
'''
点击投递简历按钮
:return:
'''
# ----职位详情页----
# 切换页面,进入职位详情页
self.change_handle()
self.title()
self.url()
# 点击职位申请按钮
self.find_and_click(By.XPATH, "//*[@class='a-button a--bordered a--filled']")
# 跳转投递结果页
return DeliverResultPage(self.driver)
# page/deliver_result_page.py
class DeliverResultPage(BaseDriver):
def get_deliver_result(self):
'''
获取投递结果
:return:
'''
# 切换页面
self.change_handle()
self.title()
self.url()
# 获取投递结果文本
result = self.find_and_get_text(By.XPATH, "//*[@class='deliver-dialog__box__title']")
print(result)
return result
# test/test_deliver_resume.py
class TestDeliverResume:
def setup(self):
self.main = MainPage()
def teardown(self):
self.main.close()
def test_job_info_deliver(self):
'''
测试步骤
1 登录进入首页
2 搜索职位
3 点击搜索结果页的第一个职位
4 在职位详情页点击投递简历
5 断言投递结果页展示投递结果信息
:return:
'''
result = self.main.login().input_search_key("测试开发").click_job().click_deliver().get_deliver_result()
assert result == '申请成功!'
allure --version
pip install allure-pytest
# test/test_deliver_resume.py
@allure.feature("智联招聘网站测试")
class TestDeliverResume:
def setup(self):
self.main = MainPage()
def teardown(self):
self.main.close()
@allure.story("简历投递")
@allure.title("职位详情页投递简历")
def test_job_info_deliver(self):
'''
测试步骤
1 登录进入首页
2 搜索职位
3 点击搜索结果页的第一个职位
4 在职位详情页点击投递简历
5 断言投递结果页展示投递结果信息
:return:
'''
result = self.main.login().input_search_key("测试开发").click_job().click_deliver().get_deliver_result()
assert result == '申请成功!'
# base/base_driver.py
class BaseDriver:
...
def open_url(self, url=None):
'''
打开网页
:param url: 要打开页面的 URL
'''
info = f"要打开的页面 url 为 {url}"
print(info)
with allure.step(info):
self.driver.get(url)
def find_ele(self, by, value):
'''
查找单个元素
:param by: 元素定位方式
:param value: 元素定位表达式
:return: 找到的元素对象
'''
info = f"查找单个元素:{by},{value}"
print(info)
with allure.step(info):
ele = self.driver.find_element(by, value)
return ele
def find_eles(self, by, value):
'''
查找多个元素
:param by: 元素定位方式
:param value: 元素定位表达式
:return: 找到的元素对象列表
'''
info = f"查找多个元素的定位:{by},{value}"
print(info)
with allure.step(info):
eles = self.driver.find_elements(by, value)
return eles
# 在测试执行期间收集结果
pytest [测试用例/模块/包] --alluredir=./result/ --clean-alluredir
# 生成在线的测试报告
allure serve ./result
# 生成静态报告
allure generate --clean result/html result -o result/html