你不知道的Cypress系列(11) -- 使用cy.session()加速鑒權(quán)。
iTesting,愛測試,愛分享
轉(zhuǎn)眼之間,你不知道的Cypress系列已經(jīng)到第11篇了。在Cypress中國群內(nèi)、在公眾號iTesting里,我每天都能看到大量關(guān)于Cypress的使用討論和私下問詢。這讓我感到無比榮幸(買了書的同學(xué)們,公眾號回復(fù)你的微信號,拉你到Cypress中國群)。
今天是你不知道的Cypress系列(11) -- 使用cy.session()加速鑒權(quán)。
鑒權(quán)的問題
鑒權(quán)(authentication)是指驗證用戶是否擁有訪問系統(tǒng)的權(quán)利。在自動化測試中特制登錄態(tài)的保持。 當(dāng)前登錄態(tài)的保持,存在如下痛點:
1. 每次測試開始前必須重新登錄。
2. 在通過一個測試中,切換賬戶登錄需要先登出。
針對第一個問題, 當(dāng)前普遍的做法是將登錄命令封裝在Custom Commands中(比如封裝成cy.login()),然后在每個測試用例運行時,即beforeEach()中調(diào)用cy.login()。為了減少登錄的次數(shù),有些同學(xué)會使用before()這個前置操作,即在JS文件的一次執(zhí)行中,無論有多少個測試用例,僅登錄一次,登錄后使用Preserve Cookies來保持登錄態(tài)。Preserve Cookies相關(guān)代碼一般寫在index.js中,用于在獲取登錄態(tài)后保持它不被清除(這個方法你需要明確知道要保留那些Cookie)。但這個方法違背了每個測試用例應(yīng)該是獨立的、原子的這個特性。
針對第二個問題,,在同一個測試用例中使用不同賬戶登錄,只能先登出第一個,然后再登錄第二個。這無形中增加了整個測試用例的執(zhí)行時間。
這兩個問題的存在影響了測試效率,直到8.2.0發(fā)布,Cypress有了更好的解決辦法。
解決設(shè)想
我在書中以及無數(shù)次公開課中都提到過,鑒權(quán)最關(guān)鍵的就是登錄態(tài),而登錄態(tài),最關(guān)鍵的還是Session和Cookie。(Cookie和Session的知識參見我是如何面試的 -- 從一道面試題說開去)。而Cypress解決鑒權(quán)問題的思維很簡單:
1. Cypress使用cy.session()命令在登錄成功后,將cookies、localStorage和sessionStorage緩存起來。2. 當(dāng)你下次再使用cy.login()登錄時,將不再登錄,而是將緩存的cookies、localStorage和sessionStorage恢復(fù)從而達(dá)到獲取登錄態(tài)的目的。
如何應(yīng)用
那么,如何使用cy.session()呢?
首先,你需要升級Cypress至8.2.0。
yarn upgrade cypress@8.2.0
其次,在項目根目錄下的cypress.json文件里,添加如下設(shè)置。
"experimentalSessionSupport": true,
最后,更新登錄的代碼,使用cy.session。
// 關(guān)注公眾號iTesting,跟萬人測試團(tuán)一起成長
Cypress.Commands.add('login', (username, password) => {
cy.session([username, password], () => {
cy.visit('/login')
cy.get('[data-test=username]').type(username)
cy.get('[data-test=password]').type(password)
cy.get('#login').click()
cy.url().should('contain', '/login-successful')
})
})```
最后,你就可以無感使用啦, 使用場景如下:
1. beforeEach()中寫了cy.login(),多個測試用例中,只有第一次登錄是真正的登錄,剩余的cy.login()都是恢復(fù)緩存,不是真正的執(zhí)行登錄操作。節(jié)省了時間。2. 當(dāng)你在同個測試用例中切換賬戶,無需登出,直接登錄即可。
下面列一個在同個測試用例中使用多個賬戶登錄的場景。
// 關(guān)注公眾號iTesting,跟萬人測試團(tuán)一起成長
it('多賬戶在同一個測試用例中登錄', () => {
// 第一個賬戶登錄
cy.login('iTesting', 'isGood')
// 注意,使用cy.session()后,cy.visit()不能省略,必須顯式調(diào)用
// 原因看下面解釋
cy.visit('/account')
cy.get('#amount').type('100.00')
cy.get('#send-money').click()
// 一般情況下,此時應(yīng)調(diào)用cy.logout()函數(shù)
// 使用cy.session()后,無需調(diào)用cy.logout()函數(shù)
// 直接登錄下一個賬戶
cy.login('另外賬戶', '另外賬戶密碼')
cy.visit('/account')
cy.get('#balance').should('eq', '100.00')
})
需要注意的是:
1. 這個功能是試驗性質(zhì)的,還不屬于正式功能。2. 在啟用experimentalSessionSupport這個選項后,Cypress做了如下幾件事: 1)只有這個選項enable后,cy.session()才能在測試用例中在使用。 2)Cypress.session API被添加了進(jìn)來。Cypress.session 是一組與會話相關(guān)的輔 助方法,旨在與cy.session() 命令一起使用。 3)在每個測試用例開始之前: (1)被訪問的頁面被Cypress重設(shè)成about:blank (2)所有活動的Session數(shù)據(jù)被清除 (3)以下兩個方法被重寫:Cypress.Cookies.preserveOnce() Cypress.Cookies.defaults()由于頁面在每個測試用例執(zhí)行前被清除,因此必須在每個測試用例中顯式調(diào)用 cy.visit() 以訪問應(yīng)用程序中的頁面。
總結(jié)
使用cy.session(),Cypress僅會在第一次登錄時候執(zhí)行真正的登錄操作,在同一個JS文件中的后續(xù)任何同個賬戶的登錄操作,都將通過恢復(fù)Session的方式來進(jìn)行。這種行為縮短了測試的時間。
Cypress有很多奇淫巧技, 我已經(jīng)總結(jié)超過百篇
別走開,下一篇更精彩!
往期回看:
你不知道的Cypress系列(1) --雞肋的BDD
你不知道的Cypress系列(2) -- ”該死"的PO模型!
你不知道的Cypress系列(3) -- 是時候重構(gòu)自己的思維了!
你不知道的Cypress系列(4) -- “PO”已死,App Action當(dāng)立?
你不知道的Cypress系列(5) -- "眼瞎"的TestRunner
你不知道的Cypress系列(6) -- 多Tab的小秘密
你不知道的Cypress系列(7) -- 當(dāng)iFrame遇見彈出框
你不知道的Cypress系列(8) -- “可視化”測試你知多少
你不知道的Cypress系列(9) -- 代碼“自動生成”術(shù)
你不知道的Cypress系列(10) -- CypressHelper
為了更好的支持我創(chuàng)作,麻煩同學(xué)們動動小手,點贊 + 在看 + 轉(zhuǎn)發(fā)一鍵三聯(lián):)
技術(shù)討論
公眾號里直接回復(fù) 666, 帶你入圈
- - 時人莫小池中水, 淺處不妨有臥龍 - -
作者:
Kevin Cai, 江湖人稱蔡老師。
兩性情感專家,非著名測試開發(fā)。
技術(shù)路線的堅定支持者,始終相信Nobody can be somebody。
· 猜你喜歡的文章 ·
