使用TestCafe進行UI測試


Cypress,TestCafe,Puppeteer被譽爲後Selenium時代的Web UI自動化測試的三駕馬車,本文是對其中之一的TestCafe的使用進行簡要概述,會以實際的例子帶你一起搭建一個五臟俱全的UI測試Demo。

TestCafe簡介

關注到TestCafe是由ThoughtWorks發佈的技術雷達,2018年11月TestCafe首次進入技術雷達,處於評估階段,2019年4月的技術雷達裏,它的狀態更新爲試驗階段。TestCadfe的官網描述的特點有以下幾點:
1.自動等待:頁面加載、執行動作後自動等待元素出現,無需手動設置
2.測試腳本支持javaScript&typeScript
3.可以識別被測頁面的js語法錯誤
4.支持同時打開多個瀏覽器頁面並行執行用例
5.有強大易讀的API供使用者使用
6.支持持續集成
7.Live模式方便調試用例
以上幾點會在下面一一詳細講解。

安裝TestCafe並運行官網Demo

1.安裝TestCafe

(1)打開電腦命令行執行以下命令

npm install -g testcafe

(2)安裝完成可以執行以下命令查看testCafe版本

testcafe —version

2.運行官網Demo

(1)從官網下載示例代碼:https://devexpress.github.io/testcafe/downloads/sample-test.zip
(2)將該zip包裏的兩個js文件copy到你自定義的任意目錄下,用VSCode打開這兩文件,可以看見test-example.js是測試用例,basic-page-model.js是page object
(3)然後從命令行進入該目錄,執行以下命令運行測試用例

 testcafe chrome test-example.js

用例執行失敗,並且打印出了報告,可以看到是15行expect出錯,分析用例可知,輸入的是P.Parker,expect的卻是Peter
在這裏插入圖片描述
(4)修改test-example.js第15行的Peter爲Parker,再次執行用例,用例執行成功
在這裏插入圖片描述

新建一個項目使用TestCafe進行UI測試

以上的操作均在命令行之心,並且用例也只是一個js文件,在真實項目中,我們會創建一個項目來管理UI測試的測試用例,下面將會詳細講解如何新建一個項目然後使用TestCafe進行UI測試。

1.新建一個前端項目

(1)在自定義的任意目錄下執行

mkdir testCafeProject

(2)進入testCafeProject所在目錄執行

npm int

在這裏插入圖片描述
(3)使用IntelliJ打開該項目,使用pageObject的形式組織代碼,所以新建目錄page&test

在這裏插入圖片描述

(4)安裝testCafe(如果之前已經執行過npm install -g testcafe則跳過此步驟)

npm install testcafe —save-dev

2.寫測試用例

然後我們開始寫測試用例,我的思路將頁面元素以及執行動作都放在page裏面,包成方法供測試用例使用,冊書用例裏面只需要調用包好方法即可,這樣測試用例更加明晰,和官網的例子有些不同。以新浪微博註冊爲例,測試代碼如下
weiboSignUpTest.js

import WeiboHomePage from '../page/weiboHomePage';//引用pageObject裏的方法
import WeiboSignUpPage from '../page/weiboSignUpPage';

fixture`weibo sign up fixture`//固定寫法,fixture相當於測試集,裏面可以包含多個test
    .page`https://weibo.com/`;

//測試用例
test('search something in weibo and sign up test', async t => { //固定寫法
    await WeiboHomePage.searchSomething('人民日報')//調用WeiboHomePage裏面的方法
    await WeiboHomePage.clickSignUp()
    await WeiboSignUpPage.fillSignUpFormAndSubmit('123', '123098', '1995', '2', '20', '123')
    await WeiboSignUpPage.shouldShowErrorMessage('手機號長度11位,以13/14/15/16/17/18/19開頭')
});

weiboHomePage.js

import {Selector, t} from 'testcafe'

class WeiboHomePage {

    get inputSearchContent() {
        return Selector('input[node-type=searchInput]')//使用selector選擇頁面元素
    }

    get signUp() {
        return Selector('.S_txt1').withText('註冊')
    }

    async searchSomething(keyword) {
        await t.selectText(this.inputSearchContent).pressKey('delete')//調用testcafe的api進行頁面操作,各種具體操作可以查看官網Docs->Test API
            .typeText(this.inputSearchContent, keyword).pressKey('enter')
    }

    async clickSignUp() {
        await t.click(this.signUp)
    }
}

export default new WeiboHomePage()//供其他js文件調用

weiboSignUpPage.js

import {Selector, t} from 'testcafe'

class WeiboSignUpPage {

    get telNumber() {
        return Selector('input[name=username]')
    }

    get password() {
        return Selector('input[name=passwd]')
    }

    get birthdayYear() {
        return Selector('select[node-type=birthday_year]')
    }

    get birthdayMonth() {
        return Selector('select[node-type=birthday_month]')
    }

    get birthdayDay() {
        return Selector('select[node-type=birthday_day]')
    }

    get pincode() {
        return Selector('input[name=pincode]')
    }

    get submit() {
        return Selector('a[action-type=btn_submit]')
    }

    async fillSignUpFormAndSubmit(telNumber, passwd, birthdayYear, birthdayMonth, birthdayDay, pincode) {
        await t.typeText(this.telNumber, telNumber)
            .typeText(this.password, passwd)
            .click(this.birthdayYear)
            .click(Selector('option').filter('[value="' + birthdayYear + '"]'))
            .click(this.birthdayMonth)
            .click(Selector('option').filter('[value="' + birthdayMonth + '"]'))
            .click(this.birthdayDay)
            .click(Selector('option').filter('[value="' + birthdayDay + '"]'))
            .typeText(this.pincode, pincode)
            .click(this.submit)
    }

    async shouldShowErrorMessage(errorMessage) {
        await t.expect(Selector('.error').nth(0).textContent).contains(errorMessage)
    }
}

export default new WeiboSignUpPage()

3.運行測試用例

(1)直接使用命令運行用例

testcafe chrome test/weiboSignUpTest.js

(2)將命令下載package.json裏面,命令行直接運行

npm run weiboSignUpTest
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "testCafeFeedbackTest": "testcafe chrome test/testCafeFeedbackTest.js",
  "weiboSignUpTest": "testcafe chrome test/weiboSignUpTest.js"
}

4.Live模式

在寫測試代碼的過程中,你有沒有發現這樣一個問題:一旦元素找錯了或者代碼中有錯誤,用例運行失敗,瀏覽器關閉,沒辦法查看現場,修改代碼之後又需要重新運行用例,很耗費時間且不方便排查錯誤。
這時候我們就需要使用Live模式了,運行用例的時候啓用Live模式:testcafe chrome test/weiboSignUpTest.js
這時候你會發現,當用例運行完成(失敗/成功)瀏覽器並不會關閉,你可以清晰的知道用例停在哪一步了,並且可以打開developer tool進行問題排查。當你發現問題並修改代碼後,testcafe會監聽到代碼變化,會自動重新運行用例,但在調試的過程中我發現並不是每一次它都正確監聽到了代碼的變化並自動重新運行用例,這時候你就需要用到一下幾個命令了:
‘Ctrl+S’ - 停止運行用例;
‘Ctrl+R’ - 重新運行用例;
‘Ctrl+W’ - 監聽/不監聽源碼的變化;
‘Ctrl+C’ - 停止live模式並且關閉瀏覽器.

5.多瀏覽器運行用例

testcafe最大的最吸引人的特點就是支持多瀏覽器運行用例,可以很好支持兼容性測試,也可以支持多用例並行測試減少用例運行時間。
(1)通用瀏覽器
同一用例多個瀏覽器同時運行

testcafe chrome,safari,firefox test/weiboSignUpTest.js

多個js文件裏的多個用例在同一瀏覽器併發運行

testcafe -c 3 chrome  test/*.js

單個js文件裏的多個用例在同一瀏覽器併發運行

testcafe -c 2 chrome test/testCafeFeedbackTest.js

(2)不常見瀏覽器
testcafe現在支持主流的大部分瀏覽器:
Google Chrome: Stable, Beta, Dev and Canary
Internet Explorer (11+)
Microsoft Edge (legacy and Chromium-based)
Mozilla Firefox
Safari
Google Chrome mobile
Safari mobile
其他暫不支持的瀏覽器可以自己寫一個browser provider plugin,testcafe官網有詳細教程可以參考:https://devexpress.github.io/testcafe/documentation/extending-testcafe/browser-provider-plugin/
在npm也有一些寫好的插件,可以直接下載使用:https://www.npmjs.com/search?q=testcafe-browser-provider

6.遠程設備運行測試用例

testcafe還支持在沒有安裝testcafe的遠程設備上運行測試用例,是通過命令生成url,遠程設備只要訪問該url即可運行測試用例,當然,前提是遠程設備需要和生成url的設備在子同一局域網內。
(1)生成二維碼供遠程設備訪問

testcafe remote tests/weiboSignUpTest.js

(2)生成二維碼供移動端訪問

testcafe remote tests/weiboSignUpTest.js --qr-code

(3)如果想要多臺遠程設備同時連接

testcafe remote:3 tests/weiboSignUpTest.js

7.配置configure文件

由以上的練習我們可以知道,每次運行需要用例的時候需要使用各種參數來達到不同的目的,比如每次都需要指定測試運行的瀏覽器,瀏覽器是否可以在某個地方統一配置?如果要生成測試報告、截圖是要怎麼配置?
testcafe提供了配置文件.testcaferc.json來存儲這些配置,每次運行時會使用該文件裏的配置,如果運行時指定了特定參數會覆蓋文件裏的配置。下面會介紹幾個常見的配置。
(1)指定瀏覽器

"browsers": ["chrome", "firefox","safari”]

在這裏設置之後,運行用例的命令裏就不再需要指定瀏覽器了,可以直接運行:testcafe tests/weiboSignUpTest.js

(2)截圖相關配置

"screenshots": {
  "path": "screenshots",
  "takeOnFails": true,
  "pathPattern": "${DATE}_${TIME}/test-${TEST_INDEX}/${USERAGENT}/${FILE_INDEX}.png",
  "fullPage": true
}

(3)報告相關配置
testcafe支持多種格式的報告,內置的有spec/list/minimal/xUnit/JSON(可以各自試一下查看一下報告效果),如果想要其他格式的可以自定義格式,下載插件generator-testcafe-reporter,然後按照官網教程開發自定義報告式:https://devexpress.github.io/testcafe/documentation/extending-testcafe/reporter-plugin/,當然npm社區也有一些已經開發好的報告格式,可以自行下載:https://www.npmjs.com/search?q=testcafe-reporter。既然testcafe支持多種格式的測試報告,當然它也支持同時生成多種格式的報告,但是它只支持一種報告輸出到日誌中,其他類型的測試報告需要指定輸出文件,如下圖,配置了默認的spec類型的測試報告和html類型的測試報告並且指定輸出路徑。

"reporter": [
  {
    "name": "spec"
  },
  {
    "name": "html",
    "output": "report/report.html"
  }
]

(4)跳過js錯誤檢查
testcafe有一個很棒的小功能,可以檢查被測頁面的js錯誤,如果有錯誤則判定爲用例失敗。但如果你的項目組對js錯誤沒有很高的要求,那麼你可以設置不檢查頁面的js錯誤。

"skipJsErrors": true

以上是筆者認爲比較常用的configure配置,還有很多其他的有用的配置可以參考:https://devexpress.github.io/testcafe/documentation/using-testcafe/configuration-file.html

至此,使用testcafe進行UI測試常用的、特色的功能已經介紹得差不多了,當然還有持續集成部分筆者沒有介紹,如果需要請參考:https://devexpress.github.io/testcafe/documentation/continuous-integration/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章