2

我正在将 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);
        }
    }
}

我不想为每个场景编写一个步骤定义,因为它重用了很多我宁愿在一个方法中使用的代码。那么如何重用步骤定义并仍然使用页面对象模式呢?

谢谢。

4

2 回答 2

1

您可以通过在基本页面对象上公开一个属性来做到这一点,该属性允许迭代当前页面上的所有控件(可能通过反射,但只要它有效,您如何实现它就无关紧要)。

一旦你有了这个,你就可以通过调用这个属性来寻找步骤中给出的名称的链接('link1'或'link2')然后单击它来实现该步骤。

虽然这会起作用,但我建议您应该尽量避免使您的场景如此特定于实现。与其说“当我点击‘link1’时”,不如使用更能描述意图的内容,而不是“当我去购物篮时”或“当我导航到我的帐户详细信息时”。这不是那么可重用,但它也抵制重构您的设计,并允许在“单击”链接没有意义时将您的步骤重用于不同的设备(如触摸设备)

于 2015-07-29T13:27:54.760 回答
0

我也会对其他人的意见和做法非常感兴趣,但这是我的想法。

如果您使用通用的“当我单击 '([^']*)'”绑定时,您在通用时没有太多信息当当前场景是关于什么的。您仍然可以尝试“等待”加载下一页,并且可以检查(IWebDriver)Url 以确定您在哪里(根据浏览器)。您需要在 Url 和您的页面对象之间进行映射,以便能够适当地选择当前页面对象。为此,您可以手动建立一个映射,您可以使用一些约定,或者您可以使用其他现有的“映射信息”,如 ASP.NET 路由或站点地图,或者很可能是这些的混合。;)

另一种可能性是将当前 url 的评估推迟到 Then,但在这种情况下,CurrentPageObject 属性 getter 可能应该封装它。我的意思是,属性的​​价值不应该取决于你是否“调用”某个 Then 与否。

我在最近的一个项目中尝试了一种稍微不同的方法。我为我的场景写了更具体的When语句,所以不是“当我点击‘搜索’时”、“当我点击‘订购’时”或“当我点击‘确认’时”我有“当我用参数触发搜索时填写”、“当我订购所选项目时”或“当我确认订单时”。由于这些语句描述了一个具体的动作,我将它们委托给当前页面对象(投射到有问题的具体页面),其中页面对象具有这些动作的具体方法。该实现不仅“单击”了适当的按钮(基本功能),而且还等待页面加载并适当地设置当前页面对象。在这种具体情况下,“下一个”当前页面对象是什么很明显,或者如果有更多可能的结果,我可以或多或少地轻松检查发生了什么。我付出的代价是它不仅仅是一个通用的点击步骤定义,好处(除了上面解释的那个)是场景的措辞更关注用户意图而不是具体的 UI 控件级别交互(执行操作与单击某物)

于 2011-08-28T21:22:40.783 回答