如何动态化用户名和密码



当我在黄瓜中输入参与者名称时,我如何使用数据驱动或动态用户名和密码,它应该使用相应的密码,可能来自 JSON 文件或其他取决于参与者的东西。

所以当我在功能文件中输入这个时

//example.feature

Feature: Add item and place the order for that item
In order to wear something new
As an online shopping customer
I want to be able to add an item to my shopping bag and then place the order
Scenario: Add an item to shopping bag to place the order using Paypal
Given that "Bruno" is logged in to his "admin" account
When he searches and adds an item from "men" section to his shopping bag
Then he can place the order

example.steps.ts

import { Actor } from "serenity-js/lib/screenplay";
import { BrowseTheWeb } from "serenity-js/lib/screenplay-protractor";
import { protractor } from "protractor";
import { Start, AddItemsToShoppingBag } from "../website-model/src/index";
import { Authenticate } from '../website-model/src/ability/authenticate';
protractor.browser.ignoreSynchronization = true;
export = function selectItemSteps() {
let actor = Actor.named('Bruno').whoCan(BrowseTheWeb.using(protractor.browser));
this.Given(/^that "([^"]*)" is logged in to his "([^"]*)" account$/, function (name: string, pageUrl: string) {
return actor.attemptsTo(
Start.LaunchUrl(pageUrl, name),
);
});
this.When(/^he searches and adds an item from "([^"]*)" section to his shopping bag$/, function (gender:string) {
return actor.attemptsTo(
AddItemsToShoppingBag.called(gender)
);
});
this.Then(/^he can place the order$/, function () {
return actor.attemptsTo(
// PlaceOrder.hjgkhaksdjh()
);
// expect(james.toSee(thankYouPageElementsMap(lbl_thank_you).Displayed)).eventually.equal('Thank You');
});
}

登录用户.ts

import { Task, step, PerformsTasks } from "serenity-js/lib/screenplay";
import { Click, Enter } from "serenity-js/lib/screenplay-protractor";
import { homePageElementsMap } from "../interactions/html-elements/pages-elements-maps/home-page-elements-maps";
import { loginPageElementsMap } from "../interactions/html-elements/pages-elements-maps/login-page-elements-map";
export class LoginUser implements Task {
static called(name: string): LoginUser {
return new LoginUser(name);
}
@step('{0} Login Page - Login Bruno')
performAs(actor: PerformsTasks): PromiseLike<void> {
return actor.attemptsTo(
Click.on(homePageElementsMap.lnk_login),
Enter.theValue('test@test.com').into(loginPageElementsMap.txt_login_email),
Enter.theValue('password111').into(loginPageElementsMap.txt_login_pwd),
Click.on(loginPageElementsMap.btn_login)
);
}
constructor(private name: string) {
}
}

实现步骤

Given that "Bruno" is logged in to his "admin" account

以随机选择用户。 您可以从文件或任何相当于枚举或集合的打字稿中随机选择它们。

注意:目前您在步骤定义之外分配"Bruno"。我认为这是不好的做法,因为您的测试的实施与您的步骤无关(即事情发生在它们之外),这可能会导致不正确的功能文件/意外行为。例如: 如果将步骤更改为

Given that "Bob" is logged in to his "customer" account

这不会自动工作,因为你仍然硬编码演员是布鲁诺。

您仍然必须在步骤之间共享状态(即场景中的所有步骤都需要知道哪个参与者登录到哪个帐户)

我使用一些奇怪的语法采取以下方法。

与应用程序中的大多数内容相比,用户非常不寻常,因为他们知道应用程序不知道的东西(他们的密码)。因此,要登录,您不能使用夹具或工厂从数据库中获取现有用户。

我在测试代码中所做的是专门为用户创建一个类。我称之为TUser.在我的测试世界中,我只通过他们的名字来识别用户,然后我生成其他所有内容,包括他们的密码。所以如果有一个用户布鲁诺,我的代码将

  • 调用TUser.new(first_name: Bruno)给我我的用户并将其存储在变量中,假设此示例@bruno
  • 使用该用户创建数据库记录,例如create_user(用户:@bruno)
  • 访问登录页面并通过向@bruno询问来填写详细信息,例如'fill_in(:p assword,使用:@bruno.password)

这样做的库克会读成类似

Given there is a user Bruno When Bruno signs in Then Bruno should ...

**以上都是红宝石**

您可以在我的一个示例项目中查看更详细的版本。让 Txxx 类来创建特定实体的测试版本是非常强大的,一旦你克服了它们最初的陌生感。

最新更新