你不知道的Cypress系列(11) -- 使用cy.session()加速鉴权。

iTesting

共 5643字,需浏览 12分钟

 · 2021-09-28

iTesting,爱测试,爱分享


转眼之间,你不知道的Cypress系列已经到第11篇了。在Cypress中国群内、在公众号iTesting里,我每天都能看到大量关于Cypress的使用讨论和私下问询。这让我感到无比荣幸(买了书的同学们,公众号回复你的微信号,拉你到Cypress中国群)。

今天是你不知道的Cypress系列(11) -- 使用cy.session()加速鉴权。

鉴权的问题

鉴权(authentication)是指验证用户是否拥有访问系统的权利。在自动化测试中特制登录态的保持。 当前登录态的保持,存在如下痛点: 

  • 1.  每次测试开始前必须重新登录。 

  • 2.  在通过一个测试中,切换账户登录需要先登出。

针对第一个问题, 当前普遍的做法是将登录命令封装在Custom Commands中(比如封装成cy.login()),然后在每个测试用例运行时,即beforeEach()中调用cy.login()。为了减少登录的次数,有些同学会使用before()这个前置操作,即在JS文件的一次执行中,无论有多少个测试用例,仅登录一次,登录后使用Preserve Cookies来保持登录态。Preserve Cookies相关代码一般写在index.js中,用于在获取登录态后保持它不被清除(这个方法你需要明确知道要保留那些Cookie)。但这个方法违背了每个测试用例应该是独立的、原子的这个特性。

针对第二个问题,,在同一个测试用例中使用不同账户登录,只能先登出第一个,然后再登录第二个。无形中增加了整个测试用例的执行时间。

这两个问题的存在影响了测试效率,直到8.2.0发布,Cypress有了更好的解决办法。

解决设想

我在书中以及无数次公开课中都提到过,鉴权最关键的就是登录态,而登录态,最关键的还是Session和Cookie。(Cookie和Session的知识参见我是如何面试的 -- 从一道面试题说开去)。而Cypress解决鉴权问题的思维很简单:

1. Cypress使用cy.session()命令在登录成功后,将cookies、localStorage和sessionStorage缓存起来。2. 当你下次再使用cy.login()登录时,将不再登录,而是将缓存的cookieslocalStoragesessionStorage恢复从而达到获取登录态的目的。

如何应用

那么,如何使用cy.session()呢?

首先,你需要升级Cypress至8.2.0。

yarn upgrade cypress@8.2.0


其次,在项目根目录下的cypress.json文件里,添加如下设置。

  "experimentalSessionSupport"true,


最后,更新登录的代码,使用cy.session。

// 关注公众号iTesting,跟万人测试团一起成长
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()都是恢复缓存,不是真正的执行登录操作。节省了时间。2. 当你在同个测试用例中切换账户,无需登出,直接登录即可。


下面列一个在同个测试用例中使用多个账户登录的场景。

// 关注公众号iTesting,跟万人测试团一起成长
it('多账户在同一个测试用例中登录', () => {
  // 第一个账户登录
  cy.login('iTesting''isGood')
  // 注意,使用cy.session()后,cy.visit()不能省略,必须显式调用
 // 原因看下面解释
  cy.visit('/account')
  cy.get('#amount').type('100.00')
  cy.get('#send-money').click()

  // 一般情况下,此时应调用cy.logout()函数
  // 使用cy.session()后,无需调用cy.logout()函数
  // 直接登录下一个账户
  cy.login('另外账户''另外账户密码')
  cy.visit('/account')
  cy.get('#balance').should('eq''100.00')
})


需要注意的是

1. 这个功能是试验性质的,还不属于正式功能。2. 在启用experimentalSessionSupport这个选项后,Cypress做了如下几件事:    1)只有这个选项enable后,cy.session()才能在测试用例中在使用。    2)Cypress.session API被添加了进来。Cypress.session 是一组与会话相关的辅       助方法,旨在与cy.session() 命令一起使用。    3)在每个测试用例开始之前:        (1)被访问的页面被Cypress重设成about:blank        (2)所有活动的Session数据被清除        (3)以下两个方法被重写:Cypress.Cookies.preserveOnce()                                        Cypress.Cookies.defaults()
由于页面在每个测试用例执行前被清除,因此必须在每个测试用例中显式调用 cy.visit() 以访问应用程序中的页面。

总结

使用cy.session(),Cypress仅会在第一次登录时候执行真正的登录操作,在同一个JS文件中的后续任何同个账户的登录操作,都将通过恢复Session的方式来进行。这种行为缩短了测试的时间。



Cypress有很多奇淫巧技, 我已经总结超过百篇

别走开,下一篇更精彩!

往期回看:

                    你不知道的Cypress系列(1) --鸡肋的BDD

                    你不知道的Cypress系列(2) -- ”该死"的PO模型!

                    你不知道的Cypress系列(3) -- 是时候重构自己的思维了!

                    你不知道的Cypress系列(4) -- “PO”已死,App Action当立?

                    你不知道的Cypress系列(5) -- "眼瞎"的TestRunner

                    你不知道的Cypress系列(6) -- 多Tab的小秘密

                       你不知道的Cypress系列(7) -- 当iFrame遇见弹出框          


                        你不知道的Cypress系列(8) -- “可视化”测试你知多少


                        你不知道的Cypress系列(9) -- 代码“自动生成”术

         

                        你不知道的Cypress系列(10) -- CypressHelper


              

为了更好的支持我创作,麻烦同学们动动小手,点赞 + 在看 + 转发一键三联:)


技术讨论

公众号里直接回复 666, 带你入圈


 -   -  时人莫小池中水, 浅处不妨有卧龙  -  -

作者:

Kevin Cai, 江湖人称蔡老师。

两性情感专家,非著名测试开发。

技术路线的坚定支持者,始终相信Nobody can be somebody。      


· 猜你喜欢的文章 ·


功能测试进阶系列直播(免费)

前端测试框架Cypress从入门到精通

自研测试框架ktest介绍(适用于UI和API)

测试开发入门与实战

浏览 16
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报