3 Cypress 測驗框架概述
3.1 Cypress 默認檔案結構
? ? 在Cypress安裝完成后,其生成的默認檔案目錄如下所示:

3.1.1 Fixtures
? ? Fixture又稱之為測驗夾具,通常配合cy.fixture命令使用,主要用于存盤測驗用例的外部靜態資料,其默認位置位于cypress\fixtures中,也可以根據需要配置到其他目錄, Fixtures里面的靜態資料通常存盤在json檔案中,而這部分資料通常是某個網路請求對應的回應部分,如HTTP狀態碼和回傳值等,Fixture的應用場景通常為,當測驗需要對某些外部介面進行訪問并依賴于其回傳值時,可以使用fixture而無需訪問這些介面,
3.1.2 測驗檔案
? ? 測驗檔案就是對應的測驗用例,一般位于cypress\integration中,也可以根據需要配置到另一個目錄中,通常為js檔案,在Cypress中其他命令格式為:fileName.spec.js,支持的檔案型別如下所示:
- .js
- .jsx
- .coffee
- .cjsx
3.1.3 Plugins
? ? 在Cypress中,測驗代碼是運行瀏覽器里面,提供了更加可靠的測驗體驗,但也存在明顯的缺點,使得與瀏覽器之外進行通信更加困難,為解決這個問題,Cypress提供了一些插件,可以修改或擴展Cypress的內部行為,插件一般位于cypress\plugins,在每個測驗檔案運行之前,Cypress會自動加載該目錄中的index.js檔案,
3.1.4 Support
? ? 支持檔案一般位于目錄cypress\support中,可以根據需要放置在其他目錄中,其主要功能是放置可復用配置項,如底層通用方法、全域默認配置等,在每個測驗檔案運行前,Cypress會自動加載該目錄中的index.js檔案,
? ? 使用方法也非常簡單,僅需要在cypress\support\index.js檔案中添加beforeEach()函式即可,示例如下所示:
beforeEach( function (){
cy.log(`Current Enviroment is ${JSON.stringfy(Cypress.env())}`)
}
)
3.2 核心概念
3.2.1 核心引數配置
? ? 在第一次打開Cypress Test Runner后,cypress.json將會創建,目錄與Cypress同級,該檔案主要用于保存所有支持的自定義配置,在配置了錄制和測驗專案后,則projectId將會被保存至cypress.json檔案中,
用戶可以通過引數來定義所使用的組態檔,引數為--config-file
3.2.1.1 全域配置項
? ? 以下為Cypress支持的常用自定義的全域配置及其默認值,如下所示:
| 配置項 | 默認值 | 描述 |
|---|---|---|
| baseUrl | null | URL前綴,通常與命令cy.visit()/cy.request()結合使用 |
| clientCertificates | [] | 客戶端證書選項陣列 |
| env | {} | 環境變數設定選項,任何支持的值均可 |
| numTestsKeptInMemory | 50 | 在記憶體中保存的快照和命令資料等數量,在運行測驗時,若記憶體占用太高,可以減少該值 |
| port | null | Cypress使用的埠號,默認隨機產生 |
| redirectionLimit | 20 | 在出現錯誤前,允許應用程式在測驗運行時重定向的數量 |
| reporter | spec | 在Cypress運行時使用的的reporter |
| reporterOptions | null | reporter支持的配置選項 |
| watchForFileChanges | true | 用于監測檔案變化,若有變化,則自動重新運行該用例 |
3.2.1.2 超時
? ? 超時是Cypress中的核心概念,所以必須了解,常見的超時引數如下所示:
| 配置項 | 默認值 | 描述 |
|---|---|---|
| defaultCommandTimeout | 4000 | 命令默認超時時間,單位為ms |
| execTimeout | 60000 | 在cy.exec()執行期間,等待系統命令完成執行的超時時間,單位為ms |
| taskTimeout | 60000 | 在cy.task()執行期間,等待任務完成執行的超時時間,單位為ms |
| pageLoadTimeout | 60000 | 在等待頁面加載或cy.visit()/cy.go()/cy.reload()等命令觸發其他頁面加載事件的超時時間,單位為ms,網路請求受限于作業系統 |
| requestTimeout | 5000 | 在執行cy.wait()命令時,請求超時時間,單位為ms |
| responseTimeout | 30000 | 在執行命令cy.request()/cy.wait()/cy.fixture()/cy.getCookie()/cy.getCookies()/cy.setCookie()/ cy.clearCookie()/ cy.clearCookies/cy.screenshot()時的回應超時時間,單位為ms |
| slowTestThreshold | 10000 | 250 | 在Cypress run期間,運行較慢的測驗用例在reporter中將會以桔黃色顯示,通過該引數可進行單獨設定E2E和組件測驗超時時間,E2E默認超時時間為 10000ms,而組件測驗為250ms,單位為ms |
3.2.1.3 目錄和檔案
? ? Cypress支持自定義目錄和檔案,如下所示:
| 配置項 | 默認值 | 描述 |
|---|---|---|
| downloadsFolder | cypress/downloads | 在測驗期間,默認的檔案下載目錄 |
| fileServerFolder | root project folder | 向服務器發送的應用程式檔案目錄 |
| fixturesFolder | cypress/fixtures | fixture默認目錄,可更改默認值為false來禁用 |
| ignoreTestFiles | *.hot-update.js | 在運行期間,需要忽略的測驗用例 |
| integrationFolder | cypress/integration | 測驗用例所在目錄 |
| pluginsFile | cypress/plugins/index.js | Plugins所在目錄,可更改默認值為false來禁用 |
| screenshotsFolder | cypress/screenshots | 在測驗用例運行失敗或cy.screenshot()命令觸發截圖,用于保存這些截圖的目錄 |
| supportFile | cypress/support/index.js | 在測驗加載之前要加載的檔案 |
| testFiles | **/. | 要加載的測驗檔案 |
| videosFolder | cypress/videos | 在Cypress run運行期間,用于保存video的目錄 |
3.2.1.4 截圖
| 配置項 | 默認值 | 描述 |
|---|---|---|
| screenshotOnRunFailure | true | 測驗用例運行失敗后將進行截圖 |
| screenshotsFolder | cypress/screenshots | 在測驗用例運行失敗或cy.screenshot()命令觸發截圖,用于保存這些截圖的目錄 |
3.2.1.5 視頻
| 配置項 | 默認值 | 描述 |
|---|---|---|
| videoCompression | 32 | 設定視頻的壓縮比,設定為false關閉壓碩訓0~51,數字越低,視頻質量越好,檔案越大 |
| videosFolder | cypress/videos | 在Cypress run運行期間,用于保存video的目錄 |
| video | true | 是否啟用視頻功能 |
| videoUploadOnPasses | true | 是否啟用在用例運行通過后,上傳視頻至Dashboard,僅適用于錄制專案,如果關閉該功能,則僅上傳運行失敗的視頻 |
3.2.1.6 視圖
| 配置項 | 默認值 | 描述 |
|---|---|---|
| viewportHeight | 660 | 測驗視圖下待測驗應用程式的默認高度,單位為pixels,可使用cy.viewport()命令覆寫 |
| viewportWidth | 1000 | 測驗視圖下待測驗應用程式的默認寬度,單位為pixels,可使用cy.viewport()命令覆寫 |
更多自定義選項,可查閱官方檔案,地址為:https://docs.cypress.io/guides/references/configuration
3.2.1.7 命令列
? ? 除了使用組態檔進行配置以外,也可以使用命令列進行設定以下各個引數,如下所示:
cypress open --config pageLoadTimeout=30000,baseUrl=https://www.surpass.com
cypress run --config integrationFolder=tests,videoUploadOnPasses=false
3.2.1.8 Cypress.config()
? ? 除了直接在cypress.json檔案中更改配置之外,也可以通過Cypress.config()去獲取或覆寫某些配置項,其基本使用方法如下所示:
// 獲取所有config資訊
Cypress.config()
// 獲取指定config資訊
Cypress.config(name)
// 更改指定config資訊
Cypress.config(name,value)
// 設定多個config項
Cypress.config(object)
? ? 示例代碼如下所示:
describe("測驗Cypress.config",function(){
it("獲取defaultCommandTimeout",function(){
cy.log(`defaultCommandTimeout value is:${Cypress.config("defaultCommandTimeout")}`)
// 設定引數選項值
Cypress.config("defaultCommandTimeout",99999)
cy.log(`defaultCommandTimeout value is:${Cypress.config("defaultCommandTimeout")}`)
})
})
? ? 運行結果如下所示:

3.2.2 用例結構
? ? Cypress是建立在Mocha和Chai之上,因此同時支持Chai的BDD和TDD兩種風格,如果你熟悉JavaScript風格的代碼,那么在Cypress中寫測驗用例是很容易上手的,
Mocha是一款適用于Node.js和瀏覽器的測驗框架,可使用異步測驗變得簡單靈活,
? ? Cypress的測驗風格繼承于Mocha,提供了describe()、context()、it()、specify()四個關鍵字,對于一條可執行的測驗而言,必須包含以下兩個組成部分:
- describe()和context()等效,均表示一個測驗套件或測驗集
- it()和specify()等效,均表示一個測驗用例
? ? 示例如下所示:
describe('我是一個測驗集', () => {
it('測驗用例-1', () => {
expect(1+2).to.eq(3)
});
it('測驗用例-2', () => {
expect(3-2).to.eq(1)
});
it('測驗用例-3', () => {
expect(3*2).to.eq(5)
});
});
? ? 最終的運行結果如下所示:

更多測驗用例的組織和撰寫會在后續詳細講解
3.2.3 重試機制
? ? 重試是Cypress一個非常重要的功能,在了解重試的概念后,有助于寫出更加健壯的測驗,
3.2.3.1 命令和斷言
? ? 命令和斷言是兩種在Cypress中測驗常用的兩種方法,示例如下所示:
/// <reference types="cypress" />
describe('', () => {
let baseUrl="https://example.cypress.io/todo"
it('測驗用例-1', () => {
// 一個命令 visit
cy.visit(baseUrl);
// 一個命令 get,一個斷言 should
cy.get(".header input").should("have.class","new-todo");
// 三個命令 get 和 type
cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
// 一個命令 get,一個斷言 should
cy.get('.todo-list li').should('have.length', 4);
});
});
? ? 最終的運行結果如下所示:

? ? 讓我們一起來看看最后一行的命令和斷言,如下所示:
cy.get('.todo-list li').should('have.length', 4);
? ? 以上命令和斷言,是通過cy.get()命令查找頁面的DOM,在找到與選擇器匹配的元素,然后進行斷言嘗試,而現在很多WEB應用幾乎都是異步的,以最后一行代碼為例,Cypress不能在查詢DOM元素(todo-list)的同時又去檢查其元素個數是否為4個,因此在出現以下情況,就會出現問題,如下所示:
- 1.當運行命令或斷言時,應用程式沒有更新DOM時,怎么辦?
- 2.當運行命令或斷言時,應用程式正在等待后端回傳回應,而頁面暫時沒有結果時,怎么辦?
- 3.當運行命令或斷言時,應用程式正在進行密集計算,而導致頁面顯示未及時更新時,怎么辦?
? ? 以上幾種情況,在測驗程序中非常常見,一般處理辦法在斷言前,設定一個等待時間,但這個等待時間,在不同環境中還不能完全統一,還是會導致經常出錯,而Cypress處理這種問題,則非常智能,如下所示:
在實際運行時,如果cy.get()命令之后的斷言通過,則認為該命令成功執行,如果失敗,則cy.get()命令將重新查詢應用程式的DOM,再進行斷言,如果失敗,則再次執行cy.get()命令查詢DOM,再進行斷言,依此類推,直至斷言成功或cy.get()命令超時為止,
? ? 正是因為Cypress的這種自動重試功能避免了在測驗代碼中出現硬編碼的等待,使測驗代碼更加健壯,
3.2.3.2 多重斷言
? ? 在日常測驗中,有時候需要對一個資料進行多次斷言,Cypress提供一種方法叫多重斷言,其定義為:單個命令后跟多個斷言,在斷言時,Cypress將按順序重試每個命令,即當第一個斷言通過后,在進行第二個斷言時仍會重試第一個斷言,當第一和第二個斷言都通過后,在進行第三個斷言,仍然會重試第一和第二個斷言,依此類推,來看看以下示例:
/// <reference types="cypress" />
describe('多重斷言示例', () => {
let baseUrl="https://example.cypress.io/todo";
it('演示用例-1', () => {
cy.visit(baseUrl);
cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
cy.get('.todo-list li')
.should('have.length',4)
.and(($li) => {
expect($li.get(2).textContent,'first item').to.equal('todo A')
expect($li.get(3).textContent,'second item').to.equal('todo B')
});
});
});
.and()斷言是.should()的別名,它是.should()的自定義回呼函式,包含兩個expect()斷言,
? ? 最終的運行結果如下所示:

? ? 上面代碼共有三個斷言,分別是should和兩個expect,在測驗程序中,如果第二個斷言失敗了,則第三個斷言不會執行,如果第二個斷言執行通過,整個命令還未超時,在執行第三個斷言前,會再次重試第一個和第二個斷言,
? ? 修改代碼使得第二個斷言出現失敗,代碼如下所示:
/// <reference types="cypress" />
describe('多重斷言示例', () => {
let baseUrl="https://example.cypress.io/todo";
it('演示用例-1', () => {
cy.visit(baseUrl);
cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
cy.get('.todo-list li')
.should('have.length',4)
.and(($li) => {
expect($li.get(2).textContent,'first item').to.equal('toda A')
expect($li.get(3).textContent,'second item').to.equal('todo B')
});
});
});
? ? 在第二個斷言運行失敗后,第三個斷言則不會被執行,在執行命令超時后,會在運行頁面顯示第一個斷言執行成功,第二個斷言執行失敗,如下圖所示:

3.2.3.3 重試條件
? ? Cypress并不會重試所有命令,當命令可能改變待測應用程式的狀態時,則將不會進行重試操作(例如.click()命令),Cypress僅會重試查詢DOM的命令,例如cy.get()、.find()、.contains()等等,
如果需要查詢更多重試的命令,可查閱API檔案中Assertions檔案https://docs.cypress.io/guides/references/assertions
? ? 重試的超時時間默認為4s,也可通過defaultCommandTimeout進行設定,
3.2.3.3.1 增加超時時間
? ? 我們也可以通過修改所有命令的超時時間,例如,將全域的默認超時時間設定為10s,如下所示:
cypress run --config defaultCommandTimeout=10000
? ? 以上這種方式可以修改全域的超時時間,但不推薦,相反,我們可以通過設定單個命令的超時時間{ timeout: ms },而更加靈活的控制各個命令的超時時間,示例如下所示:
/// <reference types="cypress" />
describe('多重斷言示例', () => {
let baseUrl="https://example.cypress.io/todo";
it('演示用例-1', () => {
cy.visit(baseUrl,{timeout:1000});
cy.get('.new-todo').type('todo A{enter}').type('todo B{enter}');
cy.get('.todo-list li')
.should('have.length',4)
.and(($li) => {
expect($li.get(2).textContent,'first item').to.equal('toda A')
expect($li.get(3).textContent,'second item').to.equal('todo B')
});
});
});
? ? 以上代碼,設定訪問網站的超時時間為1s,運行結果如下所示:

3.2.3.3.2 禁用重試
? ? 如果將超時時間設定為0,其本質上是禁用重試機制,示例如下所示:
cy.get('.new-todo',,{timeout:0}).type('todo A{enter}').type('todo B{enter}');
原文地址:https://www.jianshu.com/p/55819e173a5d
本文同步在微信訂閱號上發布,如各位小伙伴們喜歡我的文章,也可以關注我的微信訂閱號:woaitest,或掃描下面的二維碼添加關注:

作者: Surpassme
來源: http://www.jianshu.com/u/28161b7c9995/
http://www.cnblogs.com/surpassme/
宣告:本文著作權歸作者所有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出 原文鏈接 ,否則保留追究法律責任的權利,如有問題,可發送郵件 聯系,讓我們尊重原創者著作權,共同營造良好的IT朋友圈,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/505327.html
標籤:其他
下一篇:用python反彈shell
