在 Cypress 测试中创建和重用对象数据

在 Cypress 测试中创建和重用对象数据

在 cypress 测试中,直接在异步回调函数外部访问变量常导致 ‘未定义’ 错误。本文将详细讲解如何利用 cypress 的别名(alias)机制,从服务器响应中捕获并封装复杂数据对象。通过 `cy.wrap().as()` 创建别名,再使用 `cy.get().then()` 安全地在后续测试步骤中重用这些数据,从而有效管理测试状态,提升测试代码的健壮性和可维护性。

在 Cypress 端到端测试中,经常需要从前一个步骤(例如 API 响应)中提取数据,并在后续步骤中重用。然而,由于 Cypress 命令的异步性质和其独特的命令队列机制,直接在 cy.then() 回调函数内部定义变量并尝试在外部访问,通常会导致 ReferenceError: [变量名] is not defined 的错误。这正是许多初学者在尝试将响应数据保存为普通 JavaScript 对象并在测试中后续步骤重用时遇到的常见挑战。

理解问题:为什么直接定义变量会失败?

考虑以下场景,我们希望从服务器响应中解析出一个商品对象 Item,并在后续的 cy.addItemToShoppingCart 命令中使用它:

cy.wait('@pageLoaded').then(({ response }) => {    expect(response.statusCode).to.equal(200);    let i = randomItem();    // 在回调函数内部创建对象    const Item = {        Id: response.body.items[i].id,        IpuCode: response.body.items[i].ipuCode,        Description: response.body.items[i].description,        PackSize: response.body.items[i].packSize,        PackType: response.body.items[i].packType,    };    cy.log(Item); // 在这里可以正常访问 Item});// 尝试在这里重用 Item// cy.addItemToShoppingCart(Item.IpuCode, pharmacyId, Item.Id, currentDateTime);// 结果:ReferenceError: Item is not defined

Item 变量是在 cy.then() 的回调函数作用域内定义的。当 Cypress 执行到 cy.addItemToShoppingCart 这行代码时,外部作用域并不知道 Item 变量的存在,因为 cy.then() 的回调函数可能尚未执行,或者即使执行了,其内部变量也不会自动暴露到外部命令队列中。Cypress 的命令是排队执行的,而不是像普通 JavaScript 那样立即执行。

解决方案:使用 Cypress 别名(Aliases)管理对象数据

Cypress 提供了一种强大且优雅的机制来解决这个问题,即使用别名(Aliases)。别名允许我们将数据、DOM 元素或路由请求保存起来,并在测试的任何后续步骤中通过其别名进行引用。对于复杂的数据对象,我们可以使用 cy.wrap() 命令将其包装成一个可别名的 Cypress Subject。

1. 捕获数据并创建别名

首先,在获取到服务器响应并构建出所需的对象后,使用 cy.wrap() 将该对象包装起来,并通过 .as() 命令为其指定一个别名。

cy.wait('@pageLoaded').then(({ response }) => {    expect(response.statusCode).to.equal(200);    let i = randomItem();    // 从响应中提取数据并构建对象    const itemData = {        id: response.body.items[i].id,        ipuCode: response.body.items[i].ipuCode,        description: response.body.items[i].description,        packSize: response.body.items[i].packSize,        packType: response.body.items[i].packType,    };    // 使用 cy.wrap() 包装对象并创建别名    cy.wrap(itemData).as('itemDetails'); // 建议使用驼峰命名法    cy.log('Aliased Item Details:', itemData);});

在上述代码中,我们将从响应中解析出的商品信息封装成 itemData 对象,然后使用 cy.wrap(itemData).as(‘itemDetails’) 将其保存为名为 ‘itemDetails’ 的别名。

2. 在后续测试中重用别名对象

要访问已保存的别名对象,需要使用 cy.get(‘@aliasName’) 命令。这个命令会从 Cypress 的内部存储中检索别名所指向的值,并将其作为下一个命令的主题(subject)传递。通常,我们会紧接着使用 .then() 回调函数来处理这个别名对象。

// 在测试的后续步骤中cy.get('@itemDetails').then(item => {    // 此时,item 变量就是我们之前保存的 itemDetails 对象    cy.log('Reusing Aliased Item:', item);    // 现在可以安全地访问 item 对象的属性    cy.addItemToShoppingCart(item.ipuCode, pharmacyId, item.id, currentDateTime);    // ... 其他使用 item 属性的 Cypress 命令});

通过这种方式,cy.get(‘@itemDetails’) 将等待 itemDetails 别名可用(即 cy.wrap().as(‘itemDetails’) 命令执行完毕),然后将其值传递给 .then() 回调函数。这样就确保了数据的正确传递和可用性,避免了作用域问题。

完整示例代码

// Cypress 测试文件describe('商品购物车功能测试', () => {    let pharmacyId = 'somePharmacyId'; // 示例变量    let currentDateTime = new Date().toISOString(); // 示例变量    function randomItem() {        // 模拟随机选择一个商品索引        return Math.floor(Math.random() * 5); // 假设有5个商品    }    it('应该能够从响应中获取商品并添加到购物车', () => {        // 1. 访问页面并等待 API 响应        cy.visit('/some-page'); // 假设页面会触发一个名为 '@pageLoaded' 的 API 请求        cy.intercept('GET', '/api/items*', { fixture: 'items.json' }).as('pageLoaded'); // 模拟 API 响应        cy.wait('@pageLoaded').then(({ response }) => {            expect(response.statusCode).to.equal(200);            let i = randomItem();            // 2. 从响应中解析数据并创建对象            const itemData = {                id: response.body.items[i].id,                ipuCode: response.body.items[i].ipuCode,                description: response.body.items[i].description,                packSize: response.body.items[i].packSize,                packType: response.body.items[i].packType,            };            // 3. 将对象保存为 Cypress 别名            cy.wrap(itemData).as('itemDetails');            cy.log('已将商品详情保存为别名:', itemData);        });        // 4. 在后续测试步骤中重用别名对象        cy.get('@itemDetails').then(item => {            cy.log('从别名中获取商品:', item);            // 假设 cy.addItemToShoppingCart 是一个自定义 Cypress 命令            cy.addItemToShoppingCart(item.ipuCode, pharmacyId, item.id, currentDateTime);            // 进一步的断言或操作            cy.get('.shopping-cart-item').should('contain', item.description);            cy.get('.shopping-cart-item').should('contain', item.packSize);        });    });});// 假设在 cypress/support/commands.js 中定义了自定义命令// Cypress.Commands.add('addItemToShoppingCart', (ipuCode, pharmacyId, itemId, dateTime) => {//     cy.request('POST', '/api/add-to-cart', {//         ipuCode,//         pharmacyId,//         itemId,//         dateTime//     }).then(response => {//         expect(response.status).to.equal(200);//         cy.log('商品已添加到购物车');//     });// });

注意事项与最佳实践

命名约定: 在 JavaScript 中,通常推荐使用驼峰命名法(camelCase)来命名变量和对象属性(例如 ipuCode 而不是 IpuCode)。这有助于保持代码风格的一致性。别名范围: Cypress 别名在当前 it 块中是可用的。如果需要在多个 it 块之间共享数据,可以使用 beforeEach 或 before 钩子来定义别名,或者将数据存储到 Cypress.env() 中(但对于测试内部数据,别名通常更合适)。单值别名: 即使是单个值,也可以使用 cy.wrap(value).as(‘aliasName’) 来创建别名,然后通过 cy.get(‘@aliasName’).then(value => { /* use value */ }) 来访问。清晰的测试流程: 使用别名有助于将数据获取和数据使用逻辑分离,使测试代码更具可读性和可维护性。

总结

通过 Cypress 的别名机制,我们可以有效地管理测试中的异步数据流,避免因 JavaScript 作用域和 Cypress 命令队列特性引起的问题。将从响应中获取的复杂数据对象通过 cy.wrap().as() 保存为别名,并在后续步骤中通过 cy.get(‘@aliasName’).then() 安全地重用,是编写健壮、可维护的 Cypress 测试的关键实践之一。这种方法不仅解决了数据访问问题,也提升了测试代码的结构性和可读性。

以上就是在 Cypress 测试中创建和重用对象数据的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1535192.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
如何从HTML Canvas输出24位深度TIFF图像
上一篇 2025年12月21日 02:13:21
手写一个符合Promises/A+规范的Promise_javascript进阶
下一篇 2025年12月21日 02:13:36

相关推荐

  • C# .NET中基于JWT和外部授权服务器的REST API安全配置指南

    C# .NET中基于JWT和外部授权服务器的REST API安全配置指南C# .NET中基于JWT和外部授权服务器的REST API安全配置指南C# .NET中基于JWT和外部授权服务器的REST API安全配置指南C# .NET中基于JWT和外部授权服务器的REST API安全配置指南

    本文旨在提供一个简洁明了的教程,指导开发者如何在C# .NET应用中,以纯资源服务器模式,通过外部授权服务器(如AWS Cognito或Asgardeo)实现REST API的安全保护。文章将重点介绍如何利用JWT Bearer认证机制,通过最小化配置,快速构建一个能够验证传入访问令牌的API服务,…

    2026年9月27日 • 用户投稿
    000
  • Codename One:实现安全的数字密码输入框

    Codename One:实现安全的数字密码输入框Codename One:实现安全的数字密码输入框Codename One:实现安全的数字密码输入框Codename One:实现安全的数字密码输入框

    本文详细介绍了在Codename One中创建既能接受纯数字输入又能进行密码遮罩的文本输入框的方法。通过使用位或运算符(|)组合TextArea.NUMERIC和TextArea.PASSWORD约束,可以有效地实现这一需求,避免了链式调用constraint()的常见误区,从而提升用户体验和输入安…

    2026年9月27日 • 用户投稿
    000
  • 苹果 A19 芯片内部特写:架构微调带来能效提升

    苹果 A19 芯片内部特写:架构微调带来能效提升苹果 A19 芯片内部特写:架构微调带来能效提升苹果 A19 芯片内部特写:架构微调带来能效提升苹果 A19 芯片内部特写:架构微调带来能效提升

    苹果最新一代的a19芯片在芯片制造工艺方面较a18有显著提升,近期一组显微照片首次揭示了iphone 17系列最新芯片的内部细节。 本次随iPhone 17发布亮相的A19及A19 Pro芯片,是苹果自研芯片设计的又一进步。尽管苹果方面针对性能提升作出多项官方承诺,但由ChipWise团队拍摄的So…

    2026年9月27日 • 用户投稿
    000
  • 豆包AI如何实现智能排版 豆包AI文档自动格式化功能

    豆包AI提供的智能排版功能,能够显著提升文档处理效率。本文将详细介绍如何利用豆包AI的文档自动格式化能力,解决文档排版耗时的问题。我们将逐步解析使用该功能的过程,包括如何启用、输入内容以及完成格式化,以便用户能够轻松掌握并应用。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 …

    2026年9月27日
    000
  • sublime如何只在当前文件中替换_sublime当前文件内替换方法

    sublime如何只在当前文件中替换_sublime当前文件内替换方法sublime如何只在当前文件中替换_sublime当前文件内替换方法sublime如何只在当前文件中替换_sublime当前文件内替换方法sublime如何只在当前文件中替换_sublime当前文件内替换方法

    使用Ctrl+H打开替换面板,确保在当前文件中查找和替换,输入内容后选择替换选项,避免使用多文件搜索功能即可安全完成单文件替换。 在 Sublime Text 中,如果你只想在当前文件中进行替换操作,而不是在整个项目或多个文件中替换,可以使用“**在文件内查找和替换**”功能。以下是具体操作方法: …

    2026年9月27日 • 用户投稿
    000
  • Java Swing GUI:构建交互式逻辑门(AND门示例)

    Java Swing GUI:构建交互式逻辑门(AND门示例)Java Swing GUI:构建交互式逻辑门(AND门示例)Java Swing GUI:构建交互式逻辑门(AND门示例)Java Swing GUI:构建交互式逻辑门(AND门示例)

    本文详细介绍了如何使用Java Swing构建一个简单的AND逻辑门GUI应用。通过结合JCheckBox作为输入和JLabel作为视觉输出,并利用ChangeListener监听组件状态变化,实现当两个复选框都被选中时显示“绿色”,否则显示“红色”的功能。教程涵盖了组件创建、事件监听以及将自定义面…

    2026年9月27日 • 用户投稿
    100
  • MAC妙控鼠标怎么设置右键_Mac妙控鼠标辅助点按(右键)设置方法

    MAC妙控鼠标怎么设置右键_Mac妙控鼠标辅助点按(右键)设置方法MAC妙控鼠标怎么设置右键_Mac妙控鼠标辅助点按(右键)设置方法MAC妙控鼠标怎么设置右键_Mac妙控鼠标辅助点按(右键)设置方法MAC妙控鼠标怎么设置右键_Mac妙控鼠标辅助点按(右键)设置方法

    首先检查并开启辅助点按功能,进入系统设置→鼠标,打开辅助点按并选择右侧区域触发右键;随后校准点击位置与力度,确保点击设定区域且力度适中;最后确认蓝牙连接正常且鼠标电量充足,以排除连接与硬件问题。 如果您在使用Mac妙控鼠标时发现无法执行右键操作,可能是由于辅助点按功能未正确配置。妙控鼠标通过触控表面…

    2026年9月27日 • 用户投稿
    000
  • AI Overviews如何设置智能告警 AI Overviews异常检测阈值

    AI Overviews如何设置智能告警 AI Overviews异常检测阈值AI Overviews如何设置智能告警 AI Overviews异常检测阈值AI Overviews如何设置智能告警 AI Overviews异常检测阈值AI Overviews如何设置智能告警 AI Overviews异常检测阈值

    本文将详细指导您如何在AI Overviews中设置智能告警以及调整异常检测阈值,帮助您及时发现并响应潜在问题。我们将分步骤讲解具体操作过程,确保您能够顺利配置这些关键功能,从而实现更主动、更精准的系统监控。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索, 免费无限量使用 DeepSeek R…

    2026年9月27日 • 用户投稿
    000
  • 曝华为Mate80系列新增Air机型 支持eSIM 采用微泵液

    曝华为Mate80系列新增Air机型 支持eSIM 采用微泵液曝华为Mate80系列新增Air机型 支持eSIM 采用微泵液曝华为Mate80系列新增Air机型 支持eSIM 采用微泵液曝华为Mate80系列新增Air机型 支持eSIM 采用微泵液

    9月24日,cnmo获悉,有数码博主透露了华为mate80 pro+的部分配置详情。据消息显示,该机型顶配版将配备6000mah大容量电池,搭配24gb运行内存与2tb机身存储。此外,华为mate80系列将新增一款air版本,采用创新的微泵液冷技术(无风扇设计),并支持esim功能。 华为Mate …

    2026年9月27日 • 用户投稿
    100
  • 360极速浏览器收藏夹栏怎么显示_360极速浏览器显示或隐藏书签栏的方法

    360极速浏览器收藏夹栏怎么显示_360极速浏览器显示或隐藏书签栏的方法360极速浏览器收藏夹栏怎么显示_360极速浏览器显示或隐藏书签栏的方法360极速浏览器收藏夹栏怎么显示_360极速浏览器显示或隐藏书签栏的方法360极速浏览器收藏夹栏怎么显示_360极速浏览器显示或隐藏书签栏的方法

    360极速浏览器书签栏未显示时,可通过快捷键Ctrl+Shift+B切换,或在菜单“工具”中点击“显示书签栏”,也可在“设置-外观”中开启默认显示。 如果您希望在浏览网页时快速访问常用网站,但发现360极速浏览器的收藏夹栏未显示,可能是书签栏被隐藏了。以下是恢复显示书签栏的操作方法。 本文运行环境:…

    2026年9月27日 • 用户投稿
    100
  • sublime怎么设置字体大小_sublime字体大小调整教程

    sublime怎么设置字体大小_sublime字体大小调整教程sublime怎么设置字体大小_sublime字体大小调整教程sublime怎么设置字体大小_sublime字体大小调整教程sublime怎么设置字体大小_sublime字体大小调整教程

    答案:通过快捷键或菜单可临时调整Sublime Text字体大小,使用Ctrl/Cmd+滚轮或View→Font Size;通过Preferences→Settings修改”font_size”和”font_face”可永久设置字体大小和类型。 打开S…

    2026年9月27日 • 用户投稿
    000
  • MAC怎么完全重置恢复到出厂设置_macOS恢复出厂设置与抹掉所有内容指南

    MAC怎么完全重置恢复到出厂设置_macOS恢复出厂设置与抹掉所有内容指南MAC怎么完全重置恢复到出厂设置_macOS恢复出厂设置与抹掉所有内容指南MAC怎么完全重置恢复到出厂设置_macOS恢复出厂设置与抹掉所有内容指南MAC怎么完全重置恢复到出厂设置_macOS恢复出厂设置与抹掉所有内容指南

    推荐使用“抹掉所有内容和设置”功能,进入系统设置-通用-传输或还原,点击抹掉按钮并输入密码,Mac将自动清除数据并重装系统;02. 若无法正常启动,可尝试通过恢复模式手动操作,关机后长按电源键进入启动选项,选择“选项”进入恢复模式,使用磁盘工具抹掉硬盘(格式选APFS),再重新安装macOS;03.…

    2026年9月27日 • 用户投稿
    000
  • Java Swing 实现带复选框和图像的逻辑门

    Java Swing 实现带复选框和图像的逻辑门Java Swing 实现带复选框和图像的逻辑门Java Swing 实现带复选框和图像的逻辑门Java Swing 实现带复选框和图像的逻辑门

    本文介绍了如何使用 Java Swing 创建一个简单的 AND 逻辑门 GUI,该 GUI 包含两个复选框和一个图像。当两个复选框都被选中时,图像变为绿色;否则,图像变为红色。我们将使用 JCheckBox、JLabel 和 ChangeListener 来实现这一功能,并提供完整的代码示例。 创…

    2026年9月27日 • 用户投稿
    000
  • Perplexity AI如何实现考古鉴定 Perplexity AI文物真伪辨别

    Perplexity AI如何实现考古鉴定 Perplexity AI文物真伪辨别Perplexity AI如何实现考古鉴定 Perplexity AI文物真伪辨别Perplexity AI如何实现考古鉴定 Perplexity AI文物真伪辨别Perplexity AI如何实现考古鉴定 Perplexity AI文物真伪辨别

    本文将探讨 Perplexity AI 在考古鉴定和文物真伪辨别中扮演的角色。我们将详细讲解如何利用这一工具辅助考古研究人员和鉴定专家进行初步的信息检索和分析,为文物的真伪判断提供参考依据。文章会分步骤指导用户如何操作,以便更好地理解和应用 Perplexity AI 的功能。 ☞☞☞AI 智能聊天…

    2026年9月27日 • 用户投稿
    000
  • windows怎么用命令提示符_Windows命令提示符(CMD)常用命令大全

    windows怎么用命令提示符_Windows命令提示符(CMD)常用命令大全windows怎么用命令提示符_Windows命令提示符(CMD)常用命令大全windows怎么用命令提示符_Windows命令提示符(CMD)常用命令大全windows怎么用命令提示符_Windows命令提示符(CMD)常用命令大全

    通过CMD可高效执行IP查询、网络测试、DNS清理、目录管理、文件操作、系统信息查看及关机控制等任务,提升Windows系统操作效率。 如果您需要在Windows系统中执行各种文件管理、系统诊断或网络配置任务,使用命令提示符(CMD)可以高效地完成这些操作。通过输入特定命令,您可以直接与操作系统交互…

    2026年9月27日 • 用户投稿
    000
  • 解决Spring REST API 406 Not Acceptable错误

    解决Spring REST API 406 Not Acceptable错误解决Spring REST API 406 Not Acceptable错误解决Spring REST API 406 Not Acceptable错误解决Spring REST API 406 Not Acceptable错误

    本文旨在帮助开发者解决在使用Spring REST API时遇到的“406 Not Acceptable”错误。该错误通常表示服务器无法找到客户端可接受的表示形式。我们将详细介绍错误的原因、解决方案,并通过示例代码演示如何配置produces属性来指定API的响应类型,确保客户端能够正确接收和处理数…

    2026年9月27日 • 用户投稿
    000
  • 多模态AI如何处理雷达信号 多模态AI目标跟踪技术

    多模态AI如何处理雷达信号 多模态AI目标跟踪技术多模态AI如何处理雷达信号 多模态AI目标跟踪技术多模态AI如何处理雷达信号 多模态AI目标跟踪技术多模态AI如何处理雷达信号 多模态AI目标跟踪技术

    本文将详细阐述多模态AI如何有效处理雷达信号,并将其应用于目标跟踪技术。我们将从雷达信号的基础处理入手,逐步讲解如何将雷达数据融入多模态AI框架,并通过分步骤的方式解析AI进行目标跟踪的具体过程。这将帮助读者理解多模态AI在复杂环境中利用雷达数据的强大能力。 ☞☞☞AI 智能聊天, 问答助手, AI…

    2026年9月27日 • 用户投稿
    000
  • 跨平台无纸化会议安装指南

    跨平台无纸化会议安装指南跨平台无纸化会议安装指南跨平台无纸化会议安装指南跨平台无纸化会议安装指南

    无纸化会议的投屏功能通常依赖于windows或安卓系统,但本文提供一种兼容多种操作系统的部署方案,实现跨平台应用。无论使用windows、安卓、ios还是mac设备,均可顺利安装并运行无纸化会议系统,显著提升会议的便捷性与协作效率。 1、 首先将无纸化会议服务器部署至机柜中,接通网络与电源,后续无需…

    2026年9月27日 • 用户投稿
    400
  • Java:子类如何在不修改父类的情况下,通过重写方法间接利用父类私有成员

    Java:子类如何在不修改父类的情况下,通过重写方法间接利用父类私有成员Java:子类如何在不修改父类的情况下,通过重写方法间接利用父类私有成员Java:子类如何在不修改父类的情况下,通过重写方法间接利用父类私有成员Java:子类如何在不修改父类的情况下,通过重写方法间接利用父类私有成员

    在Java中,当子类需要在不修改父类的前提下,利用父类的私有成员时,直接访问是不允许的。本教程将展示如何通过调用父类的公共或保护方法(例如super.toString()),来间接利用父类内部已处理过的私有数据,尤其适用于重写方法并在此基础上扩展功能的情景。 Java封装性与私有成员:理解限制 ja…

    2026年9月27日 • 用户投稿
    000
  • win8系统盘符图标怎么恢复默认_Win8系统盘图标恢复方法

    win8系统盘符图标怎么恢复默认_Win8系统盘图标恢复方法win8系统盘符图标怎么恢复默认_Win8系统盘图标恢复方法win8系统盘符图标怎么恢复默认_Win8系统盘图标恢复方法win8系统盘符图标怎么恢复默认_Win8系统盘图标恢复方法

    首先通过文件夹属性还原默认图标,若无效则清除图标缓存并重启资源管理器,接着删除磁盘根目录下的autorun.inf隐藏文件,最后使用注册表编辑器删除DriveIcons路径下对应盘符的注册表项以彻底恢复默认图标显示。 如果您发现Windows 8系统中的硬盘盘符图标显示异常,可能是由于自定义设置、图…

    2026年9月27日 • 用户投稿
    000

发表回复

登录后才能评论
关注微信