簡體   English   中英

帶有頁面對象模型的 Specflow 中的常見步驟定義

[英]Common Step Definitions in Specflow with Page Object Model

我的登錄頁面綁定中有一個步驟定義

[When(@"I click the '(.*)' button")]
public void IClickTheButton(string buttonName)
{
    LoginPage loginPage = new LoginPage();
    loginPage.ClickTheButton(buttonName);
}

我的頁面對象是使用 BasePage 中的ClickTheButton方法設置的:

public class LoginPage : BasePage
{
    public LoginPage(IWebDriver _driver)
    {
        driver = _driver;
    }
    // some methods

}
public class HomePage : BasePage
{
    public HomePage(IWebDriver _driver)
    {
        driver = _driver;
    }
    // some methods
}
public class BasePage
{
    //no constructor atm
    public void ClickTheButton(string buttonName)
    {
        driver.GetFirstButtonWithTextContaining(buttonName).Click();
    }
    // more methods
}      

應用程序中的所有按鈕的格式都相同,因此GetFirstButtonWithTextContaining方法將使用

driver.FindElements(By.TagName("button")).Where(x => x.Text == buttonName).First();

問題是我將在我所有的功能文件中使用“我點擊‘(.*)’按鈕”,比如主頁功能,所以使用登錄頁面步驟定義似乎不正確,它利用了登錄實例其他頁面上所有按鈕的頁面類。

我正在考慮為這些類型的方法創建一個通用步驟 defs 文件,但是當我向 BasePage 添加一個構造函數(與其他頁面對象類相同)並在通用步驟 defs 綁定中執行以下操作時:

BasePage basePage = new BasePage();
basePage.ClickTheButton(buttonName);

有更好的實現嗎?...使用 BasePage 類似乎是錯誤的,但我看不到在使用頁面對象時如何跨多個功能共享步驟定義。 我正在嘗試創建盡可能多的通用步驟以在所有功能之間共享。

您的頁面模型並不是真正的頁面模型。 它們只是使用 Selenium 做事情的方便包裝器,並沒有提供良好的抽象層。

直接在步驟定義中使用擴展方法:

[When(@"I click the '(.*)' button")]
public void IClickTheButton(string buttonName)
{
    driver.GetFirstButtonWithTextContaining(buttonName).Click();
}

或者重寫你的頁面模型來封裝頁面上的用戶操作:

public class LoginPage
{
    private readonly IWebDriver driver;
    private IWebElement Password => driver.FindElement(By.Id("Password"));
    private IWebElement Username => driver.FindElement(By.Id("Username"));
    private IWebElement LoginButton => driver.FindElement(By.XPath("//button[contains(., 'Log In')]"));

    public LoginPage(IWebDriver driver)
    {
        this.driver = driver;
    }

    public HomePage Login(string username, string password = "test")
    {
        Username.SendKeys(username);
        Password.SendKeys(password);
        LoginButton.Click();

        var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(30));

        wait.Until(ExpectedConditions.StalenessOf(LoginButton));

        return new HomePage(driver);
    }
}

這意味着將您的步驟從程序風格(我點擊這個;我這樣做)更改為更加行為驅動的風格。 例如,使用程序步驟“登錄”是很常見的:

Given I am on the login page
When I enter "foo" for the "Username"
And I enter "bar" for the "Password"
And I click the "Log In" button

相反,行為驅動的步驟將是一個快速的單行代碼,將其大部分行為委托給頁面模型:

Given I am logged in as "foo"

[Given(@"I am logged in as ""(.+)""")]
public GivenIAmLoggedInAs(string username)
{
    var loginPage = new LoginPage(driver);

    loginPage.LogIn(username);
}

您的黃瓜步驟應該是一層薄薄的貼面,將特征文件中的應用程序行為描述粘合到將行為封裝在頁面中的頁面模型上。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM