之前我曾經在《Rize – 一個可以讓你簡單、優雅地使用 puppeteer 的 Node.js 庫》一文簡單介紹過 Rize 這個庫。當時僅僅是介紹這個庫本身,關於如何使用,我沒有給太多的指導。
這篇文章講的是如何使用 Rize 來做 UI 測試或 E2E 測試。
在正式開始之前,先給可能沒了解過 Rize 的同學做個簡單的介紹:Rize 是一個提供了相對頂層並且可鏈式呼叫的 API 的庫,可與 puppeteer 一起使用。目前開源在 GitHub,地址是 github.com/g-plane/riz…,歡迎大家前往 GitHub 給個 star。
安裝
首先是安裝 Rize 和 puppeteer。
如果您使用 Yarn:
$ yarn add --dev rize puppeteer
複製程式碼
如果您使用 npm:
$ npm install --save-dev rize puppeteer
複製程式碼
考慮到國內的網路原因,您可能需要使用國內的 Chromium 映象:
對於 Linux 或 macOS 使用者:
PUPPETEER_DOWNLOAD_HOST=https://storage.googleapis.com.cnpmjs.org yarn add --dev puppeteer rize
複製程式碼
Windows 使用者:
SET PUPPETEER_DOWNLOAD_HOST=https://storage.googleapis.com.cnpmjs.org yarn add --dev puppeteer rize
複製程式碼
(npm 使用者同理)
由於安裝 puppeteer 的時候會下載 Chromium,所以整個過程可能比較費時,需要耐心等待。
約定
我們假定要被測試的頁面是這樣的:
<html>
<head>
<title>標題</title>
</head>
<body>
<div class="greeting">
Hello World!
</div>
<a href="">Another Page</a>
<button id="btn">Click Me</button>
<input type="checkbox" name="cb1" checked />
<input type="checkbox" name="cb2" />
</body>
</html>
複製程式碼
開始編寫測試
首先是匯入。我們推薦使用 ES2015 的 import 語法:
import Rize from `rize`
複製程式碼
當然您也可以用 CommonJS 方式:
const Rize = require(`rize`)
複製程式碼
第一件事是構造一個 Rize 例項:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
})
})
複製程式碼
然後要轉到要被測試的頁面。我們假定前面設定的頁面執行在 http://localhost:8000/ 上,那麼我們可以:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
})
})
複製程式碼
斷言
斷言頁面標題
我們可以使用 assertTitle
方法來斷言當前頁面的標題:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
.assertTitle(`標題`)
})
})
複製程式碼
斷言文字內容
可以使用 assertTitle
方法來斷言當前頁面存在指定的文字:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
.assertTitle(`標題`)
.assertSee(`Hello World!`)
})
})
複製程式碼
我們還可以明確在某個元素中存在指定文字,只需給出該元素的 CSS 選擇器即可:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
.assertTitle(`標題`)
.assertSee(`Hello World!`)
.assertSeeIn(`.greeting`, `Hello World!`)
})
})
複製程式碼
斷言是否存在指定的類名
我們可以斷言某個元素存在指定的類名:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
.assertTitle(`標題`)
.assertSee(`Hello World!`)
.assertSeeIn(`.greeting`, `Hello World!`)
.assertClassHas(`div`, `greeting`)
})
})
複製程式碼
還可以斷言不存在指定的類名:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
.assertTitle(`標題`)
.assertSee(`Hello World!`)
.assertSeeIn(`.greeting`, `Hello World!`)
.assertClassHas(`div`, `greeting`)
.assertClassMissing(`div`, `greet`)
})
})
複製程式碼
斷言表單狀態
我們可以斷言一些表單控制元件的狀態,例如核取方塊(checkbox)選中或未選中:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
.assertTitle(`標題`)
.assertSee(`Hello World!`)
.assertSeeIn(`.greeting`, `Hello World!`)
.assertClassHas(`div`, `greeting`)
.assertClassMissing(`div`, `greet`)
.assertChecked(`[name="cb1"]`) // 斷言已選中
.assertNotChecked(`[name="cb2"]`) // 斷言未選中
})
})
複製程式碼
與頁面互動
在實際測試的過程中,我們不僅僅需要進行一些斷言,還需要與頁面進行互動。
例如,我們以上面的頁面為例,我們可以單擊那個按鈕:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
.assertTitle(`標題`)
.assertSee(`Hello World!`)
.assertSeeIn(`.greeting`, `Hello World!`)
.assertClassHas(`div`, `greeting`)
.assertClassMissing(`div`, `greet`)
.assertChecked(`[name="cb1"]`) // 斷言已選中
.assertNotChecked(`[name="cb2"]`) // 斷言未選中
.click(`#btn`)
})
})
複製程式碼
也可以單擊某個連結,我們只需要給出該連結上的文字:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
.assertTitle(`標題`)
.assertSee(`Hello World!`)
.assertSeeIn(`.greeting`, `Hello World!`)
.assertClassHas(`div`, `greeting`)
.assertClassMissing(`div`, `greet`)
.assertChecked(`[name="cb1"]`) // 斷言已選中
.assertNotChecked(`[name="cb2"]`) // 斷言未選中
.click(`#btn`)
.clickLink(`Another Page`)
})
})
複製程式碼
當然,我們還能與表單進行互動。例如,勾選某個核取方塊:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
.assertTitle(`標題`)
.assertSee(`Hello World!`)
.assertSeeIn(`.greeting`, `Hello World!`)
.assertClassHas(`div`, `greeting`)
.assertClassMissing(`div`, `greet`)
.assertChecked(`[name="cb1"]`) // 斷言已選中
.assertNotChecked(`[name="cb2"]`) // 斷言未選中
.click(`#btn`)
.clickLink(`Another Page`)
.check(`[name="cb2"]`)
})
})
複製程式碼
或者取消勾選某個核取方塊:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
.assertTitle(`標題`)
.assertSee(`Hello World!`)
.assertSeeIn(`.greeting`, `Hello World!`)
.assertClassHas(`div`, `greeting`)
.assertClassMissing(`div`, `greet`)
.assertChecked(`[name="cb1"]`) // 斷言已選中
.assertNotChecked(`[name="cb2"]`) // 斷言未選中
.click(`#btn`)
.clickLink(`Another Page`)
.check(`[name="cb2"]`)
.uncheck(`[name="cb1"]`)
})
})
複製程式碼
關閉瀏覽器
在完成所有工作之後,需要退出瀏覽器:
describe(`UI test`, () => {
it(`example test`, async () => {
const rize = new Rize()
rize
.goto(`http://localhost:8000/`)
.assertTitle(`標題`)
.assertSee(`Hello World!`)
.assertSeeIn(`.greeting`, `Hello World!`)
.assertClassHas(`div`, `greeting`)
.assertClassMissing(`div`, `greet`)
.assertChecked(`[name="cb1"]`) // 斷言已選中
.assertNotChecked(`[name="cb2"]`) // 斷言未選中
.click(`#btn`)
.clickLink(`Another Page`)
.check(`[name="cb2"]`)
.uncheck(`[name="cb1"]`)
await rize.end()
})
})
複製程式碼
更多
實際上 Rize 的功能遠不只上面那些。想要獲取更多資訊,可以前往以下頁面:
Rize 的 GitHub 倉庫:github.com/g-plane/riz… (歡迎 star)
Rize 的文件教程:rize.js.org/
Rize 所有的 API 參考:https://rize.js.org/api/classes/index.rize.html