C # Specflow - хук BeforeScenario не вызывается, и драйвер становится нулевым - PullRequest
0 голосов
/ 29 сентября 2019

Я довольно новичок в Specflow и C #, поэтому я столкнулся с проблемой с перехватчиками specflow. Проблема в том, что когда я использую [BeforeScenario], метод даже не вызывается во время отладки. Удаляя эти хуки и заменяя их на [TestInitialize], он работает отлично. Я искал здесь решение во многих вопросах, но я не нашел никаких проблем, кроме как с частными методами, что, похоже, не в моем случае.

У меня есть 4 класса: Tests, Steps, PageObjects и Hooks(который содержит драйвер и крючки). Класс 'Tests' наследуется от 'Steps', который наследуется от 'PageObjects', который наследуется от 'Hooks'. Каждый вызов общедоступен, и я записываю некоторый код из класса 'Hooks':

 namespace AutomationPractice.Helper
{
    [Binding]
    public class Hooks
    {
        public IWebDriver _driver;

        [BeforeFeature]
        public void BeforeScenario()
        {
            if (_driver == null)
            {
                _driver = new ChromeDriver();
            }
            else { throw new Exception("Couldn't initialize the driver"); }

        }

        [AfterFeature]
        public void AfterScenario()
        {
            if (_driver != null)
            {
                _driver.Quit();
            }
            else throw new Exception("There was an error while trying to close the driver");

            }
}
}

Класс 'PageObjects':

namespace AutomationPractice.PageObjects
{
    [Binding]
    public class GoogleSearchPageObjects : Hooks
    {
        public string goToGooglePage(string url)
        {
            return _driver.Url = url;
        }

        public IWebElement GetTxtSearch()
        {
            return _driver.FindElement(By.Name("q"));
        }

        public void fillTxtSearch(string search)
        {
            GetTxtSearch().SendKeys(search);
        }

    }
}

Класс 'Steps':

namespace AutomationPractice.Steps
{
    [Binding]

    public class GoogleSearchSteps : GoogleSearchPageObjects
    {

        [Given(@"I am on google home page")]
        public void GivenIAmOnGoogleHomePage(string url)
        {
            goToGooglePage(url);

        }

        [When(@"I fill the '(.*)' field")]
        public void WhenIFillTheField(string search)
        {
            fillTxtSearch(search);
        } 

Хотя каждый класс округляется [Binding].

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 01 октября 2019

У вас слишком много вещей, происходящих в одной иерархии классов. Было бы намного проще отделить следующие вещи:

  • Веб-драйвер
  • Объекты страницы
  • Определения шагов

Выможно использовать инфраструктуру внедрения зависимостей SpecFlow, чтобы связать эти вещи вместе, используя аргументы конструктора.

Сначала ваш класс Hooks, где вы управляете экземпляром веб-драйвера для всех определений шагов и объектов страницы:

[Binding]
public class Hooks
{
    private IObjectContainer container;

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

    [BeforeScenario]
    public void CreateWebDriver()
    {
        var driver = new ChromeDriver();

        container.RegisterInstanceAs<IWebDriver>(driver);
    }

    [AfterScenario]
    public void DestroyWebDriver()
    {
        var driver = container.Resolve<IWebDriver>();

        driver.Quit();
        driver.Dispose();
    }
}

Иобъект страницы поиска Google становится отдельным классом, который получает объект веб-драйвера в качестве параметра конструктора, который разделяет его со SpecFlow вместе.

public class GoogleSearchPage
{
    private readonly IWebDriver driver;

    private IWebElement TxtSearch => driver.FindElement(By.Name("q"));

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

    public void EnterSearchTerm(string searchTerm)
    {
        TxtSearch.SendKeys(searchTerm);
    }
}

И, наконец, класс определения шага, в котором все подключаетсявместе с помощью инфраструктуры внедрения зависимостей, которая поставляется вместе с SpecFlow:

[Binding]
public class GoogleSearchSteps
{
    private GoogleSearchPage googleSearch;

    public GoogleSearchSteps(IWebDriver driver)
    {
        googleSearch = new GoogleSearchPage(driver);
    }

    [When(@"I fill the '(.*)' field")]
    public void WhenIFillTheField(string search)
    {
        googleSearch.EnterSearchTerm(search);
    }
}

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

0 голосов
/ 30 сентября 2019

Ваши методы - это имена BeforeScenario и AfterScenario, но вы используете атрибуты для BeforeFeature и AfterFeature. Они должны быть статическими, чтобы их вызывали.

Вам необходимо изменить атрибуты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...