web自動化小記

目錄

  1. selenium webdriver環境安裝、原理
  2. 前端頁面、html、DOM對象
  3. 8大元素定位、xpath詳解
  4. web常用元素操作
  5. PageObject模式應用、自動化用例設計
  6. 分層設計
  7. basepage頁面提取
  8. pytest框架應用
  9. jenkins 集成
  10. allure報告集成

代碼 --通過-- 驅動器 --連接-- 瀏覽器
chrome (chromedriver)
ie (IEserverdriver)
firefox (geckodriver)

web頁面組成

常用 HTML+CSS+Javascript
HTML:定義頁面呈現的內容 鍵值對
CSS:控制你的網頁如何呈現。即布局設置 顏色 字體等
JavaScript:頁面依據不同的情形做不同的事情 JavaScript就是實現這個的編程語言的一種

安裝selenium+chrome+Chromedriver

selenium - webdriver

# learn_selenium_webdriver.py
from selenium import webdriver

# service_log_path 日志輸出路徑
# 啟動谷歌瀏覽器,開啟與瀏覽器之間的會話
# 原理 chromedriver -> commend命令 -> http請求 -> chrome
# window10 會自動殺掉多余的chromedriver進程 windows7就不會
driver = webdriver.Chrome(service_log_path='')

# 訪問一個網頁
driver.get('http://www.baidu.com')

# 窗口最大化
driver.maximize_window()

# driver.set_window_size(100,200)

# 訪問
driver.get('http://www.taobao.com')
# 上一頁
driver.back()
# 下一頁
driver.forward()
# 刷新
driver.refresh()

print('網頁標題',driver.title)
print('網頁網址',driver.current_url)
print('窗口句柄',driver.current_window_handle)

# 徹底結束會話 關閉剛打開的瀏覽器
# driver.quit()

# 關閉當前窗口(一個標簽頁)
# driver.close()

定位元素

截屏2020-11-27 下午2.20.06.png

html中的datatype http://www.lxweimin.com/p/75caa9c46fdd

# find_element.py
from selenium import webdriver

# service_log_path 日志輸出路徑
# 啟動谷歌瀏覽器,開啟與瀏覽器之間的會話
# 原理 chromedriver -> commend命令 -> http請求 -> chrome
# window10 會自動殺掉多余的chromedriver進程 windows7就不會
driver = webdriver.Chrome(service_log_path='')

# 訪問一個網頁
driver.get('http://www.baidu.com')

# 元素定位 沒有 id 優先選name

# 方式一
ele = driver.find_element_by_id('kw')
print(ele)
print(ele.get_attribute('class'))

# 方式二
class_eles = driver.find_elements_by_class_name('s_ipt')
print('數組', class_eles)
class_ele = driver.find_element_by_class_name('s_ipt')
print(class_ele)

# 方式三
driver.find_elements_by_class_name('wd')
driver.find_element_by_class_name('wd')

# 方式四
driver.find_element_by_tag_name('input')
driver.find_elements_by_tag_name('input')

# 方式五、六  針對鏈接 文本鏈接(圖片鏈接不可)
driver.find_element_by_link_text('更多產品')  # 精確查找
driver.find_element_by_partial_link_text('產品')  # 模糊查找

# ------萬能定位方式 不打開網頁的情況下 獲取------
# 方式七 xpath

driver.find_element_by_xpath('//a[@name = "tj_login" and @class="lb"]')
# 相對定位 以// 開頭, 不依賴頁面的順序位置,只看 整個頁面有沒有符合表達式的元素
# !!! F12的Element區域 command + F(Windows control+F) find by string,selector,or xpath
"""
xpath 表達式
1.默認找到第一個元素 屬性名稱最好粘貼 防止寫錯
//開頭 標簽類型[@屬性名稱=值 and @屬性名稱=值]
多個條件用 and or 邏輯運算符連接  and前后有空格
//input[@name="rsv_bp" and @]
//a[@name = "tj_login" and @class="lb"]
2.層級等位 找到 這個元素的父標簽
//div[@id="u1"]//a[@name = "tj_login"]


3.開發沒有寫 name id 之類的 定位不到的時候 還可以采取用
text()函數
//a[text()="知道"]
contains() 包含
//a[contains(@class,"more")]
"""
"""
xpath軸定位語法
軸運算
ancestor : 祖先節點,包括父
parent: 父節點
preceding-sibling : 當前元素節點標簽之前的所有兄弟節點
following-sibling :當前元素節點標簽之后的所有兄弟節點

使用語法
/軸名稱::節點名稱[@屬性=值....]
//span[text()="python10"]/ancestor::a/following-sibling::div//a
"""

# 絕對定位 以/開頭  非常依賴頁面的順序和位置 錄制的就是絕對定位 經常變動
# F12 選中元素 右鍵 Copy -> Copy xPath

# css

還是用到了 下標 這個不好 不會寫
軸定位 百度貼吧 人文 江西會考的文字
//div[text()="人文自然"]/following-sibling::div[1]/ul[1]/li[1]/a/div/p[@class="bft_forum_name"]

截屏2020-11-27 下午3.57.58.png

等待

# learn_wait.py
import time

from selenium import webdriver
# ----顯性等待需要導入的類-----
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# -----

# 代碼和瀏覽器之間整個會話周期  開啟和關閉
# 啟動谷歌瀏覽器 開啟與瀏覽器之間的會話
driver = webdriver.Chrome()

# # 全局等待 隱形等待 元素查找 操作等待 智能的 推薦用顯性等待
# driver.implicitly_wait(30)

driver.get('https://www.pgyer.com')

# 強制等待 sleep(秒)

# 顯性等待
# 元素定位表達式
ele_xpath = '//li[@class="menu-li"]//a[text()="登錄"]'
# 參數 locator 元組 (元素的定位類型,元素的定位表達式)
locator = (By.XPATH, ele_xpath)
WebDriverWait(driver, 10).until(EC.visibility_of_any_elements_located(locator))

login_ele = driver.find_element_by_xpath(ele_xpath)
login_ele.click()

# 目標在頁面的iframe下邊 需要切換到該iframe
# 進入了另一個html頁面
# # 方式一
# driver.switch_to.frame('login_frame_qq')  # 1.根據名字
# # 2.根據下標
# # 3.根據xpath定位
# iframe_xpath = '//iframe[@name="login_frame_qq"]'
# driver.switch_to.frame(driver.find_element_by_xpath(iframe_xpath))
# time.sleep(0.5)
# driver.find_element_by_id('switcher_plogin')

# # 方式二
# WebDriverWait(driver, 10).until(EC.frame_to_be_available_and_switch_to_it("login_frame_qq"))

# 從iframe當中 回到默認的頁面中
driver.switch_to.default_content()
# 回到上一級
driver.switch_to.parent_frame()
  • css表達式定位


    拿到列表中所有的title

    goods_title_css = '.goods-list .title'
    WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.CSS_SELECTOR, goods_title_css)))
    goods_items = driver.find_elements_by_css_selector(goods_title_css)
    goods_items_titles = [item.text for item in goods_items]  #  這個是python的語法 列表生成
    assert search_text in goods_items_titles式

句柄 窗口切換

# learn_handle.py
import time
from selenium import webdriver
# ----顯性等待需要導入的類-----
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
# -----
driver = webdriver.Chrome()
driver.get("http://www.baidu.com")

driver.find_element_by_id('kw').send_keys('檸檬班')
driver.find_element_by_id('su').click()

n_tieba_xpath = '//p[contains(text(),"檸檬班,騰訊課堂唯一連續4年認證機構")]/ancestor::div[@class="result c-container"]/preceding-sibling::h3/a'
located = (By.XPATH, n_tieba_xpath)
WebDriverWait(driver, 20).until(EC.visibility_of_any_elements_located(located))

handles = driver.window_handles  # 窗口總數為2

# 點擊了 引起了窗口數量的變化
driver.find_element_by_xpath(n_tieba_xpath).click()

# 等待新窗口的出現
WebDriverWait(driver, 10).until(EC.new_window_is_opened(handles))

# 窗口切換
handles = driver.window_handles  # 窗口總數為3
# 切換句柄
driver.switch_to.window(handles[-1])

# 窗口切換
#
# # step1:獲取窗口的總數以及句柄 新打開的窗口在最后一個
# handles = driver.window_handles
# print(handles)
# print(handles[-1])
# print(handles[0])
#
# # 當前窗口的句柄
# print('當前窗口的句柄', driver.current_window_handle)
#
# # step2 切換句柄
# driver.switch_to.window(handles[-1])

# 新的頁面操作
WebDriverWait(driver, 20).until(EC.visibility_of_any_elements_located((By.ID, "j_head_focus_btn")))
driver.find_element_by_id("j_head_focus_btn").click()


time.sleep(120)
driver.quit()

切換alert

# learn_alert.py
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait

import time

driver = webdriver.Chrome()
driver.get(r"C:\Users\DN\Desktop\Python_Test_Project\pythonProject_web\pythonProject_web\learn\learn_html.html")

# 等待alert出現
WebDriverWait(driver, 10).until(EC.alert_is_present())
# alert切換  不是html元素
alert_new = driver.switch_to.alert
print(alert_new.text)
# alert_new.dismiss()
time.sleep(10)
alert_new.accept()


time.sleep(120)
driver.quit()

鼠標操作

由selenium的ActionChains類來完成模擬鼠標操作的
主要流程:1.存儲鼠標操作 ;2.perfrom()來執行鼠標操作
支持以下操作:double_click content_click drag_and_drop move_to_element
perform()
單擊、雙擊、右鍵、懸停

獲取web頁面鼠標懸浮的列表
chrome
光標在Element區域
鼠標移動到 懸浮會出現列表的元素上 -> 出現列表 -> 按一下 ctrl+shift+C -> 鼠標移動到想要操作的元素列表項上
單擊該列表項 就可以找到該元素

下拉列表 select 類

# learn_mouse.py
import time

from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By


# 能用點擊操作就不要用鼠標操作,不穩定
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('http://www.baidu.com')

# 1.找到鼠標要操作的元素
set_xpath = '//div[@id="u1"]//span[@id="s-usersetting-top"]'
set_sel = driver.find_element_by_xpath(set_xpath)

# # 2.實例化ActionChains類
# ac = ActionChains(driver)
#
# # 3。將鼠標操作加到 ActionChains列表中
# ac.move_to_element(set_sel)
#
# # 4.調用perform()來執行鼠標操作
# ac.perform()

# ActionChains(driver).move_to_element(set_sel).perform()

# 通過點擊就能實現
set_sel.click()

high_set_xpath = '//a[text()="高級搜索"]'
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, high_set_xpath)))
high_set = driver.find_element_by_xpath(high_set_xpath)
high_set.click()

# # 下拉列表 select 標簽 Select類
# from selenium.webdriver.support.select import Select
# # 1.找到select元素
# select_xpath = '//select[@name="ft"]'
# WebDriverWait(driver, 20).until(EC.visibility_of_element_located((By.XPATH, select_xpath)))
# select_ele = driver.find_element_by_xpath(select_xpath)
# 
# # 2.實例化Select類
# s = Select(select_ele)
# 
# # 3.選擇下拉列表值
# # 方式一:下標從0開始
# s.select_by_index(4)
# # 方式二:value值
# s.select_by_value("all")
# # 方式三:文本內容
# s.select_by_visible_text("Adobe Acrobat PDF (.pdf)")

鍵盤操作

# @File: learn_keys.py
# @Author: MJ
# @Time: 2020/11/28 20:00
# ---
from selenium.webdriver.common.keys import Keys
import time

from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.by import By

# 能用點擊操作就不要用鼠標操作,不穩定
driver = webdriver.Chrome()
driver.maximize_window()
driver.get('http://www.baidu.com')
driver.find_element_by_id('kw').send_keys('檸檬班', Keys.ENTER)

#
# 滾動條操作,如果被測系統太長 不在可視范圍內報錯  需要滾動排除不在可視范圍內的原因
# 1.找打要滾動到可視區域的元素
baike_xpath = '//a[@title="核心價值觀"]/ancestor::div[contains(@class, "c-span9")]/preceding-sibling::div/a'
WebDriverWait(driver, 10).until(EC.visibility_of_element_located((By.XPATH, baike_xpath)))
baike_ele = driver.find_element_by_xpath(baike_xpath)

# 2.使用js進行滾動操作
driver.execute_script("arguments[0].scrollIntoView(false)", baike_ele)

# js語句

time.sleep(120)
driver.quit()

arguments[0].scrollIntoView(false) 滾動到可視區域的底部

上傳操作

  1. 如果是input可以直接輸入路徑的,那么直接調send_keys輸入路徑
  2. 非input標簽的上傳,則需要借助第三方工具:
    2.1 Auto 我們去調用其生成的au3或exe文件https://blog.csdn.net/qq_42293487/article/details/84662376
    2.2 SendKeys第三方庫(目前只支持到2.7版本)https://pypi.python.org/pypi/SendKeys
    2.3 Python pywin32庫,識別對話框句柄,進而操作
    -- mac
  3. pyautoit
  4. https://blog.csdn.net/rp517045939/article/details/103211496
    工具: pywin32 和 spy++(執行python代碼)
    Winspy++ Baidu盤
# -*- coding: utf-8 -*-
# ---
# @PROJECT_NAME: pythonProject_web
# @File: upload_file.py
# @Author: MJ
# @Time: 2020/11/30 11:00 上午
# ---
import win32gui
import win32con


class UploadFile:

    @staticmethod
    def upload_file_win(filePath, browser):
        w_title = '打開'
        if browser.lower() == 'chrome':
            w_title = '打開'
            
        # 一級窗口
        dialog = win32gui.FindWindow('#32770', w_title)
        # 二級窗口
        comboxex32 = win32gui.FindWindowEx(dialog, 0, 'ComboBoxEx32', None)
        # 三級窗口
        combox = win32gui.FindWindowEx(comboxex32, 0, 'ComboBox', None)
        # 文本的輸入窗口 - 四級
        edit = win32gui.FindWindowEx(combox, 0, 'Edit', None)
        # 打開按鈕 - 二級窗口
        button = win32gui.FindWindowEx(dialog, 0, 'Button', '打開(&0)')

        # 輸入文件地址
        win32gui.SendMessage(edit, win32con.WM_SETTEXT, None, filePath)  # 發送文件路徑
        # 點擊 打開按鈕 提交文件
        win32gui.SendMessage(dialog, win32con.WM_COMMAND, 1, button)

自動化測試用例 編寫

截屏2020-11-30 下午1.42.56.png

PageObject 模式

原理:
將頁面的元素定位和元素行為封裝成一個page類
類的屬性:元素的定位
類的行為:元素的操作
頁面對象和測試用例分離。
測試用例:
調用所需頁面對象中的行為,組成測試用例。
好處:

  1. 當某個頁面的元素發生變化,只需要修改該頁面對象中的代碼即可,測試用例不需要修改。
  2. 提高代碼重用率,結構清晰,維護代碼更容易
  3. 測試用例發生變化時,不需要或者只需要修改少數頁面對象代碼即可

持續集成的一種方式 Jenkins

Master/Slave 模式
Master 安裝了Jenkins的電腦(管理者)
Slave 小弟 其他電腦

  1. slave向Master報告
    Manager Jenkins
    -> Manage Nodes(節點管理)
    -> New Node
    -> Node Name;Permanent Agent(永久節點)OK
    -> # of executors(執行能力,根據執行機性能分配 給分配幾個任務 1/2/3)
    Remote root directory(遠程工作目錄,放下載的代碼的目錄)
    Usage use this ...(隨時待命,給我什么都可以) Only build...(只執行分配給他的任務)
    Launch method
    Launch agent via Java Web Start (Windows)
    ...master (linux、mac)
    ...SSH (linux、mac)
    Available...keep...
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,836評論 6 540
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,275評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,904評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,633評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,368評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,736評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,740評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,919評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,481評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,235評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,427評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,968評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,656評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,055評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,348評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,160評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,380評論 2 379

推薦閱讀更多精彩內容