Cypress V10 BDD测试报错:无法读取undefined的'mobileHandset'属性
解决Cypress Cucumber BDD模式下
this.data未定义的问题 问题描述
将Cypress Mocha框架转换为BDD模式后,测试运行报错:TypeError: Cannot read properties of undefined (reading 'mobileHandset')。已将BeforeEach文件移至Support目录,问题仍未解决。
相关代码
Feature文件
Feature: End to End Shopping Purchase Validation Registered user will be able to purchase an item and have it shipped to their country Scenario: Customer Purchase and delivery Given I am on the eCommerce page When I add items to cart And I confirm shopping cart total Then I select my delivery country and see a thank for your order notification
步骤定义
import { Given, And, Then, When } from "@badeball/cypress-cucumber-preprocessor"; import Homepage from '../../../support/pageObjects/Homepage' import orderSummaryPage from '../../../support/pageObjects/orderSummaryPage' import completeOrderPage from '../../../support/pageObjects/completeOrderPage' const data = require ('../../../fixtures/example.json'); const homepage = new Homepage() const StartCheckout = new orderSummaryPage() const CompleteOrder = new completeOrderPage() Given(/^I am on the eCommerce page$/, () => { cy.visit(``+"/angularpractice/") }); When(/^I add items to cart$/, function() { homepage.getShopTab().click({force:true}) this.data.mobileHandset.forEach(function(element) { cy.AddToCart(element) }); StartCheckout.getBasketCheckoutButton().click() }); When(/^I confirm shopping cart total$/, () => { let sum=0 CompleteOrder.getProductCost().each(($e1, index, $list) =>{ const unitCost=$e1.text() let res= unitCost.split(" ") res= res[1].trim() sum=Number(sum)+Number(res) }).then(function() { cy.log(sum) }) }); Then(/^I select my delivery country and see a thank for your order notification$/, () => { StartCheckout.getStartCheckoutButton().click() CompleteOrder.getShippingCountry().type('United Kingdom') CompleteOrder.getShippingCountryConfirm().click() CompleteOrder.getTermsConditionsCheckbox().click({force: true}) CompleteOrder.getPurchaseButton().click() CompleteOrder.getPurchaseAlert().then(function(element){ const actualText= element.text() expect(actualText.includes('Success')).to.be.true }) });
测试数据(example.json)
{ "name": "MY_NAME", "gender": "Female", "mobileHandset": ["Blackberry", "Nokia Edge"] }
BeforeEach代码(Support目录下)
beforeEach(function() { cy.fixture('example').then(function(data){ this.data=data }) })
问题原因
@badeball/cypress-cucumber-preprocessor 默认不将步骤定义中的this绑定到Cypress的运行上下文,导致this.data无法访问到BeforeEach中挂载的fixture数据。
解决方案
方案1:使用Cypress全局环境存储数据
修改BeforeEach代码,将数据存入Cypress全局环境:
beforeEach(function() { cy.fixture('example').then(function(data) { Cypress.env('testData', data); }); });
修改步骤定义中的调用逻辑:
When(/^I add items to cart$/, function() { homepage.getShopTab().click({force:true}); const testData = Cypress.env('testData'); testData.mobileHandset.forEach(function(element) { cy.AddToCart(element); }); StartCheckout.getBasketCheckoutButton().click(); });
方案2:开启预处理器的bindToRunInstance配置
在cypress.config.js中添加配置,让步骤定义的this指向Cypress运行实例:
const { defineConfig } = require("cypress"); const createBundler = require("@bahmutov/cypress-esbuild-preprocessor"); const addCucumberPreprocessorPlugin = require("@badeball/cypress-cucumber-preprocessor").addCucumberPreprocessorPlugin; const createEsbuildPlugin = require("@badeball/cypress-cucumber-preprocessor/esbuild").createEsbuildPlugin; module.exports = defineConfig({ e2e: { async setupNodeEvents(on, config) { const bundler = createBundler({ plugins: [createEsbuildPlugin(config)], }); on("file:preprocessor", bundler); await addCucumberPreprocessorPlugin(on, config); return config; }, specPattern: "cypress/e2e/**/*.feature", experimentalSessionAndOrigin: true, env: { "cypress-cucumber-preprocessor": { bindToRunInstance: true } } }, });
确保步骤定义中使用普通函数(而非箭头函数),即可正常访问this.data。
方案3:直接使用导入的fixture数据
利用已导入的data变量替代this.data,快速解决问题:
When(/^I add items to cart$/, function() { homepage.getShopTab().click({force:true}); data.mobileHandset.forEach(function(element) { cy.AddToCart(element); }); StartCheckout.getBasketCheckoutButton().click(); });
此方案适合快速验证,但动态切换fixture时灵活性不足。
内容的提问来源于stack exchange,提问作者fypnlp
相关产品推荐
相关产品推荐

