赛普拉斯测试之间通过状态的最佳实践是什么

What is the best practice of pass states between tests in Cypress

我想 pass/share 每次测试之间的数据。在 Cypress 中实现它的最佳方法是什么?

例如:

 it('test 1'), () => {
   cy.wrap('one').as('a')
   const state1 = 'stat1'
 })

 it('test 2'), () => {
   cy.wrap('two').as('b')
 })

 it('test 2'), () => {
   //I want to access this.a and this.b

   //Also I want to access state1

 })

在 Javascript 个变量的情况下,你可以这样做:

let state;

describe('test 1', () => {
    it('changes state', () => {
        state = "hi";
     });
});

describe('test 2', () => {
    it('reports state', () => {
        cy.log(state); // logs "hi" to the Cypress log panel
     });
});

.as() 似乎无法在 describe 块之间携带状态。

假设您正在尝试传递文本

it('test 1'), () => {
  cy.wrap('one').as('a')
}

it('test 2'), () => {
  cy.wrap({ valueName: 'two' }).as('b')
}

it('test 2'), () => {
  //I want to access this.a and this.b
  cy.get('@a').then((thisIsA) => {
    cy.log(thisIsA);
    // logs 'one'
  }

  cy.get('@b').its('valueName').then((thisIsB) => {
    cy.log(thisIsB);
    // logs 'two'
  }

  cy.get('@b').its('valueName').should('eq', 'two')
}

我尝试了其他一些解决方案,但它们对我不起作用。也许最近的版本发生了变化。以下示例应该有效。请注意两个测试都使用了 function() ,这使事情保持在 'this.'.

的上下文中
  it('get the value', function () {
    cy.get('#MyElement').invoke('text').as('mytext1')
  })

  it('use the value', function () {
    cy.log(this.mytext1);
  })

正如 abbr 在评论中指出的那样,如果测试在不同的 url.

上开始,则使用全局变量共享值将不起作用

所以这些不起作用:

  • 全局变量赋值和读取(是否在describe/context块外无关紧要)
  • 依赖Mocha this.state(这个测试完就清零了)
  • 使用 Cypress as

剩下的当然是文件了。 Read and write.


describe("Test", () => {

  it("Can access 3000", function () {
    cy.visit("http://localhost:3000");

    cy.writeFile("shared.json", {count: 2})
  });


  it("Can access 8000", function () {
    cy.visit("http://localhost:8000");

    cy.readFile("shared.json").then(cy.log)
  });

});

您可以像这样在步骤之间共享状态

describe('A suite of steps', () => {

    it('visit a page and save the url', function () {
        cy.visit('/hello-world')
        // Store url
        cy.url().as('pageUrl');
    });

    it('load page url', function () {
        // Load the page from the previous step
        cy.visit(this.pageUrl)
    });
})

我可以看到作者的答案有效,但如果有人需要在不同的测试文件之间共享数据,解决方案是使用 cy task method 并将数据存储在 Node 环境中,例如在我的例子中,我需要存储用户数据:

// cypress/plugins/index.ts
export default (on, config) => {
  on('task', {
    setUserData: (userData: UserDataType) => {
      global.userData = userData;
      return null;
    },
    getUserData: () => {
      return global.userData;
    },
  });
};

然后在测试用例中我们可以这样做:

// cypress/integration/login.spec.ts
describe('Login', () => {
  it('should work', () => {
    cy.visit('/login-page');
    cy.intercept('api/login-endpoint').as('postLogin');
    // login interactions
    cy.wait('@postLogin').then((interception) => {
      // intercept user data and store it in global variable
      cy.task('setUserData', JSON.parse(interception.response.body));
    });
    // ... further assertions
  });
});

稍后我们可以轻松检索此数据:

// cypress/integration/otherTest.spec.ts
describe('Other test', () => {
  it('uses user data', () => {
    cy.task('getUserData').then((userData: UserDataType) => {
      console.log(userData);
      // voila! Stored data between two .spec files
    });
  });
});

您还需要为此扩展 Node TS 类型,但这个答案已经足够长了。

是的,我知道这根本不是编写测试的好方法,因为它使它们相互依赖,但有时应用程序中的长时间交互流程使它成为必要。

在处理这个问题时,我无意中找到了解决方案。不知道为什么会这样。导入任何 json 文件(此解决方案不会更改 json 文件)

someTest.spec.js:

import jsonFile from "../../fixtures/file.json"
describe('Test some feature', () =>{
      it('test feature 1', () => {
        jsonFile.anyWalueYouWant="this is value from feature 1"                          
      })

      it("test feature 2", ()=>{
        cy.log(jsonFile.anyWalueYouWant)
    })

})

PS:anyWalueYouWant 不需要在这个 parameters.json 文件中