【问题标题】:cypress session redirects to blank page赛普拉斯会话重定向到空白页
【发布时间】:2023-02-08 23:27:14
【问题描述】:

我是 cypress 的新手,可能缺少一些关于会话如何在 cypress 中工作的关键理解。

我正在构建一个简单的测试,它将登录到系统,然后执行特定操作 贝娄是我的测试。登录功能按预期执行,但是当第一个 it 完成时,序列转到空白页面,除非我在下一个 it 中再次登录,否则它不起作用。 我怎样才能在不同的its 之间保持会话而不让它跳转页面?

describe('create cycle', () =>{

    it("login as super user", () =>{
    cy.session('login', ()=>{
            cy.visit('/')
            login();
        })  
    })

    it('start cycle', ()=>{  
      cy.get("#cycles-library > ul > #library-item-2").click();
      cy.get("#create-cycle").click()
      cy.get("#startDate > label").first().click()
      cy.get("#duration > label").first().click()
      cy.get('#groups-input').click()
      cy.get("body>div").last().contains('group 2').click()
      cy.get("button#create-cycle").click()

    })

})

谢谢!

【问题讨论】:

    标签: reactjs testing cypress


    【解决方案1】:

    cy.session() 通常与beforeEach() 一起使用以确保为每个测试设置正确的会话数据。

    模式是

    describe('tests requiring session data', () =>{
    
      beforeEach(() =>{
        cy.session('login', ()=>{
          cy.visit('/')
          login();
        })  
      })
    
      it('test that expects logged-in status', () => {  
    
      it('another one', () => {  
    })
    

    看起来您每次都在执行登录,但事实并非如此。 cy.session() 是一个缓存函数,它在第一次测试时运行一次,然后只为每个后续测试恢复会话数据。

    你可以把它想象成 React hooks useEffect() 和一个空的依赖列表,它在组件生命周期中也只运行一次。

    自从你有一个登录测试,你应该在另一个 describe() 块中单独执行它,因为每个测试的初始条件都不同。

    【讨论】:

      【解决方案2】:

      每个it 都会清除导航器存储,包括您的会话。

      要处理此问题,您应该创建一个 cypress command,它将为您创建会话,此命令可以根据您的身份进行更改。

      例如,如果你有一个简单的 POST /login 端点,它接收用户名和密码参数,返回的会话数据必须存储在 cookie 中,你可以做类似的事情:

      // cypress/support/commands.js
      Cypress.Commands.add('login', () => {
        cy.request('POST', `${Cypress.env('apiUrl')}/users/login`, {
          username: Cypress.env('userEmail'),
          password: Cypress.env('userPassword'),
        }).then((response) => {
          cy.setCookie('sessionId', response.body.sessionId)
          cy.setCookie('userId', response.body.userId)
          cy.setCookie('userName', response.body.userName)
        })
      })
      

      在你的测试或beforeEach测试中:

      ...
          it('start cycle', () => {  
            cy.login()
            // cy.get("#cycles-library > ul > #library-item-2").click();
            // cy.get("#create-cycle").click()
            // cy.get("#startDate > label").first().click()
            // cy.get("#duration > label").first().click()
            // cy.get('#groups-input').click()
            // cy.get("body>div").last().contains('group 2').click()
            // cy.get("button#create-cycle").click()
          })
      ...
      

      我推荐你stubeach specific request ,列出来自您的应用程序的所有请求/响应,然后使用它来测试您的后端。这使事情变得更快、更容易。

      Pact 使用这个strategy,但你不一定需要使用 Pact,只需保持你的测试数据同步以测试后端和前端,否则即使你的 CI 通过,事情也会在生产中失败,一个 monorepo 可以帮助解决这个问题。

      【讨论】:

      • 所以我确实需要在每次登录后执行登录,对吗?请提出后续问题:一个测试,无论多长时间,都应该在一个单独的“它”函数中还是分解为不同“它”中的逻辑块?
      • 它应该在单个 it 中,但不必太长,如果您将测试的“GIVEN”状态与夹具文件中的“THEN”断言分开,则您的测试应该足够小。
      • 一个重要的概念是您的应用程序应该是可测试的。不管你使用任何测试工具有多好,如果你的软件不是为测试而设计的,你就会失败。使用 cypress 很重要,能够在您执行操作和断言之前设置您的应用程序状态。
      【解决方案3】:

      在我的例子中,我必须将 testIsolation 属性设置为 false。在那之后 cy.session 开始工作并且没有以空白页结束:

      describe('my tests',{ testIsolation: false }, () => {...});
      

      【讨论】:

        猜你喜欢
        • 2021-10-14
        • 2022-06-10
        • 2020-12-23
        • 1970-01-01
        • 2022-07-22
        • 1970-01-01
        • 2022-10-01
        • 2021-08-07
        • 1970-01-01
        相关资源
        最近更新 更多