Оригинал
Driving Web Behaviour
Selenium является мощным инструментом с открытым исходным кодом для автоматизированного тестирования web-приложений. С версии 2.x, он предлагает на выбор два API: API Selenium (обратная совместимость с 1.x) и новый WebDriver API. JBehave поддерживает оба. Когда мы говорим о Selenium, мы обычно подразумеваем сам фреймворк, а если нужно различать API, мы специально обратимся к API и Selenium WebDriver API.
Давайте посмотрим, как мы можем легко использовать Selenium для запуска "веб-историй". Целью создания DSL является представление бизнес-функциональности домена в то же время абстрагируясь от деталей реализации, в этом случае доступ к веб-слою осуществляется с помощью специального инструмента тестирования, такого как Selenium. То же самое DSL должно иметь возможность повторного использования с другими инструментами тестирования.
Как обычно, примеры говорят громче, чем слова:
Scenario
: User searches for a single step
Given
user is on Home page
When
user opens Find Steps page
Then
Find Steps page is shown
When
user searches for "
Given
a threshold of 10.0"
Then
search returns: "
Given
a threshold of $threshold"
When
user views with methods
Then
search returns: "
Given
a threshold of $threshold,
[org.jbehave.web.examples.trader.steps.TraderSteps.aThreshold(double)]"
And
steps instances include: "TraderSteps,StockExchangeSteps"
public class TraderWebSteps { private final Pages pages; public TraderWebSteps(Pages pages) { this .pages = pages; } @Given ( "user is on Home page" ) public void userIsOnHomePage(){ pages.home().open(); } @When ( "user opens Find Steps page" ) public void userClicksOnFindSteps(){ pages.findSteps().open(); } @Then ( "Find Steps page is shown" ) public void findStepsPageIsShown(){ pages.findSteps().pageIsShown(); } @When ( "user searches for \"$step\"" ) public void userSearchesForSteps(String step){ pages.findSteps().find(step); } @Then ( "search returns: \"$stepsOrMethods\"" ) public void stepsFound(List<String> stepsOrMethods){ pages.findSteps().found(stepsOrMethods); } @Then ( "steps instances include: \"$names\"" ) public void stepsInstancesFound(List<String> names){ pages.findSteps().found(names); } } |
Настройка JBehave для использования Selenium
Как всегда, мы настроим JBehave несколькими различными способами. Один из способов, это иметь встраиваемый запускаемый класс, то есть JUnit-запускаемый класс TraderWebStories. Здесь в игру вступает выбор API.Использование Selenium API
public class TraderWebStories extends JUnitStories { private Selenium selenium = SeleniumConfiguration.defaultSelenium(); private ConditionRunner conditionRunner = SeleniumConfiguration.defaultConditionRunner(selenium); private Pages pages = new Pages(selenium, conditionRunner); private SeleniumSteps lifecycleSteps = new PerStorySeleniumSteps(selenium); private SeleniumContext seleniumContext = new SeleniumContext(); @Override public Configuration configuration() { Class<? extends Embeddable> embeddableClass = this .getClass(); return new SeleniumConfiguration() .useSelenium(selenium) .useSeleniumContext(seleniumContext) .useStepMonitor( new SeleniumStepMonitor(selenium, seleniumContext, new SilentStepMonitor())) .useStoryLoader( new LoadFromClasspath(embeddableClass)) .useStoryReporterBuilder( new StoryReporterBuilder() .withCodeLocation(codeLocationFromClass(embeddableClass)) .withDefaultFormats() .withFormats(CONSOLE, TXT, HTML, XML)); } @Override public InjectableStepsFactory stepsFactory() { return new InstanceStepsFactory(configuration(), new TraderWebSteps(pages), lifecycleSteps, new SeleniumScreenshotOnFailure(selenium)); } @Override protected List<String> storyPaths() { return new StoryFinder() .findPaths(codeLocationFromClass( this .getClass()).getFile(), asList( "**/*.story" ), null ); } } |
Использование API WebDriver
public class TraderWebStories extends JUnitStories { private WebDriverProvider driverProvider = new PropertyWebDriverProvider(); private WebDriverSteps lifecycleSteps = new PerStoriesWebDriverSteps(driverProvider); // or PerStoryWebDriverSteps(driverProvider) private Pages pages = new Pages(driverProvider); private SeleniumContext context = new SeleniumContext(); private ContextView contextView = new LocalFrameContextView().sized( 500 , 100 ); public TraderWebStories() { // If configuring lifecycle per-stories, you need to ensure that you a same-thread executor if ( lifecycleSteps instanceof PerStoriesWebDriverSteps ){ configuredEmbedder().useExecutorService(MoreExecutors.sameThreadExecutor()); } } @Override public Configuration configuration() { Class<? extends Embeddable> embeddableClass = this .getClass(); return new SeleniumConfiguration() .useSeleniumContext(context) .useWebDriverProvider(driverProvider) .useStepMonitor( new SeleniumStepMonitor(contextView, context, new SilentStepMonitor())) .useStoryLoader( new LoadFromClasspath(embeddableClass)) .useStoryReporterBuilder( new StoryReporterBuilder() .withCodeLocation(codeLocationFromClass(embeddableClass)) .withDefaultFormats() .withFormats(CONSOLE, TXT, HTML, XML)); } @Override public InjectableStepsFactory stepsFactory() { Configuration configuration = configuration(); return new InstanceStepsFactory(configuration, new TraderWebSteps(pages), lifecycleSteps, new WebDriverScreenshotOnFailure(driverProvider, configuration.storyReporterBuilder())); } @Override protected List<String> storyPaths() { return new StoryFinder() .findPaths(codeLocationFromClass( this .getClass()).getFile(), asList( "**/*.story" ), null ); } // This Embedder is used by Maven or Ant and it will override anything set in the constructor public static class SameThreadEmbedder extends Embedder { public SameThreadEmbedder() { useExecutorService(MoreExecutors.sameThreadExecutor()); } } } |
Жизненный цикл шагов
JBehave интеграции с Selenium и WebDriver API, направлена на выполнение общих задач. Среди них одна из самых распространенных является управление жизненным циклом, например, запуском и остановкой браузера.JBehave предусматривает три типа управления жизненным циклом:
- Через истории: через PerStoriesSeleniumSteps или PerStoriesWebDriverSteps .
- Через историю: через PerStorySeleniumSteps или PerStoryWebDriverSteps .
- Через сценарий: через PerScenarioSeleniumSteps или PerScenarioWebDriverSteps .