求助:Serenity-JS+Cucumber Screenplay步骤间传递数据失败
Serenity-JS + Cucumber Screenplay模式下步骤间传递数据的解决方案
1. 先确保Actor实例完全一致
这是数据丢失最常见的原因:如果每个步骤都创建新的Actor,之前存储的笔记、响应自然会丢失。
- 在Cucumber的
BeforeHook里初始化一次Actor,后续所有步骤都复用这个实例:Before(() => { actorCalled('Bruno').whoCan( BrowseTheWeb.using(protractor.browser), CallAnApi.at('https://your-api-url.com'), TakeNotes.usingAnEmptyNotebook() // 若用TakeNotes需初始化 ); }); - 后续步骤里一律用
actorCalled('Bruno')获取同一个实例,不要手动new Actor(...)。
2. 正确使用TakeNotes存储/读取数据
如果之前用TakeNotes丢数据,大概率是顺序或key的问题,按下面的标准写法来:
存储数据(When步骤)
// 自定义Interaction:调用接口并存储响应 class FetchUserProfile implements Interaction { performAs(actor: Actor): Promise<void> { return actor.attemptsTo( Send.a(GetRequest.to('/api/user/123')), // 必须在请求完成后,用TakeNotes存储LastResponse TakeNotes.of(LastResponse.body()).as('user_profile') ); } static fromApi(): FetchUserProfile { return new FetchUserProfile(); } } // When步骤绑定 When('用户获取个人资料', () => actorCalled('Bruno').attemptsTo(FetchUserProfile.fromApi()) );
读取数据(Then步骤)
// 自定义Interaction:校验响应 class VerifyUserProfile implements Interaction { performAs(actor: Actor): Promise<void> { return actor.attemptsTo( // 用Notes.of(key)读取之前存储的数据 Ensure.that(Notes.of('user_profile'), has({ id: 123, name: 'Bruno' })) ); } static isCorrect(): VerifyUserProfile { return new VerifyUserProfile(); } } // Then步骤绑定 Then('个人资料数据正确', () => actorCalled('Bruno').attemptsTo(VerifyUserProfile.isCorrect()) );
3. 更轻量的方式:直接用Actor的remember/recall
不用TakeNotes,直接操作Actor的内置记忆功能,更灵活:
存储数据
class FetchUserProfile implements Interaction { async performAs(actor: Actor): Promise<void> { // 先获取接口响应 const response = await actor.answer(LastResponse.body()); // 存入Actor的记忆 actor.remember('user_profile', response); } }
读取数据
class VerifyUserProfile implements Interaction { performAs(actor: Actor): Promise<void> { // 从Actor记忆中取出数据 const profile = actor.recall('user_profile'); return Ensure.that(profile.name, equals('Bruno')); } }
4. 排查LastResponse丢失的问题
LastResponse是绑定到当前Actor上下文的,必须满足两个条件:
- 发送请求和读取LastResponse的是同一个Actor实例
- 读取动作必须在请求执行完成之后(Serenity-JS的Interaction是按顺序执行的,只要不异步乱序就没问题)
正确示例:
When('用户调用接口', () => actorCalled('Bruno').attemptsTo(Send.a(GetRequest.to('/api/data'))) ); Then('接口返回状态码200', () => actorCalled('Bruno').attemptsTo( Ensure.that(LastResponse.status(), equals(200)) ) );
内容的提问来源于stack exchange,提问作者bruno777
相关产品推荐
相关产品推荐

