t.me/atinfo_chat Telegram группа по автоматизации тестирования

Nunit SpecFlow инициализация шагов вне основных классов Given, When, Then

csharp
specflow
nunit
webdriver
selenium
Теги: #<Tag:0x00007f9c4fb163e8> #<Tag:0x00007f9c4fb162a8> #<Tag:0x00007f9c4fb16168> #<Tag:0x00007f9c4fb16028> #<Tag:0x00007f9c4fb15ee8>

(Максим Лаптев) #1

Здравствуте, вопрос след плана, есть тесты Nunit которые использует SpecFlow, тест отрабатывает корректно

{
    [TestFixture]
    [Binding]
    public class Login_Test : BaseTest
    {
       
    
        [Given(@"test test")]
        public void testTets()
        {
			LoginSteps steps = new LoginSteps(driver);
			steps.Login();
           
        }
	}
}

Но, каким образом вынести 

LoginSteps steps = new LoginSteps(driver);

выше тестов, поскольку дальше классы When, Then и в каждом из них инизиализировать шаги не хочется

(Valentin G ) #2

Лучше всего делать это в конструкторе.

public class ShopMainPageSteps
    {
        private readonly Driver _driver;
        private readonly ShopMainPage _shopMainPage;

        public ShopMainPageSteps(Driver driver)
        {
            _driver = driver;
            _shopMainPage = new ShopMainPage(driver);
        }
.......
}

Для своих тестов я использую структуру как тут.


(Максим Лаптев) #3

а каким образом в самом классе Given это все дело вызвать?


(Максим Лаптев) #4

если таким же макаром, то не выходит


(Максим Лаптев) #5

По сути у меня все тоже самое, если речь о тестах Nunit ранее в одном классе перед всеми действиями инициализировались шаги и все ок. Сейчас же SpecFlow делит все на отдельные классы, обернуть все это в единый класс, как я понял нельзя, чтобы перед всем этим делом инициализировать шаги, работает только если в каждом классе это делать, но это неправильно


(Vladislav Abramov) #6

мы классы шагов, которые привязаны к фичам, наследуем от класса общих шагов

браузер инициализируем вообще в другом классе BaseSteps, на который вешаем [Binding] и где у нас хранятся обработки типа [BeforeSteps]

при старте теста в конструкторе класса BaseSteps объявляем [ThreadStatic] IWebDriver Browser, куда кладем стартующий браузер


(Максим Лаптев) #7

А можно пример? меня только интересует как из Given получить собственно steps.Login(); исходя из того, что я наследуюсь от BaseTest где в методе setUp лежит
LoginSteps steps = new LoginSteps(driver);
Здесь проблема больше понимания мною c#, нежели фреймворков


(Valentin G ) #8

Лучше Login() положить в PageObject class. И вызывать уже из него из Steps класса.
С использованием SpecFlow у тебя появляется еще один слой. Новая структура должна быть следующая - Feature, Steps, который содержит в себе ссылки на PageObjects. Именно такая структура у меня в проекте, на который я дал ссылку. Там у меня есть класс - Hooks, где есть методы с аннотациями [BeforeScenario] and [AfterScenario], эти методы вызываются перед и после каждого сценария и там запускается и останавливается Driver и помещается в ObjectContainer, что позволяет использовать Dependency Injection в Step классах.
По моему мнению (может не совсем правильно), для каждого PageObject класса надо использовать свой Step class.


(Максим Лаптев) #9

Проблема решена
private LoginSteps _step;
[BeforeStep]
public void setUP()
{
_step = new LoginSteps(driver);
}
Добавил это в начале всех Given, When


(Юрий Аксютин) #10

Возможно вам подойдет такая технология как DI(dependency injection).В спекфлоу она реализованна на уроне фреймворка. Очень простая реализация