Cypress中Maximum call stack size exceeded错误的解决方法
问题描述
我尝试运行一项Cypress测试,流程为先获取x-auth-token并将其存储到txt文件中,随后在commands.js文件中编写如下getAllNoteIDs命令读取该token:
Cypress.Commands.add("getAllNoteIDs", () => { let notes_ids = []; cy.readFile("cypress/user_data/token.txt").then((token) => { cy.log("Token is "+token) }) // 此处能正确获取token cy.request({ method: "GET", url: "https://practice.expandtesting.com/notes/api/notes", form: true, failOnStatusCode: false, timeout: 30000, headers: { accept: "application/json", "x-auth-token": cy.readFile("cypress/user_data/token.txt").then((token) => { cy.log(token) }), }, }).then((response) => { cy.log(response) const responseBodyKeys = Cypress._.keys(response.body); cy.log(responseBodyKeys) cy.log(response.body['message']) let results = response.body.data; for (let i of results) { notes_ids.push(i.id); } cy.wrap(notes_ids); }); });
运行该命令时,出现了Maximum call stack size exceeded错误,若直接硬编码token则测试正常运行,不想采用硬编码方式,请问该如何解决?
解决方案
出现这个错误的核心原因是你在cy.request的headers配置中直接嵌套了cy.readFile命令。Cypress的命令是异步的,不能直接作为同步值赋值给请求头,这种写法会导致命令链无限循环,最终触发栈溢出。
以下是两种可行的解决方法:
方法1:将请求放在文件读取的回调内
把cy.request包裹在cy.readFile的.then()回调中,确保获取到token后再发起请求:
Cypress.Commands.add("getAllNoteIDs", () => { let notes_ids = []; cy.readFile("cypress/user_data/token.txt").then((token) => { cy.log("Token is " + token); // 在token获取成功后发起请求 cy.request({ method: "GET", url: "https://practice.expandtesting.com/notes/api/notes", form: true, failOnStatusCode: false, timeout: 30000, headers: { accept: "application/json", "x-auth-token": token // 直接使用获取到的token值 }, }).then((response) => { cy.log(response); const responseBodyKeys = Cypress._.keys(response.body); cy.log(responseBodyKeys); cy.log(response.body['message']); let results = response.body.data; for (let i of results) { notes_ids.push(i.id); } cy.wrap(notes_ids); }); }); });
方法2:使用Cypress环境变量存储token(更推荐)
可以在测试初始化阶段读取token并设置为环境变量,后续命令直接调用,避免重复读取文件:
- 在
cypress/support/e2e.js(或对应配置文件)中添加初始化逻辑:
// 测试前读取token并设置为环境变量 before(() => { cy.readFile("cypress/user_data/token.txt").then((token) => { Cypress.env("AUTH_TOKEN", token); }); });
- 修改
getAllNoteIDs命令:
Cypress.Commands.add("getAllNoteIDs", () => { let notes_ids = []; const token = Cypress.env("AUTH_TOKEN"); // 直接从环境变量获取token cy.request({ method: "GET", url: "https://practice.expandtesting.com/notes/api/notes", form: true, failOnStatusCode: false, timeout: 30000, headers: { accept: "application/json", "x-auth-token": token }, }).then((response) => { cy.log(response); const responseBodyKeys = Cypress._.keys(response.body); cy.log(responseBodyKeys); cy.log(response.body['message']); let results = response.body.data; for (let i of results) { notes_ids.push(i.id); } cy.wrap(notes_ids); }); });
内容的提问来源于stack exchange,提问作者qatesterbecomingprogrammer
相关产品推荐
相关产品推荐

