You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Protractor+Cucumber E2E测试中Promise内赋值丢失问题排查

问题分析与解决方案

你遇到的核心问题是异步操作的等待逻辑没处理好,Cucumber还没等到getText()的异步操作完成,就直接执行了后续的Then步骤,导致你在Promise回调里设置的loggedUser.username还没生效,Then步骤读到的还是初始值。

问题根源

你的When步骤函数里调用了getText().then(...),但这个步骤函数没有返回对应的Promise。Cucumber的步骤执行是异步感知的——如果步骤里包含异步操作,必须返回这个Promise,Cucumber才会等待异步操作完成后,再执行下一个步骤(也就是你的Then步骤)。现在的情况是,When步骤刚触发getText()就结束了,Then步骤立刻执行,这时候then回调里的赋值逻辑还没运行,loggedUser.username自然还是初始的"dummyname"。

修复后的代码

修改你的When步骤,让它返回Promise,确保Cucumber等待异步操作完成:

var loggedUser = new User("dummyname", "dummyrole");

this.When(/^I click on a user name$/, function(){
  // 返回getText()的Promise链,让Cucumber等待异步操作完成
  return userelem.element(by.className('username')).getText().then(function (txt) {
    loggedUser.username = txt;
  });
});

this.Then(/^The username of the object "loggedUser" is set to a new value$/, function(){
  var answer = "dummyname" != loggedUser.username;
  assert.isOk(answer, "username is still dummyname!");
});

额外优化建议

如果你的运行环境支持ES6语法,用async/await可以让代码更简洁易读,同时自动处理Promise等待:

var loggedUser = new User("dummyname", "dummyrole");

this.When(/^I click on a user name$/, async function(){
  const txt = await userelem.element(by.className('username')).getText();
  loggedUser.username = txt;
});

this.Then(/^The username of the object "loggedUser" is set to a new value$/, function(){
  assert.notEqual(loggedUser.username, "dummyname", "username is still dummyname!");
});

这里用async/await替代了Promise的then回调,逻辑更线性;async函数会自动返回Promise,Cucumber同样会等待它完成。另外把断言改成assert.notEqual,语义更直观。


内容的提问来源于stack exchange,提问作者saab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:16:56