摘要:本篇內容將記錄并介紹使用進行自動化網頁測試,并依靠約定來避免反復修改測試用例的方案??偨Y根據以上的功能劃分,我們很好的將一整個應用拆分成各個測試單元進行單元測試。
本篇內容將記錄并介紹使用Puppeteer進行自動化網頁測試,并依靠約定來避免反復修改測試用例的方案。主要解決頁面眾多時,修改代碼導致的牽連錯誤無法被發現的運行時問題。文章首發于個人博客。起因
對前端感興趣希望一起討論的可以加我vx:w554091944
目前我們在持續開發著一個幾十個頁面,十萬+行代碼的項目,隨著產品的更迭,總會出現這樣的問題。在對某些業務邏輯或者功能進行添加或者修改的時候(尤其是通用邏輯),這些通用的邏輯或者組件往往會牽扯到一些其他地方的問題。由于測試人員受限,我們很難在完成一個模塊單元后,對所有功能重新測試一遍。
同時,由于環境及數據的區別,(以及在開發過程中對代碼完備性的疏忽),代碼會在某些特殊數據的解析和和展示上出現問題,在開發和測試中很難去發現??偟膩碚f,我們希望有一個這樣的工具,幫我們解決上述幾個問題:
在進行代碼和功能改動后,能夠自動訪問各個功能的頁面,檢測問題
針對大量的數據內容,進行批量訪問,檢測對于不同數據的展示是否存在問題
測試與代碼功能盡量不耦合,避免每次上新功能都需要對測試用例進行修改,維護成本太大
定期的測試任務,及時發現數據平臺針對新數據的展示完備性
其中,最重要的問題,就是將測試代碼與功能解耦,避免每次迭代和修改都需要追加新的測試用例。我們如何做到這一點呢?首先我們來梳理下測試平臺的功能。
功能設定由于我們的平臺主要是進行數據展示,所以我們在測試過程中,主要以日常的展示數據為重心即可,針對一些復雜的表單操作先不予處理。針對上述的幾個問題,我們針對自動化測試工具的功能如下:
依次訪問各個頁面
訪問各個頁面的具體內容,如時間切換、選項卡切換、分頁切換、表格展開行等等
針對數據表格中的詳情鏈接,選擇前100條進行訪問,并進行下鉆頁的繼續測試
捕獲在頁面中的錯誤請求
對錯誤信息進行捕獲,統計和上報
根據以上的梳理,我們可以把整個應用分為幾個測試單元
頁面單元,檢測各功能頁面訪問的穩定性
詳情頁單元,根據頁面的數據列表,進行批量的詳情頁跳轉,檢測不同參數下詳情頁的穩定性
功能單元,用于檢測頁面和詳情頁各種展示類型點擊切換后是否產生錯誤
通過這樣的劃分,我們針對各個單元進行具體的測試邏輯書寫用例,這樣就可以避免再添加新功能和頁面時,頻繁對測試用例進行修改了。
Puppeteer帶著上面我們的需求,我們來看下Puppeteer的功能和特性,是否能夠滿足我們的要求。
文檔地址
Puppeteer是一個Node庫,它提供了一個高級 API 來通過 DevTools 協議控制 Chromium 或 Chrome。Puppeteer 默認以 headless 模式運行,但是可以通過修改配置文件運行“有頭”模式。
我們可以使用Puppeteer完成以下工作:
訪問頁面,進行截圖
自動進行鍵盤輸入,提交表單
模擬點擊等用戶操作
等等等等。。
我們來通過一些小案例,來介紹他們的基本功能:
訪問一個帶有ba認證的網站puppeteer可以創建page實例,并使用goto方法進行頁面訪問,page包含一系列方法,可以對頁面進行各種操作。
(async () => { const browser = await puppeteer.launch(); const page = await browser.newPage(); // ba認證 await page.authenticate({ username, password }); // 訪問頁面 await page.goto("https://example.com"); // 進行截圖 await page.screenshot({path: "example.png"}); await browser.close(); })();訪問登陸頁面,并進行登錄
首先,對于SPA(單頁面應用),我們都知道,當頁面進入后,客戶端代碼才開始進行渲染工作。我們需要等到頁面內容渲染完成后,再進行對應的操作。我們有以下幾種方法來使用
waitUntilpuppeteer針對頁面的訪問,切換等,提供了waitUntil參數,來確定滿足什么條件才認為頁面跳轉完成。包括以下事件:
load - 頁面的load事件觸發時
domcontentloaded - 頁面的DOMContentLoaded事件觸發時
networkidle0 - 不再有網絡連接時觸發(至少500毫秒后)
networkidle2 - 只有2個網絡連接時觸發(至少500毫秒后)
通過waitUnitl,我們可以當頁面請求都完成之后,確定頁面已經訪問完成。
waitForwaitFor方法可以在指定動作完成后才進行resolve
// wait for selector await page.waitFor(".foo"); // wait for 1 second await page.waitFor(1000); // wait for predicate await page.waitFor(() => !!document.querySelector(".foo"));
我們可以利用waitForSelector方法,當登錄框渲染成功后,才進行登錄操作
// 等待密碼輸入框渲染 await page.waitFor("#password"); // 輸入用戶名 await page.type("input#username", "username"); // 輸入密碼 await page.type("input#password", "testpass"); // 點擊登錄按鈕 await Promise.all([ page.waitForNavigation(), // 等跳轉完成后resolve page.click("button.login-button"), // 點擊該鏈接將間接導致導航(跳轉) ]); await page.waitFor(2000) // 獲取cookies const cookies = await page.cookies()針對列表內容里的鏈接進行批量訪問
主要利用到page實例的選擇器功能
const table = await page.$(".table") const links = await table.$$eval("a.link-detail", links => links.map(link => link.href) ); // 循環訪問links ...進行錯誤和訪問監聽
puppeteer可以監聽在頁面訪問過程中的報錯,請求等等,這樣我們就可以捕獲到頁面的訪問錯誤并進行上報啦,這也是我們進行測試需要的基本功能~
// 當發生頁面js代碼沒有捕獲的異常時觸發。 page.on("pagerror", () => {}) // 當頁面崩潰時觸發。 page.on("error", () => {}) // 當頁面發送一個請求時觸發 page.on("request") // 當頁面的某個請求接收到對應的 response 時觸發。 page.on("response")
通過以上的幾個小案例,我們發現Puppeteer的功能非常強大,完全能夠滿足我們以上的對頁面進行自動訪問的需求。接下來,我們針對我們的測試單元進行個單元用例的書寫
最終功能通過我們上面對測試單元的規劃,我們可以規劃一下我們的測試路徑
訪問網站 -> 登陸 -> 訪問頁面1 -> 進行基本單元測試 -> 獲取詳情頁跳轉鏈接 -> 依次訪問詳情頁 -> 進行基本單元測試
-> 訪問頁面2 ...
所以,我們可以拆分出幾個大類,和幾個測試單元,來進行各項測試
// 包含基本的測試方法,log輸出等 class Base {} // 詳情頁單元,進行一些基本的單元測試 class PageDetal extends Base {} // 頁面單元,進行基本的單元測試,并獲取并依次訪問詳情頁 class Page extends PageDetal {} // 進行登錄等操作,并依次訪問頁面單元進行測試 class Root extends Base {}
同時,我們如何在功能頁面變化時,跟蹤到測試的變化呢,我們可以針對我們測試的功能,為其添加自定義標簽test-role,測試時,根據自定義標簽進行測試邏輯的編寫。
例如針對時間切換單元,我們做一下簡單的介紹:
// 1. 獲取測試單元的元素 const timeSwitch = await page.$("[test-role="time-switch"]"); // 若頁面沒有timeSwitch, 則不用進行測試 if (!timeSwitch) return // 2. time switch的切換按鈕 const buttons = timeSwitch.$$(".time-switch-button") // 3. 對按鈕進行循環點擊 for (let i = 0; i < buttons.length; i++) { const button = buttons[i] // 點擊按鈕 await button.click() // 重點! 等待對應的內容出現時,才認定頁面訪問成功 try { await page.waitFor("[test-role="time-switch-content"]") } catch (error) { reportError (error) } // 截圖 await page.screenshot() }
上面只是進行了一個簡單的訪問內容測試,我們可以根據我們的用例單元書寫各自的測試邏輯,在我們日常開發時,只需要對需要測試的內容,加上對應的test-role即可。
總結根據以上的功能劃分,我們很好的將一整個應用拆分成各個測試單元進行單元測試。需要注意的是,我們目前僅僅是對頁面的可訪問性進行測試,僅僅驗證當用戶進行各種操作,訪問各個頁面單元時頁面是否會出錯。并沒有對頁面的具體展示效果進行測試,這樣會和頁面的功能內容耦合起來,就需要多帶帶的測試用例的編寫了。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/101902.html
摘要:抓取并生成預先呈現的內容即。自動表單提交,測試,鍵盤輸入等。創建一個最新的自動化測試環境。使用最新的的和瀏覽器功能,直接在最新版本的瀏覽器中運行測試。捕獲您網站的時間線跟蹤,以幫助診斷性能問題。 木偶 Puppeteer 更友好的 Headless Chrome Node API木偶也是有心的 (=?ω?=) showImg(https://segmentfault.com/img/b...
摘要:前端每周清單第期現狀分析與優化策略單元測試爬蟲作者王下邀月熊編輯徐川前端每周清單專注前端領域內容,以對外文資料的搜集為主,幫助開發者了解一周前端熱點分為新聞熱點開發教程工程實踐深度閱讀開源項目巔峰人生等欄目。 showImg(https://segmentfault.com/img/remote/1460000011008022); 前端每周清單第 29 期:Web 現狀分析與優化策略...
摘要:通過啟動時的命令行參數僅能實現簡易的啟動時初始化操作。是谷歌官方出品的一個通過協議控制的庫。使用和例子類似其他框架,通過操作實例來操作瀏覽器作出相應的反應。簡單例子的入門和實踐求贊,另外歡迎訪問我的博客 出現的背景 Chrome59(linux、macos)、 Chrome60(windows)之后,Chrome自帶headless(無界面)模式很方便做自動化測試或者爬蟲。但是如何和h...
摘要:視覺感知測試視覺回歸測試為了解決上面提到的各種問題,視覺感知測試孕育而生。第三種方式,無法進行視覺感知測試結果只能進行視覺回歸測試和上一版的繼續比較差異。 前端自動化測試 之 視覺測試 showImg(https://segmentfault.com/img/remote/1460000014720180); 前端測試分類 showImg(https://segmentfault.co...
閱讀 2400·2021-09-08 09:45
閱讀 3340·2021-09-08 09:45
閱讀 3097·2019-08-30 15:54
閱讀 3348·2019-08-26 13:54
閱讀 1405·2019-08-26 13:26
閱讀 1384·2019-08-26 13:23
閱讀 909·2019-08-23 17:57
閱讀 2178·2019-08-23 17:14