Повторно използване на стъпките на Specflow, когато използвате шаблон на Page Objects

Използвам 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);
        }
    }
}

Не искам да пиша дефиниция на една стъпка за всеки сценарий, тъй като се използва повторно много код, който бих предпочел да бъде в един метод. И така, как мога да използвам повторно дефинициите на стъпките и пак да използвам модела на обект на страница?

Благодаря.


person regisbsb    schedule 08.08.2011    source източник


Отговори (2)


можете да направите това, като изложите свойство на вашия обект на основна страница, което позволява итерация на всички контроли на текущата страница (вероятно чрез отражение, но как ще приложите това е без значение, стига да работи).

След като имате това, можете да приложите стъпката, като извикате това свойство, търсейки връзката с името, дадено в стъпката („link1“ или „link2“) и след това щракнете върху това.

Въпреки че това ще работи, бих ви препоръчал да опитате и да се въздържате от това да правите вашите сценарии толкова специфични за изпълнението. Вместо „когато щракна върху „връзка1““ е по-добре да има нещо, което е по-описателно за намерението, отколкото за изпълнението, „когато отида в кошницата“ или „когато навигирам до подробностите за моя акаунт“. Това не е многократно използваемо, но също така е устойчиво на рефакторинг на вашия дизайн и позволява вашите стъпки да бъдат използвани повторно за различни устройства, когато „щракването“ върху връзка няма смисъл (като сензорни устройства)

person Sam Holder    schedule 29.07.2015
comment
Знам. Обектите на страницата не се смесват много добре с тези сценарии като скриптове, но понякога са всичко, което имаме. Използвал съм подход, подобен на това, което казахте. - person regisbsb; 29.07.2015

Също така бих се интересувал много от мнението и практиките на други, но ето моите мисли.

Ако изберете генерично обвързване „Когато щракна върху „([^']*)“, нямате много информация в генеричното Кога за какво се отнася текущият сценарий. Все пак можете да опитате да "изчакате" за зареждане на следващата страница и можете да проверите (IWebDriver) Url, за да разберете къде се намирате (според браузъра). Ще ви трябва съпоставяне между Url и вашите обекти на страницата, за да можете да изберете обекта на текущата страница по подходящ начин. Можете да създадете картографиране ръчно за тази цел, можете да използвате някои конвенции или можете да използвате друга съществуваща „информация за картографиране“, като ASP.NET маршрутизиране или карта на сайта, или най-вероятно някаква комбинация от тях. ;)

Друга възможност е да отложите оценката на текущия URL адрес към Then, но в този случай вероятно инструментът за получаване на свойство CurrentPageObject трябва да капсулира това. Това, което имам предвид е, че стойността на имота не трябва да зависи от това дали "се обаждате" на определено Тогава или не.

Опитах малко по-различен подход в един от последните ми проекти. Написах по-конкретни изрази When за моите сценарии, така че вместо „Когато щракна върху „Търсене““, „Когато щракна върху „Поръчка““ или „Когато щракна върху „Потвърди““ имах „Когато задействам търсенето с параметрите попълнено“, „Когато поръчам избраните артикули“ или „Когато потвърдя поръчката“. Тъй като тези изрази описваха конкретно действие, аз ги делегирах на обекта на текущата страница (прехвърлен към въпросната конкретна страница), където обектът на страницата имаше конкретни методи за тези действия. Реализацията не само „щракна“ върху съответния бутон (базова функционалност), но също така изчака зареждането на страницата и зададе текущия обект на страница по подходящ начин. В такива конкретни случаи или беше очевидно какъв е „следващият“ обект на текущата страница, или можех повече или по-малко лесно да проверя какво се е случило, ако имаше повече възможни резултати. Цената, която платих, беше, че това не беше само една обща дефиниция на стъпката при щракване, предимството (освен обясненото по-горе) беше, че формулирането на сценариите беше по-фокусирано върху намерението на потребителя, а не върху конкретния UI контрол взаимодействие на ниво (извършване на действие срещу щракване върху нещо)

person Tz_    schedule 28.08.2011