我正在使用Specflow和页面对象,我有很多非常相似的场景。例如:
Given I view the 'page1'
When I click 'link1'
Then I should be on 'page2'
Given I view the 'page1'
When I click 'link2'
Then I should be on 'page3'
我很难看到如何为“当我点击...”步骤进行一步绑定。如果我按照页面对象模式,我应该总是返回我在“那我应该......”步骤中导航到的特定页面对象。
我有一个基本步骤定义类,它包含一个存储当前页面对象的属性。
public class BaseStep : Steps
{
protected RemoteWebDriver Driver {
get
{
return ScenarioContext.Current.Get<RemoteWebDriver>();
}
set
{
ScenarioContext.Current.Set(value);
}
}
protected BasePageObject CurrentPageObject
{
get
{
return ScenarioContext.Current.Get<BasePageObject>();
}
set
{
ScenarioContext.Current.Set(value);
}
}
}
我不想为每个场景编写一个步骤定义,因为它重用了很多我宁愿在单个方法中的代码。那么如何重用步骤定义并仍使用页面对象模式?
感谢。
答案 0 :(得分:1)
你可以通过在你的基页对象上公开一个属性来实现这个目的,它允许迭代当前页面上的所有控件(可能通过反射,但只要它有效,你如何实现它是无关紧要的。)
完成此操作后,您可以通过调用此属性来查找步骤('link1'或'link2')中指定名称的链接,然后单击此链接来实现该步骤。
虽然这会起作用,但我建议您尽量避免使您的方案特定于实现。而不是“当我点击'link1'”时,最好有一些更具描述意图的东西,然后是“当我转到篮子里”或“当我导航到我的帐户详细信息时”。这不是那么可重复使用,但它也不能重构您的设计,并允许您在“点击”链接没有意义的情况下(如触摸设备)重复使用不同设备的步骤
答案 1 :(得分:0)
我对其他人的观点和做法也很感兴趣,但这是我的想法。
如果你选择通用的“当我点击'([^'] *)'”绑定时,你在通用中没有太多信息当前场景是什么。您仍然可以尝试“等待”下一页加载,您可以检查(IWebDriver)Url以确定您的位置(根据浏览器)。您需要在Url和页面对象之间建立映射,才能正确选择当前页面对象。您可以为此目的手动构建映射,您可以使用某些约定,或者您可以使用其他现有的“映射信息”,如ASP.NET路由或站点地图,或者很可能是这些的混合。 ;)
另一种可能性是将当前url的评估推迟到Then,但在这种情况下,可能CurrentPageObject属性getter应该封装它。我的意思是,财产的价值不应该取决于你是否“召唤”某某是否。
我在上一个项目中尝试了一种稍微不同的方法。我为我的场景编写了更具体的When语句,因此不是“当我点击'搜索'”,“当我点击'订单'”或“当我点击'确认'时”我有“当我用参数触发搜索时”填写“,”当我订购所选项目时,“或当我确认订单时”。由于这些语句描述了一个具体的操作,我将它们委托给当前的页面对象(转换为有问题的具体页面),其中页面对象具有这些操作的具体方法。该实现不仅“单击”了相应的按钮(基本功能),而且还等待页面加载并适当地设置当前页面对象。在这种具体情况下,显而易见的是“下一个”当前页面对象是什么,或者我可以或多或少地轻易地检查发生了什么,如果有更多可能的结果。我支付的价格是它不仅仅是一个通用的当点击的步骤定义时,好处(除了上面解释的那个)是场景的措辞更侧重于用户意图而不是具体的UI控制级别交互(执行操作与点击某些内容)