Ненужное повторение экземпляра класса - PullRequest
1 голос
/ 08 апреля 2020

В настоящее время работает над созданием инфраструктуры автоматизации с использованием C# и SpecFlow. Одна из моих проблем на данный момент - количество случаев, когда я создаю экземпляр класса для доступа к методам или веб-элементам.

Ниже приведена часть класса, который я создаю в отдельном методе класса

public class UniversalSelectors : BasePage
{
    public  UniversalSelectors(IObjectContainer container): base(container)  { }

    //iFrame
    public IWebElement iFrame => Driver.FindElement(By.Id("content"));
    //Nav Bar Elements
    public void ClickAdministration()
    {
        Driver.FindElement(By.XPath("//a[@id='administration-menu-item']"));
    }
    public void ClickDevicesMenu()
    {
        Driver.FindElement(By.XPath("//*[@id='manage-devices-menu-item']"));
    }
    public void ClickRemoteMonitoring()
    {
        Driver.FindElement(By.Id("manage-monitoring-menu-item"));
    }
    public void ClickSystemUsers()
    {
        Driver.FindElement(By.XPath("//*[@id='manage-users-menu-header']"));
    }
    //Quick Search Elements
    public IWebElement Quick_Search => Driver.FindElement(By.XPath("//*[@class='pSearch pButton']"));
    public IWebElement Quick_Search_Box => Driver.FindElement(By.XPath("//*[@class='qsbox']"));
    public IWebElement Quick_Search_Button => Driver.FindElement(By.XPath("//*[@class='btn btn-sm btn-success flexigrid-search-button']"));
    public IWebElement Quick_Clear_Button => Driver.FindElement(By.XPath("//*[@class='btn btn-sm btn-success flexigrid-clear-button']"));

И ниже вы можете увидеть, как я создаю экземпляры в каждом методе другого класса. Но я хочу знать, является ли это необходимым или есть лучший способ обойти это?

public void NavigateToRoles()
{
    var universalselectors = new UniversalSelectors(_container);

    universalselectors.ClickAdministration();
    Thread.Sleep(1000);
    universalselectors.ClickSystemUsers();
    Thread.Sleep(1000);
    Roles.Click();
    Thread.Sleep(2000);
}
public void CreateBlankRole()
{
    var universalselectors = new UniversalSelectors(_container);

    Driver.SwitchTo().DefaultContent();
    Driver.SwitchTo().Frame(universalselectors.iFrame);
    universalselectors.ClickNewRecord();
    Thread.Sleep(2000);
    universalselectors.ClickSaveRecord();
    Thread.Sleep(2000);
}

1 Ответ

0 голосов
/ 09 апреля 2020

Вы можете исключить инициализацию нового объекта того же типа, используя внедрение зависимостей (см. Также внедрение конструктора ). В рамках SpecFlow это включает в себя создание нового экземпляра UniversalSelectors в хук SpecFlow и его регистрацию в контейнере объекта SpecFlow. Затем любой класс определения шага, которому требуется модель страницы, должен включать объект UniversalSelectors в качестве одного из аргументов конструктора, который он передает конструктору модели страницы вместе с объектом веб-драйвера.

Регистрация веб-драйвера и Объект UniversalSelector с каркасом внедрения зависимостей SpecFlow (контейнер объекта):

[Binding]
public class SpecFlowHooks
{
    private readonly IObjectContainer container;

    public SpecFlowHooks(IObjectContainer container)
    {
        this.container = container;
    }

    [BeforeScenario]
    public void BeforeScenario()
    {
        var driver = new ChromeDriver() | FirefoxDriver() // or whatever web driver you use

        // Configure the web driver

        var universalSelectors = new UniversalSelectors(driver);

        container.RegisterInstanceAs<IWebDriver>(driver);
        container.RegisterInstanceAs(universalSelectors);
    }
}

Теперь добавьте объект UniversalSelectors в аргументы конструктора для моделей страниц:

public class RolesPageModel
{
    private readonly IWebDriver Driver;
    private readonly UniversalSelectors universalSelectors;

    // other properties

    public RolesPageModel(IWebDriver driver, UniversalSelectors universalSelectors)
    {
        Driver = driver;
        this.universalSelectors = universalSelectors;
    }

    public void NavigateToRoles()
    {
        universalselectors.ClickAdministration();
        Thread.Sleep(1000);
        universalselectors.ClickSystemUsers();
        Thread.Sleep(1000);
        Roles.Click();
        Thread.Sleep(2000);
    }

    public void CreateBlankRole()
    {
        Driver.SwitchTo().DefaultContent();
        Driver.SwitchTo().Frame(universalselectors.iFrame);
        universalselectors.ClickNewRecord();
        Thread.Sleep(2000);
        universalselectors.ClickSaveRecord();
        Thread.Sleep(2000);
    }
}

И приклейте к хранить вещи вместе в ваших определениях шагов, где вам необходимо объявить аргумент UniversalSelectors для этих конструкторов:

[Binding]
public class RoleSteps
{
    private readonly RolesPageModel roles;

    public Roleteps(IWebDriver driver, UniversalSelectors universalSelectors)
    {
        roles = new RolesPageModel(driver, universalselectors);
    }

    [When(@"I create a blank role")]
    public void WhenICreateABlankRole()
    {
        roles.CreateBlankRole();
    }
}

Добавление

The реальная проблема, на мой взгляд, заключается в самом классе UniversalSelectors. «Селекторы» (или «локаторы» на языке Selenium) могут быть так же легко объявлены в модели страницы, которая использует локатор. На самом деле, это предпочтительный подход. Страницы имеют общие элементы, такие как навигационные меню и панели поиска. Эти общие элементы страницы должны быть их собственными моделями страниц. Композиция, а не наследование, более полезна:

public class RolesPageModel
{
    private readonly IWebDriver Driver;
    private readonly NavigationBarPageModel navBar;
    private readonly SiteSearchBarPageModel searchBar;

    // other properties

    public RolesPageModel(IWebDriver driver)
    {
        this.driver = driver;
        navBar = new NavigationBarPageModel(driver);
        searchBar = new SiteSearchBarPageModel(driver);
    }

    public void NavigateToRoles()
    {
        navBar.GoToRoles();
    }

Это упрощает зависимости для всех моделей страниц и полностью устраняет необходимость использования UniversalSelectors.

...